diff --git a/DEPS b/DEPS index 4f9f2f48..21f82be 100644 --- a/DEPS +++ b/DEPS
@@ -106,7 +106,7 @@ # 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': '32942201a456ace47c052536cba594be03e9aa6c', + 'pdfium_revision': '14f8897509d9db8739951a90488fb1634a497db5', # 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. @@ -142,7 +142,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': '5d3d40fb8894e8b4b63f89b0edee83375339ed8f', + 'catapult_revision': '883d59ef70276b408240bc48e9b615787a224188', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -910,7 +910,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@78ba74d755847eea235f8dd57849b7b1e9ee8d10', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ecf6e8e622df1050b4e74695930ee99958c839b5', 'condition': 'checkout_src_internal', },
diff --git a/android_webview/glue/glue.gni b/android_webview/glue/glue.gni index 1bcaa68..0581c9bb 100644 --- a/android_webview/glue/glue.gni +++ b/android_webview/glue/glue.gni
@@ -9,6 +9,8 @@ "//android_webview:android_webview_commandline_java", "//android_webview:android_webview_platform_services_java", "//android_webview:system_webview_manifest", + "//android_webview/support_library/boundary_interfaces:boundary_interface_java", + "//android_webview/support_library/callback:callback_java", "//base:base_java", "//components/autofill/android:autofill_java", "//components/autofill/android:provider_java",
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java index 2e965e0..4dc4ef0c 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewContentsClientAdapter.java
@@ -60,6 +60,8 @@ import org.chromium.base.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.TraceEvent; +import org.chromium.support_lib_boundary.util.Features; +import org.chromium.support_lib_callback_glue.SupportLibWebViewContentsClientAdapter; import java.lang.ref.WeakReference; import java.security.Principal; @@ -101,6 +103,8 @@ private final Context mContext; // The WebViewClient instance that was passed to WebView.setWebViewClient(). protected WebViewClient mWebViewClient = sNullWebViewClient; + // Some callbacks will be forwarded to this client for apps using the support library. + private SupportLibWebViewContentsClientAdapter mSupportLibClient; // The WebChromeClient instance that was passed to WebView.setContentViewClient(). private WebChromeClient mWebChromeClient; // The listener receiving find-in-page API results. @@ -176,6 +180,9 @@ } else { mWebViewClient = sNullWebViewClient; } + // Always reset mSupportLibClient, since the WebViewClient may no longer be a + // WebViewClientCompat, or may support a different set of Features. + mSupportLibClient = new SupportLibWebViewContentsClientAdapter(mWebViewClient); } WebViewClient getWebViewClient() { @@ -319,7 +326,10 @@ TraceEvent.begin("WebViewContentsClientAdapter.shouldOverrideUrlLoading"); if (TRACE) Log.i(TAG, "shouldOverrideUrlLoading=" + request.url); boolean result; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (mSupportLibClient.isFeatureAvailable(Features.SHOULD_OVERRIDE_WITH_REDIRECTS)) { + result = mSupportLibClient.shouldOverrideUrlLoading( + mWebView, new WebResourceRequestAdapter(request)); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { result = mWebViewClient.shouldOverrideUrlLoading( mWebView, new WebResourceRequestAdapter(request)); } else { @@ -547,11 +557,15 @@ */ @Override public void onPageCommitVisible(String url) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return; try { TraceEvent.begin("WebViewContentsClientAdapter.onPageCommitVisible"); if (TRACE) Log.i(TAG, "onPageCommitVisible=" + url); - mWebViewClient.onPageCommitVisible(mWebView, url); + if (mSupportLibClient.isFeatureAvailable(Features.VISUAL_STATE_CALLBACK)) { + mSupportLibClient.onPageCommitVisible(mWebView, url); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + mWebViewClient.onPageCommitVisible(mWebView, url); + } + // Otherwise, the API does not exist, so do nothing. } finally { TraceEvent.end("WebViewContentsClientAdapter.onPageCommitVisible"); } @@ -563,6 +577,10 @@ @Override public void onReceivedError(int errorCode, String description, String failingUrl) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) return; + + // This event is handled by the support lib in {@link #onReceivedError2}. + if (mSupportLibClient.isFeatureAvailable(Features.WEB_RESOURCE_ERROR)) return; + try { TraceEvent.begin("WebViewContentsClientAdapter.onReceivedError"); if (description == null || description.isEmpty()) { @@ -584,7 +602,6 @@ */ @Override public void onReceivedError2(AwWebResourceRequest request, AwWebResourceError error) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return; try { TraceEvent.begin("WebViewContentsClientAdapter.onReceivedError"); if (error.description == null || error.description.isEmpty()) { @@ -594,8 +611,15 @@ error.description = mWebViewDelegate.getErrorString(mContext, error.errorCode); } if (TRACE) Log.i(TAG, "onReceivedError=" + request.url); - mWebViewClient.onReceivedError(mWebView, new WebResourceRequestAdapter(request), - new WebResourceErrorImpl(error)); + if (mSupportLibClient.isFeatureAvailable(Features.WEB_RESOURCE_ERROR)) { + // Note: we must pass AwWebResourceError, since this class was introduced after L. + mSupportLibClient.onReceivedError( + mWebView, new WebResourceRequestAdapter(request), error); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + mWebViewClient.onReceivedError(mWebView, new WebResourceRequestAdapter(request), + new WebResourceErrorImpl(error)); + } + // Otherwise, this is handled by {@link #onReceivedError}. } finally { TraceEvent.end("WebViewContentsClientAdapter.onReceivedError"); } @@ -608,34 +632,36 @@ @TargetApi(Build.VERSION_CODES.O_MR1) public void onSafeBrowsingHit(AwWebResourceRequest request, int threatType, final Callback<AwSafeBrowsingResponse> callback) { - // WebViewClient.onSafeBrowsingHit was added in O_MR1. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1) { - callback.onResult(new AwSafeBrowsingResponse(SafeBrowsingAction.SHOW_INTERSTITIAL, - /* reporting */ true)); - return; - } try { TraceEvent.begin("WebViewContentsClientAdapter.onSafeBrowsingHit"); - mWebViewClient.onSafeBrowsingHit(mWebView, new WebResourceRequestAdapter(request), - threatType, new SafeBrowsingResponse() { - @Override - public void showInterstitial(boolean allowReporting) { - callback.onResult(new AwSafeBrowsingResponse( - SafeBrowsingAction.SHOW_INTERSTITIAL, allowReporting)); - } + if (mSupportLibClient.isFeatureAvailable(Features.SAFE_BROWSING_HIT)) { + mSupportLibClient.onSafeBrowsingHit( + mWebView, new WebResourceRequestAdapter(request), threatType, callback); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + mWebViewClient.onSafeBrowsingHit(mWebView, new WebResourceRequestAdapter(request), + threatType, new SafeBrowsingResponse() { + @Override + public void showInterstitial(boolean allowReporting) { + callback.onResult(new AwSafeBrowsingResponse( + SafeBrowsingAction.SHOW_INTERSTITIAL, allowReporting)); + } - @Override - public void proceed(boolean report) { - callback.onResult( - new AwSafeBrowsingResponse(SafeBrowsingAction.PROCEED, report)); - } + @Override + public void proceed(boolean report) { + callback.onResult(new AwSafeBrowsingResponse( + SafeBrowsingAction.PROCEED, report)); + } - @Override - public void backToSafety(boolean report) { - callback.onResult(new AwSafeBrowsingResponse( - SafeBrowsingAction.BACK_TO_SAFETY, report)); - } - }); + @Override + public void backToSafety(boolean report) { + callback.onResult(new AwSafeBrowsingResponse( + SafeBrowsingAction.BACK_TO_SAFETY, report)); + } + }); + } else { + callback.onResult(new AwSafeBrowsingResponse(SafeBrowsingAction.SHOW_INTERSTITIAL, + /* reporting */ true)); + } } finally { TraceEvent.end("WebViewContentsClientAdapter.onRenderProcessGone"); } @@ -643,14 +669,24 @@ @Override public void onReceivedHttpError(AwWebResourceRequest request, AwWebResourceResponse response) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return; try { TraceEvent.begin("WebViewContentsClientAdapter.onReceivedHttpError"); if (TRACE) Log.i(TAG, "onReceivedHttpError=" + request.url); - mWebViewClient.onReceivedHttpError(mWebView, new WebResourceRequestAdapter(request), - new WebResourceResponse(true, response.getMimeType(), response.getCharset(), - response.getStatusCode(), response.getReasonPhrase(), - response.getResponseHeaders(), response.getData())); + if (mSupportLibClient.isFeatureAvailable(Features.RECEIVE_HTTP_ERROR)) { + // Note: we do not create an immutable instance here, because that constructor is + // not available on L. + mSupportLibClient.onReceivedHttpError(mWebView, + new WebResourceRequestAdapter(request), + new WebResourceResponse(response.getMimeType(), response.getCharset(), + response.getStatusCode(), response.getReasonPhrase(), + response.getResponseHeaders(), response.getData())); + } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + mWebViewClient.onReceivedHttpError(mWebView, new WebResourceRequestAdapter(request), + new WebResourceResponse(true, response.getMimeType(), response.getCharset(), + response.getStatusCode(), response.getReasonPhrase(), + response.getResponseHeaders(), response.getData())); + } + // Otherwise, the API does not exist, so do nothing. } finally { TraceEvent.end("WebViewContentsClientAdapter.onReceivedHttpError"); }
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 5c34130..cce83619 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -864,6 +864,7 @@ WindowAndroid windowAndroid) { mContentViewCore = ContentViewCore.create(mContext, PRODUCT_VERSION, webContents, viewDelegate, internalDispatcher, windowAndroid); + mContentViewCore.setHideKeyboardOnBlur(false); SelectionPopupController controller = SelectionPopupController.fromWebContents(webContents); controller.setActionModeCallback( new AwActionModeCallback(mContext, this, controller.getActionModeCallbackHelper())); @@ -3480,7 +3481,7 @@ public void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { if (isDestroyedOrNoOperation(NO_WARN)) return; mContainerViewFocused = focused; - mContentViewCore.onFocusChanged(focused, false /* hideKeyboardOnBlur */); + mContentViewCore.onViewFocusChanged(focused); } @Override
diff --git a/android_webview/support_library/boundary_interfaces/BUILD.gn b/android_webview/support_library/boundary_interfaces/BUILD.gn index 6ce4cb1..00acb4e1 100644 --- a/android_webview/support_library/boundary_interfaces/BUILD.gn +++ b/android_webview/support_library/boundary_interfaces/BUILD.gn
@@ -7,6 +7,7 @@ android_library("boundary_interface_java") { java_files = [ + "src/org/chromium/support_lib_boundary/FeatureFlagHolderBoundaryInterface.java", "src/org/chromium/support_lib_boundary/SafeBrowsingResponseBoundaryInterface.java", "src/org/chromium/support_lib_boundary/ServiceWorkerClientBoundaryInterface.java", "src/org/chromium/support_lib_boundary/ServiceWorkerControllerBoundaryInterface.java",
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/FeatureFlagHolderBoundaryInterface.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/FeatureFlagHolderBoundaryInterface.java new file mode 100644 index 0000000..d2fa11e --- /dev/null +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/FeatureFlagHolderBoundaryInterface.java
@@ -0,0 +1,25 @@ +// Copyright 2018 The Chromium 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.support_lib_boundary; + +/** + * Boundary interface to be implemented by any type which is constructed on the support library + * side (such as callback classes). This interface is a way for the instance to declare which + * {@link org.chromium.support_lib_boundary.util.Features} it supports (this may vary between + * instances if the app uses multiple versions of the support library). + * + * This need only be implemented by objects created on the support library side, since we know any + * objects created on the chromium side have the same feature list as the WebView APK itself (as + * returned by {@link WebViewProviderFactoryBoundaryInterface#getSupportedFeatures}). + */ +public interface FeatureFlagHolderBoundaryInterface { + /** + * Indicate the list of {@link org.chromium.support_lib_boundary.util.Features} supported by + * this object. + * + * @return The supported features. + */ + String[] getSupportedFeatures(); +}
diff --git a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java index d74ea55..e4d04b46 100644 --- a/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java +++ b/android_webview/support_library/boundary_interfaces/src/org/chromium/support_lib_boundary/util/Features.java
@@ -13,6 +13,19 @@ // This class just contains constants representing features. private Features() {} - // WebViewCompat.postVisualStateCallback + // WebViewCompat#postVisualStateCallback + // WebViewClientCompat#onPageCommitVisible public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK"; + + // WebViewClientCompat#onReceivedError(WebView, WebResourceRequest, WebResourceError) + public static final String WEB_RESOURCE_ERROR = "WEB_RESOURCE_ERROR"; + + // WebViewClientCompat#onReceivedHttpError + public static final String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR"; + + // WebViewClientCompat#onSafeBrowsingHit + public static final String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT"; + + // WebViewClientCompat#shouldOverrideUrlLoading + public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS"; }
diff --git a/android_webview/support_library/callback/BUILD.gn b/android_webview/support_library/callback/BUILD.gn new file mode 100644 index 0000000..e830f65 --- /dev/null +++ b/android_webview/support_library/callback/BUILD.gn
@@ -0,0 +1,17 @@ +# Copyright 2018 The Chromium 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/config.gni") +import("//build/config/android/rules.gni") + +android_library("callback_java") { + java_files = [ "java/src/org/chromium/support_lib_callback_glue/SupportLibWebViewContentsClientAdapter.java" ] + + deps = [ + "//android_webview:android_webview_commandline_java", + "//android_webview:android_webview_java", + "//android_webview/support_library/boundary_interfaces:boundary_interface_java", + "//base:base_java", + ] +}
diff --git a/android_webview/support_library/callback/java/src/org/chromium/support_lib_callback_glue/SupportLibWebViewContentsClientAdapter.java b/android_webview/support_library/callback/java/src/org/chromium/support_lib_callback_glue/SupportLibWebViewContentsClientAdapter.java new file mode 100644 index 0000000..34a9628 --- /dev/null +++ b/android_webview/support_library/callback/java/src/org/chromium/support_lib_callback_glue/SupportLibWebViewContentsClientAdapter.java
@@ -0,0 +1,155 @@ +// Copyright 2018 The Chromium 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.support_lib_callback_glue; + +import android.support.annotation.Nullable; +import android.webkit.WebResourceRequest; +import android.webkit.WebResourceResponse; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import org.chromium.android_webview.AwContentsClient.AwWebResourceError; +import org.chromium.android_webview.AwSafeBrowsingResponse; +import org.chromium.android_webview.SafeBrowsingAction; +import org.chromium.base.Callback; +import org.chromium.support_lib_boundary.SafeBrowsingResponseBoundaryInterface; +import org.chromium.support_lib_boundary.WebResourceErrorBoundaryInterface; +import org.chromium.support_lib_boundary.WebViewClientBoundaryInterface; +import org.chromium.support_lib_boundary.util.BoundaryInterfaceReflectionUtil; +import org.chromium.support_lib_boundary.util.Features; + +import java.lang.reflect.InvocationHandler; + +/** + * Support library glue version of WebViewContentsClientAdapter. + */ +public class SupportLibWebViewContentsClientAdapter { + private static final String WEBVIEW_CLIENT_COMPAT_NAME = "androidx.webkit.WebViewClientCompat"; + + // If {@code null}, this indicates the WebViewClient is not a WebViewClientCompat. Otherwise, + // this is a Proxy for the WebViewClientCompat. + @Nullable + private WebViewClientBoundaryInterface mWebViewClient; + + private static class SafeBrowsingResponseDelegate + implements SafeBrowsingResponseBoundaryInterface { + private Callback<AwSafeBrowsingResponse> mCallback; + + SafeBrowsingResponseDelegate(Callback<AwSafeBrowsingResponse> callback) { + mCallback = callback; + } + + @Override + public void showInterstitial(boolean allowReporting) { + mCallback.onResult(new AwSafeBrowsingResponse( + SafeBrowsingAction.SHOW_INTERSTITIAL, allowReporting)); + } + + @Override + public void proceed(boolean report) { + mCallback.onResult(new AwSafeBrowsingResponse(SafeBrowsingAction.PROCEED, report)); + } + + @Override + public void backToSafety(boolean report) { + mCallback.onResult( + new AwSafeBrowsingResponse(SafeBrowsingAction.BACK_TO_SAFETY, report)); + } + }; + + private static class WebResourceErrorDelegate implements WebResourceErrorBoundaryInterface { + private AwWebResourceError mError; + + WebResourceErrorDelegate(AwWebResourceError error) { + mError = error; + } + + @Override + public int getErrorCode() { + return mError.errorCode; + } + + @Override + public CharSequence getDescription() { + return mError.description; + } + }; + + public SupportLibWebViewContentsClientAdapter(WebViewClient possiblyCompatClient) { + mWebViewClient = convertCompatClient(possiblyCompatClient); + } + + @Nullable + private WebViewClientBoundaryInterface convertCompatClient(WebViewClient possiblyCompatClient) { + if (!clientIsCompat(possiblyCompatClient)) return null; + + InvocationHandler handler = + BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(possiblyCompatClient); + + return BoundaryInterfaceReflectionUtil.castToSuppLibClass( + WebViewClientBoundaryInterface.class, handler); + } + + private boolean clientIsCompat(WebViewClient possiblyCompatClient) { + try { + Class compatClass = Class.forName(WEBVIEW_CLIENT_COMPAT_NAME, false, + possiblyCompatClient.getClass().getClassLoader()); + return compatClass.isInstance(possiblyCompatClient); + } catch (ClassNotFoundException e) { + // If WEBVIEW_CLIENT_COMPAT_NAME is not in the ClassLoader, then this cannot be an + // instance of WebViewClientCompat. + return false; + } + } + + /** + * Indicates whether this client can handle the callback(s) assocated with {@param featureName}. + * This should be called with the correct feature name before invoking the corresponding + * callback, and the callback must not be called if this returns {@code false} for the feature. + * + * @param featureName the feature for the desired callback. + * @return {@code true} if this client can handle the feature. + */ + public boolean isFeatureAvailable(String featureName) { + if (mWebViewClient == null) return false; + // TODO(ntfschr): provide a real implementation, which consults the WebViewClientCompat. + return true; + } + + public void onPageCommitVisible(WebView webView, String url) { + assert isFeatureAvailable(Features.VISUAL_STATE_CALLBACK); + mWebViewClient.onPageCommitVisible(webView, url); + } + + public void onReceivedError( + WebView webView, WebResourceRequest request, final AwWebResourceError error) { + assert isFeatureAvailable(Features.WEB_RESOURCE_ERROR); + WebResourceErrorBoundaryInterface errorDelegate = new WebResourceErrorDelegate(error); + InvocationHandler errorHandler = + BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(errorDelegate); + mWebViewClient.onReceivedError(webView, request, errorHandler); + } + + public void onReceivedHttpError( + WebView webView, WebResourceRequest request, WebResourceResponse response) { + assert isFeatureAvailable(Features.RECEIVE_HTTP_ERROR); + mWebViewClient.onReceivedHttpError(webView, request, response); + } + + public void onSafeBrowsingHit(WebView webView, WebResourceRequest request, int threatType, + Callback<AwSafeBrowsingResponse> callback) { + assert isFeatureAvailable(Features.SAFE_BROWSING_HIT); + SafeBrowsingResponseBoundaryInterface responseDelegate = + new SafeBrowsingResponseDelegate(callback); + InvocationHandler responseHandler = + BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(responseDelegate); + mWebViewClient.onSafeBrowsingHit(webView, request, threatType, responseHandler); + } + + public boolean shouldOverrideUrlLoading(WebView webView, WebResourceRequest request) { + assert isFeatureAvailable(Features.SHOULD_OVERRIDE_WITH_REDIRECTS); + return mWebViewClient.shouldOverrideUrlLoading(webView, request); + } +}
diff --git a/ash/app_list/model/search/search_result.h b/ash/app_list/model/search/search_result.h index c89a0cc..b4a33cb 100644 --- a/ash/app_list/model/search/search_result.h +++ b/ash/app_list/model/search/search_result.h
@@ -119,10 +119,6 @@ void UpdateFromMatch(const TokenizedString& title, const TokenizedStringMatch& match); - // TODO(mukai): Remove this method and really simplify the ownership of - // SearchResult. Ideally, SearchResult will be copyable. - virtual std::unique_ptr<SearchResult> Duplicate() const = 0; - // Invokes a custom action on the result. It does nothing by default. virtual void InvokeAction(int action_index, int event_flags);
diff --git a/ash/message_center/message_center_controller.cc b/ash/message_center/message_center_controller.cc index 3fc2fed..e387373 100644 --- a/ash/message_center/message_center_controller.cc +++ b/ash/message_center/message_center_controller.cc
@@ -8,6 +8,7 @@ #include "ash/public/cpp/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" #include "base/command_line.h" +#include "base/unguessable_token.h" #include "ui/base/l10n/l10n_util.h" #include "ui/message_center/message_center.h" #include "ui/message_center/public/cpp/notification.h" @@ -44,11 +45,14 @@ : public message_center::NotificationDelegate { public: AshClientNotificationDelegate(const std::string& notification_id, + const base::UnguessableToken& display_token, mojom::AshMessageCenterClient* client) - : notification_id_(notification_id), client_(client) {} + : notification_id_(notification_id), + display_token_(display_token), + client_(client) {} void Close(bool by_user) override { - client_->HandleNotificationClosed(notification_id_, by_user); + client_->HandleNotificationClosed(display_token_, by_user); } void Click(const base::Optional<int>& button_index, @@ -72,7 +76,12 @@ private: ~AshClientNotificationDelegate() override = default; - std::string notification_id_; + // The ID of the notification. + const std::string notification_id_; + + // The token that was generated for the ShowClientNotification() call. + const base::UnguessableToken display_token_; + mojom::AshMessageCenterClient* client_; DISALLOW_COPY_AND_ASSIGN(AshClientNotificationDelegate); @@ -139,12 +148,14 @@ } void MessageCenterController::ShowClientNotification( - const message_center::Notification& notification) { + const message_center::Notification& notification, + const base::UnguessableToken& display_token) { DCHECK(client_.is_bound()); auto message_center_notification = std::make_unique<message_center::Notification>(notification); - message_center_notification->set_delegate(base::WrapRefCounted( - new AshClientNotificationDelegate(notification.id(), client_.get()))); + message_center_notification->set_delegate( + base::WrapRefCounted(new AshClientNotificationDelegate( + notification.id(), display_token, client_.get()))); MessageCenter::Get()->AddNotification(std::move(message_center_notification)); }
diff --git a/ash/message_center/message_center_controller.h b/ash/message_center/message_center_controller.h index cebdfdf..d331513e 100644 --- a/ash/message_center/message_center_controller.h +++ b/ash/message_center/message_center_controller.h
@@ -38,7 +38,8 @@ void SetClient( mojom::AshMessageCenterClientAssociatedPtrInfo client) override; void ShowClientNotification( - const message_center::Notification& notification) override; + const message_center::Notification& notification, + const base::UnguessableToken& display_token) override; void CloseClientNotification(const std::string& id) override; void UpdateNotifierIcon(const message_center::NotifierId& notifier_id, const gfx::ImageSkia& icon) override;
diff --git a/ash/message_center/notifier_settings_view_unittest.cc b/ash/message_center/notifier_settings_view_unittest.cc index 926efc63..062a656 100644 --- a/ash/message_center/notifier_settings_view_unittest.cc +++ b/ash/message_center/notifier_settings_view_unittest.cc
@@ -38,7 +38,8 @@ } // mojom::AshMessageCenterClient: - void HandleNotificationClosed(const std::string& id, bool by_user) override {} + void HandleNotificationClosed(const base::UnguessableToken& token, + bool by_user) override {} void HandleNotificationClicked(const std::string& id) override {} void HandleNotificationButtonClicked( const std::string& id,
diff --git a/ash/public/interfaces/ash_message_center_controller.mojom b/ash/public/interfaces/ash_message_center_controller.mojom index 639a764..199cceb 100644 --- a/ash/public/interfaces/ash_message_center_controller.mojom +++ b/ash/public/interfaces/ash_message_center_controller.mojom
@@ -8,6 +8,7 @@ import "ui/message_center/public/mojo/notification.mojom"; import "ui/message_center/public/mojo/notifier_id.mojom"; import "mojo/public/mojom/base/string16.mojom"; +import "mojo/public/mojom/base/unguessable_token.mojom"; // A struct that contains information for presenting a notifier in a settings // panel. @@ -33,8 +34,12 @@ interface AshMessageCenterController { SetClient(associated AshMessageCenterClient client); - ShowClientNotification(message_center.mojom.Notification notification); + // Shows a notification. |display_token| will be used to reference this + // notification for AshMessageCenterClient::Close(). + ShowClientNotification(message_center.mojom.Notification notification, + mojo_base.mojom.UnguessableToken display_token); + // Closes a notification by the notification ID. CloseClientNotification(string id); UpdateNotifierIcon(message_center.mojom.NotifierId notifier_id, @@ -54,7 +59,8 @@ // the client. interface AshMessageCenterClient { // Called when a notification previously displayed by the client is closed. - HandleNotificationClosed(string id, bool by_user); + HandleNotificationClosed(mojo_base.mojom.UnguessableToken display_token, + bool by_user); // Called when the body of a notification is clicked. HandleNotificationClicked(string id);
diff --git a/ash/shell/app_list.cc b/ash/shell/app_list.cc index 4ebe7c3..130e548 100644 --- a/ash/shell/app_list.cc +++ b/ash/shell/app_list.cc
@@ -184,11 +184,6 @@ WindowTypeShelfItem::Type type() const { return type_; } - // app_list::SearchResult: - std::unique_ptr<SearchResult> Duplicate() const override { - return std::unique_ptr<SearchResult>(); - } - private: WindowTypeShelfItem::Type type_;
diff --git a/ash/wm/overview/window_selector_unittest.cc b/ash/wm/overview/window_selector_unittest.cc index bb95233..77a3e99 100644 --- a/ash/wm/overview/window_selector_unittest.cc +++ b/ash/wm/overview/window_selector_unittest.cc
@@ -2908,7 +2908,8 @@ } // Verify that attempting to drag with a secondary finger works as expected. -TEST_F(WindowSelectorTest, DraggingWithTwoFingers) { +// Flaky, see https://crbug.com/827435. +TEST_F(WindowSelectorTest, DISABLED_DraggingWithTwoFingers) { std::unique_ptr<aura::Window> window1 = CreateTestWindow(); std::unique_ptr<aura::Window> window2 = CreateTestWindow();
diff --git a/base/BUILD.gn b/base/BUILD.gn index 78cc8a74..d235a66 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2270,7 +2270,6 @@ "optional_unittest.cc", "os_compat_android_unittest.cc", "path_service_unittest.cc", - "pending_task_unittest.cc", "pickle_unittest.cc", "posix/file_descriptor_shuffle_unittest.cc", "posix/unix_domain_socket_unittest.cc",
diff --git a/base/base_switches.cc b/base/base_switches.cc index 9f33d0bf..62e6d3dc 100644 --- a/base/base_switches.cc +++ b/base/base_switches.cc
@@ -7,6 +7,9 @@ namespace switches { +// Delays execution of base::TaskPriority::BACKGROUND tasks until shutdown. +const char kDisableBackgroundTasks[] = "disable-background-tasks"; + // Disables the crash reporting. const char kDisableBreakpad[] = "disable-breakpad";
diff --git a/base/base_switches.h b/base/base_switches.h index e5b9453..a444f09b 100644 --- a/base/base_switches.h +++ b/base/base_switches.h
@@ -11,6 +11,7 @@ namespace switches { +extern const char kDisableBackgroundTasks[]; extern const char kDisableBreakpad[]; extern const char kDisableFeatures[]; extern const char kDisableLowEndDeviceMode[];
diff --git a/base/debug/task_annotator.cc b/base/debug/task_annotator.cc index d67412be..2197b8591 100644 --- a/base/debug/task_annotator.cc +++ b/base/debug/task_annotator.cc
@@ -8,12 +8,29 @@ #include "base/debug/activity_tracker.h" #include "base/debug/alias.h" +#include "base/no_destructor.h" #include "base/pending_task.h" +#include "base/threading/thread_local.h" #include "base/trace_event/trace_event.h" namespace base { namespace debug { +namespace { + +TaskAnnotator::ObserverForTesting* g_task_annotator_observer = nullptr; + +// Returns the TLS slot that stores the PendingTask currently in progress on +// each thread. Used to allow creating a breadcrumb of program counters on the +// stack to help identify a task's origin in crashes. +ThreadLocalPointer<const PendingTask>* GetTLSForCurrentPendingTask() { + static NoDestructor<ThreadLocalPointer<const PendingTask>> + tls_for_current_pending_task; + return tls_for_current_pending_task.get(); +} + +} // namespace + TaskAnnotator::TaskAnnotator() = default; TaskAnnotator::~TaskAnnotator() = default; @@ -26,6 +43,21 @@ TRACE_ID_MANGLE(GetTaskTraceID(pending_task)), TRACE_EVENT_FLAG_FLOW_OUT); } + + // TODO(https://crbug.com/826902): Fix callers that invoke DidQueueTask() + // twice for the same PendingTask. + // DCHECK(!pending_task.task_backtrace[0]) + // << "Task backtrace was already set, task posted twice??"; + if (!pending_task.task_backtrace[0]) { + const PendingTask* parent_task = GetTLSForCurrentPendingTask()->Get(); + if (parent_task) { + pending_task.task_backtrace[0] = + parent_task->posted_from.program_counter(); + std::copy(parent_task->task_backtrace.begin(), + parent_task->task_backtrace.end() - 1, + pending_task.task_backtrace.begin() + 1); + } + } } void TaskAnnotator::RunTask(const char* queue_function, @@ -58,7 +90,17 @@ pending_task->task_backtrace.end(), task_backtrace.begin() + 2); debug::Alias(&task_backtrace); + ThreadLocalPointer<const PendingTask>* tls_for_current_pending_task = + GetTLSForCurrentPendingTask(); + const PendingTask* previous_pending_task = + tls_for_current_pending_task->Get(); + tls_for_current_pending_task->Set(pending_task); + + if (g_task_annotator_observer) + g_task_annotator_observer->BeforeRunTask(pending_task); std::move(pending_task->task).Run(); + + tls_for_current_pending_task->Set(previous_pending_task); } uint64_t TaskAnnotator::GetTaskTraceID(const PendingTask& task) const { @@ -67,5 +109,16 @@ 32); } +// static +void TaskAnnotator::RegisterObserverForTesting(ObserverForTesting* observer) { + DCHECK(!g_task_annotator_observer); + g_task_annotator_observer = observer; +} + +// static +void TaskAnnotator::ClearObserverForTesting() { + g_task_annotator_observer = nullptr; +} + } // namespace debug } // namespace base
diff --git a/base/debug/task_annotator.h b/base/debug/task_annotator.h index de03e41..f53d02c 100644 --- a/base/debug/task_annotator.h +++ b/base/debug/task_annotator.h
@@ -18,6 +18,13 @@ // such as task origins, queueing durations and memory usage. class BASE_EXPORT TaskAnnotator { public: + class ObserverForTesting { + public: + // Invoked just before RunTask() in the scope in which the task is about to + // be executed. + virtual void BeforeRunTask(const PendingTask* pending_task) = 0; + }; + TaskAnnotator(); ~TaskAnnotator(); @@ -40,6 +47,14 @@ uint64_t GetTaskTraceID(const PendingTask& task) const; private: + friend class TaskAnnotatorBacktraceIntegrationTest; + + // Registers an ObserverForTesting that will be invoked by all TaskAnnotators' + // RunTask(). This registration and the implementation of BeforeRunTask() are + // responsible to ensure thread-safety. + static void RegisterObserverForTesting(ObserverForTesting* observer); + static void ClearObserverForTesting(); + DISALLOW_COPY_AND_ASSIGN(TaskAnnotator); };
diff --git a/base/debug/task_annotator_unittest.cc b/base/debug/task_annotator_unittest.cc index bfb0e7c..51a5d32 100644 --- a/base/debug/task_annotator_unittest.cc +++ b/base/debug/task_annotator_unittest.cc
@@ -3,8 +3,24 @@ // found in the LICENSE file. #include "base/debug/task_annotator.h" + +#include <algorithm> +#include <vector> + #include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/callback.h" +#include "base/macros.h" +#include "base/message_loop/message_loop.h" #include "base/pending_task.h" +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "base/synchronization/lock.h" +#include "base/synchronization/waitable_event.h" +#include "base/task_scheduler/post_task.h" +#include "base/test/scoped_task_environment.h" +#include "base/threading/thread.h" +#include "base/threading/thread_task_runner_handle.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { @@ -28,5 +44,328 @@ EXPECT_EQ(123, result); } +// Test task annotator integration in base APIs and ensuing support for +// backtraces. Tasks posted across multiple threads in this test fixture should +// be synchronized as BeforeRunTask() and VerifyTraceAndPost() assume tasks are +// observed in lock steps, one at a time. +class TaskAnnotatorBacktraceIntegrationTest + : public ::testing::Test, + public TaskAnnotator::ObserverForTesting { + public: + using ExpectedTrace = std::vector<const void*>; + + TaskAnnotatorBacktraceIntegrationTest() = default; + + ~TaskAnnotatorBacktraceIntegrationTest() override = default; + + // TaskAnnotator::ObserverForTesting: + void BeforeRunTask(const PendingTask* pending_task) override { + AutoLock auto_lock(on_before_run_task_lock_); + last_posted_from_ = pending_task->posted_from; + last_task_backtrace_ = pending_task->task_backtrace; + } + + void SetUp() override { TaskAnnotator::RegisterObserverForTesting(this); } + + void TearDown() override { TaskAnnotator::ClearObserverForTesting(); } + + void VerifyTraceAndPost(const scoped_refptr<SequencedTaskRunner>& task_runner, + const Location& posted_from, + const Location& next_from_here, + const ExpectedTrace& expected_trace, + OnceClosure task) { + SCOPED_TRACE(StringPrintf("Callback Depth: %zu", expected_trace.size())); + + EXPECT_EQ(posted_from, last_posted_from_); + for (size_t i = 0; i < last_task_backtrace_.size(); i++) { + SCOPED_TRACE(StringPrintf("Trace frame: %zu", i)); + if (i < expected_trace.size()) + EXPECT_EQ(expected_trace[i], last_task_backtrace_[i]); + else + EXPECT_EQ(nullptr, last_task_backtrace_[i]); + } + + task_runner->PostTask(next_from_here, std::move(task)); + } + + // Same as VerifyTraceAndPost() with the exception that it also posts a task + // that will prevent |task| from running until |wait_before_next_task| is + // signaled. + void VerifyTraceAndPostWithBlocker( + const scoped_refptr<SequencedTaskRunner>& task_runner, + const Location& posted_from, + const Location& next_from_here, + const ExpectedTrace& expected_trace, + OnceClosure task, + WaitableEvent* wait_before_next_task) { + DCHECK(wait_before_next_task); + + // Need to lock to ensure the upcoming VerifyTraceAndPost() runs before the + // BeforeRunTask() hook for the posted WaitableEvent::Wait(). Otherwise the + // upcoming VerifyTraceAndPost() will race to read the state saved in the + // BeforeRunTask() hook preceding the current task. + AutoLock auto_lock(on_before_run_task_lock_); + task_runner->PostTask( + FROM_HERE, + BindOnce(&WaitableEvent::Wait, Unretained(wait_before_next_task))); + VerifyTraceAndPost(task_runner, posted_from, next_from_here, expected_trace, + std::move(task)); + } + + protected: + static void RunTwo(OnceClosure c1, OnceClosure c2) { + std::move(c1).Run(); + std::move(c2).Run(); + } + + private: + // While calls to VerifyTraceAndPost() are strictly ordered in tests below + // (and hence non-racy), some helper methods (e.g. Wait/Signal) do racily call + // into BeforeRunTask(). This Lock ensures these unobserved writes are not + // racing. Locking isn't required on read per the VerifyTraceAndPost() + // themselves being ordered. + Lock on_before_run_task_lock_; + + Location last_posted_from_ = {}; + std::array<const void*, 4> last_task_backtrace_ = {}; + + DISALLOW_COPY_AND_ASSIGN(TaskAnnotatorBacktraceIntegrationTest); +}; + +// Ensure the task backtrace populates correctly. +TEST_F(TaskAnnotatorBacktraceIntegrationTest, SingleThreadedSimple) { + MessageLoop loop; + const Location location0 = FROM_HERE; + const Location location1 = FROM_HERE; + const Location location2 = FROM_HERE; + const Location location3 = FROM_HERE; + const Location location4 = FROM_HERE; + const Location location5 = FROM_HERE; + + RunLoop run_loop; + + // Task 5 has tasks 4/3/2/1 as parents (task 0 isn't visible as only the + // last 4 parents are kept). + OnceClosure task5 = BindOnce( + &TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location5, FROM_HERE, + ExpectedTrace({location4.program_counter(), location3.program_counter(), + location2.program_counter(), location1.program_counter()}), + run_loop.QuitClosure()); + + // Task i=4/3/2/1/0 have tasks [0,i) as parents. + OnceClosure task4 = BindOnce( + &TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location4, location5, + ExpectedTrace({location3.program_counter(), location2.program_counter(), + location1.program_counter(), location0.program_counter()}), + std::move(task5)); + OnceClosure task3 = BindOnce( + &TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location3, location4, + ExpectedTrace({location2.program_counter(), location1.program_counter(), + location0.program_counter()}), + std::move(task4)); + OnceClosure task2 = BindOnce( + &TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location2, location3, + ExpectedTrace({location1.program_counter(), location0.program_counter()}), + std::move(task3)); + OnceClosure task1 = + BindOnce(&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location1, location2, + ExpectedTrace({location0.program_counter()}), std::move(task2)); + OnceClosure task0 = + BindOnce(&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location0, location1, + ExpectedTrace({}), std::move(task1)); + + loop.task_runner()->PostTask(location0, std::move(task0)); + + run_loop.Run(); +} + +// Ensure it works when posting tasks across multiple threads managed by //base. +TEST_F(TaskAnnotatorBacktraceIntegrationTest, MultipleThreads) { + test::ScopedTaskEnvironment scoped_task_environment; + + // Use diverse task runners (a MessageLoop on the main thread, a TaskScheduler + // based SequencedTaskRunner, and a TaskScheduler based + // SingleThreadTaskRunner) to verify that TaskAnnotator can capture backtraces + // for PostTasks back-and-forth between these. + auto main_thread_a = ThreadTaskRunnerHandle::Get(); + auto task_runner_b = CreateSingleThreadTaskRunnerWithTraits({}); + auto task_runner_c = CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::WithBaseSyncPrimitives()}); + + const Location& location_a0 = FROM_HERE; + const Location& location_a1 = FROM_HERE; + const Location& location_a2 = FROM_HERE; + const Location& location_a3 = FROM_HERE; + + const Location& location_b0 = FROM_HERE; + const Location& location_b1 = FROM_HERE; + + const Location& location_c0 = FROM_HERE; + + RunLoop run_loop; + + // All tasks below happen in lock step by nature of being posted by the + // previous one (plus the synchronous nature of RunTwo()) with the exception + // of the follow-up local task to |task_b0_local|. This WaitableEvent ensures + // it completes before |task_c0| runs to avoid racy invocations of + // BeforeRunTask()+VerifyTraceAndPost(). + WaitableEvent lock_step(WaitableEvent::ResetPolicy::AUTOMATIC, + WaitableEvent::InitialState::NOT_SIGNALED); + + // Here is the execution order generated below: + // A: TA0 -> TA1 \ TA2 + // B: TB0L \ + TB0F \ Signal \ / + // ---------\--/ \ / + // \ \ / + // C: Wait........ TC0 / + + // On task runner c, post a task back to main thread that verifies its trace + // and terminates after one more self-post. + OnceClosure task_a2 = BindOnce( + &TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), main_thread_a, location_a2, location_a3, + ExpectedTrace( + {location_c0.program_counter(), location_b0.program_counter(), + location_a1.program_counter(), location_a0.program_counter()}), + run_loop.QuitClosure()); + OnceClosure task_c0 = + BindOnce(&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), main_thread_a, location_c0, location_a2, + ExpectedTrace({location_b0.program_counter(), + location_a1.program_counter(), + location_a0.program_counter()}), + std::move(task_a2)); + + // On task runner b run two tasks that conceptually come from the same + // location (managed via RunTwo().) One will post back to task runner b and + // another will post to task runner c to test spawning multiple tasks on + // different message loops. The task posted to task runner c will not get + // location b1 whereas the one posted back to task runner b will. + OnceClosure task_b0_fork = BindOnce( + &TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPostWithBlocker, + Unretained(this), task_runner_c, location_b0, location_c0, + ExpectedTrace( + {location_a1.program_counter(), location_a0.program_counter()}), + std::move(task_c0), &lock_step); + OnceClosure task_b0_local = + BindOnce(&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), task_runner_b, location_b0, location_b1, + ExpectedTrace({location_a1.program_counter(), + location_a0.program_counter()}), + BindOnce(&WaitableEvent::Signal, Unretained(&lock_step))); + + OnceClosure task_a1 = + BindOnce(&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), task_runner_b, location_a1, location_b0, + ExpectedTrace({location_a0.program_counter()}), + BindOnce(&TaskAnnotatorBacktraceIntegrationTest::RunTwo, + std::move(task_b0_local), std::move(task_b0_fork))); + OnceClosure task_a0 = + BindOnce(&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), main_thread_a, location_a0, location_a1, + ExpectedTrace({}), std::move(task_a1)); + + main_thread_a->PostTask(location_a0, std::move(task_a0)); + + run_loop.Run(); +} + +// Ensure nesting doesn't break the chain. +TEST_F(TaskAnnotatorBacktraceIntegrationTest, SingleThreadedNested) { + MessageLoop loop; + const Location location0 = FROM_HERE; + const Location location1 = FROM_HERE; + const Location location2 = FROM_HERE; + const Location location3 = FROM_HERE; + const Location location4 = FROM_HERE; + const Location location5 = FROM_HERE; + + RunLoop run_loop; + + // Task execution below looks like this, w.r.t. to RunLoop depths: + // 1 : T0 \ + NRL1 \ ---------> T4 -> T5 + // 2 : ---------> T1 \ -> NRL2 \ ----> T2 -> T3 / + Quit / + // 3 : ---------> DN / + + // NRL1 tests that tasks that occur at a different nesting depth than their + // parent have a sane backtrace nonetheless (both ways). + + // NRL2 tests that posting T2 right after exiting the RunLoop (from the same + // task) results in NRL2 being its parent (and not the DoNothing() task that + // just ran -- which would have been the case if the "current task" wasn't + // restored properly when returning from a task within a task). + + // In other words, this is regression test for a bug in the previous + // implementation. In the current implementation, replacing + // tls_for_current_pending_task->Set(previous_pending_task); + // by + // tls_for_current_pending_task->Set(nullptr); + // at the end of TaskAnnotator::RunTask() makes this test fail. + + RunLoop nested_run_loop1(RunLoop::Type::kNestableTasksAllowed); + + // Expectations are the same as in SingleThreadedSimple test despite the + // nested loop starting between tasks 0 and 1 and stopping between tasks 3 and + // 4. + OnceClosure task5 = BindOnce( + &TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location5, FROM_HERE, + ExpectedTrace({location4.program_counter(), location3.program_counter(), + location2.program_counter(), location1.program_counter()}), + run_loop.QuitClosure()); + OnceClosure task4 = BindOnce( + &TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location4, location5, + ExpectedTrace({location3.program_counter(), location2.program_counter(), + location1.program_counter(), location0.program_counter()}), + std::move(task5)); + OnceClosure task3 = BindOnce( + &TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location3, location4, + ExpectedTrace({location2.program_counter(), location1.program_counter(), + location0.program_counter()}), + std::move(task4)); + + OnceClosure run_task_3_then_quit_nested_loop1 = + BindOnce(&TaskAnnotatorBacktraceIntegrationTest::RunTwo, std::move(task3), + nested_run_loop1.QuitClosure()); + + OnceClosure task2 = BindOnce( + &TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location2, location3, + ExpectedTrace({location1.program_counter(), location0.program_counter()}), + std::move(run_task_3_then_quit_nested_loop1)); + + // Task 1 is custom. It enters another nested RunLoop, has it do work and exit + // before posting the next task. This confirms that |task1| is restored as the + // current task before posting |task2| after returning from the nested loop. + RunLoop nested_run_loop2(RunLoop::Type::kNestableTasksAllowed); + OnceClosure task1 = BindOnce( + [](RunLoop* nested_run_loop, const Location& location2, + OnceClosure task2) { + ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, DoNothing()); + nested_run_loop->RunUntilIdle(); + ThreadTaskRunnerHandle::Get()->PostTask(location2, std::move(task2)); + }, + Unretained(&nested_run_loop2), location2, std::move(task2)); + + OnceClosure task0 = + BindOnce(&TaskAnnotatorBacktraceIntegrationTest::VerifyTraceAndPost, + Unretained(this), loop.task_runner(), location0, location1, + ExpectedTrace({}), std::move(task1)); + + loop.task_runner()->PostTask(location0, std::move(task0)); + loop.task_runner()->PostTask( + FROM_HERE, BindOnce(&RunLoop::Run, Unretained(&nested_run_loop1))); + + run_loop.Run(); +} + } // namespace debug } // namespace base
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc index 92874be0..41cb4f4 100644 --- a/base/message_loop/message_loop.cc +++ b/base/message_loop/message_loop.cc
@@ -343,7 +343,6 @@ void MessageLoop::RunTask(PendingTask* pending_task) { DCHECK(task_execution_allowed_); - current_pending_task_ = pending_task; // Execute the task and assume the worst: It is probably not reentrant. task_execution_allowed_ = false; @@ -357,8 +356,6 @@ observer.DidProcessTask(*pending_task); task_execution_allowed_ = true; - - current_pending_task_ = nullptr; } bool MessageLoop::DeferOrRunPendingTask(PendingTask pending_task) {
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h index 81d445f..f508e1a 100644 --- a/base/message_loop/message_loop.h +++ b/base/message_loop/message_loop.h
@@ -288,9 +288,7 @@ friend class internal::IncomingTaskQueue; friend class ScheduleWorkTest; friend class Thread; - friend struct PendingTask; FRIEND_TEST_ALL_PREFIXES(MessageLoopTest, DeleteUnboundLoop); - friend class PendingTaskTest; // Creates a MessageLoop without binding to a thread. // If |type| is TYPE_CUSTOM non-null |pump_factory| must be also given @@ -365,13 +363,6 @@ ObserverList<TaskObserver> task_observers_; - // Used to allow creating a breadcrumb of program counters in PostTask. - // This variable is only initialized while a task is being executed and is - // meant only to store context for creating a backtrace breadcrumb. Do not - // attach other semantics to it without thinking through the use caes - // thoroughly. - const PendingTask* current_pending_task_ = nullptr; - scoped_refptr<internal::IncomingTaskQueue> incoming_task_queue_; // A task runner which we haven't bound to a thread yet.
diff --git a/base/message_loop/message_pump_for_io.h b/base/message_loop/message_pump_for_io.h index 78a8096..6aac1e6 100644 --- a/base/message_loop/message_pump_for_io.h +++ b/base/message_loop/message_pump_for_io.h
@@ -36,7 +36,7 @@ #elif defined(OS_POSIX) using MessagePumpForIO = MessagePumpLibevent; #else -#error Platform doesn't define MessagePumpForIO +#error Platform does not define MessagePumpForIO #endif } // namespace base
diff --git a/base/message_loop/message_pump_for_ui.h b/base/message_loop/message_pump_for_ui.h index 09db352..2d3e175 100644 --- a/base/message_loop/message_pump_for_ui.h +++ b/base/message_loop/message_pump_for_ui.h
@@ -47,7 +47,7 @@ #elif defined(OS_FUCHSIA) using MessagePumpForUI = MessagePumpFuchsia; #else -#error Platform doesn't define MessagePumpForUI +#error Platform does not define MessagePumpForUI #endif } // namespace base
diff --git a/base/pending_task.cc b/base/pending_task.cc index 31f2d2d..7224a6b0 100644 --- a/base/pending_task.cc +++ b/base/pending_task.cc
@@ -15,21 +15,7 @@ : task(std::move(task)), posted_from(posted_from), delayed_run_time(delayed_run_time), - sequence_num(0), - nestable(nestable), - is_high_res(false) { - const PendingTask* parent_task = - MessageLoop::current() ? MessageLoop::current()->current_pending_task_ - : nullptr; - if (parent_task) { - task_backtrace[0] = parent_task->posted_from.program_counter(); - std::copy(parent_task->task_backtrace.begin(), - parent_task->task_backtrace.end() - 1, - task_backtrace.begin() + 1); - } else { - task_backtrace.fill(nullptr); - } -} + nestable(nestable) {} PendingTask::PendingTask(PendingTask&& other) = default;
diff --git a/base/pending_task.h b/base/pending_task.h index 8c7854b..495015b 100644 --- a/base/pending_task.h +++ b/base/pending_task.h
@@ -44,17 +44,18 @@ // The time when the task should be run. base::TimeTicks delayed_run_time; - // Task backtrace. - std::array<const void*, 4> task_backtrace; + // Task backtrace. mutable so it can be set while annotating const PendingTask + // objects from TaskAnnotator::DidQueueTask(). + mutable std::array<const void*, 4> task_backtrace = {}; // Secondary sort key for run time. - int sequence_num; + int sequence_num = 0; // OK to dispatch from a nested loop. Nestable nestable; // Needs high resolution timers. - bool is_high_res; + bool is_high_res = false; }; using TaskQueue = base::queue<PendingTask>;
diff --git a/base/pending_task_unittest.cc b/base/pending_task_unittest.cc deleted file mode 100644 index 2a3e0c01..0000000 --- a/base/pending_task_unittest.cc +++ /dev/null
@@ -1,169 +0,0 @@ -// Copyright (c) 2017 The Chromium Authors. 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/pending_task.h" - -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace base { - -class PendingTaskTest : public ::testing::Test { - public: - PendingTaskTest() = default; - - ~PendingTaskTest() override = default; - - protected: - using ExpectedTrace = std::vector<const void*>; - - static void VerifyTraceAndPost(const scoped_refptr<TaskRunner>& task_runner, - const Location& posted_from, - const Location& next_from_here, - const std::vector<const void*>& expected_trace, - Closure task) { - SCOPED_TRACE(StringPrintf("Callback Depth: %zu", expected_trace.size())); - - // Beyond depth + 1, the trace is nonsensical because there haven't been - // enough nested tasks called. - const PendingTask* current_pending_task = - MessageLoop::current()->current_pending_task_; - size_t window = std::min(current_pending_task->task_backtrace.size(), - expected_trace.size()); - - EXPECT_EQ(posted_from, - MessageLoop::current()->current_pending_task_->posted_from); - for (size_t i = 0; i < window; i++) { - SCOPED_TRACE(StringPrintf("Trace frame: %zu", i)); - EXPECT_EQ(expected_trace[i], current_pending_task->task_backtrace[i]); - } - task_runner->PostTask(next_from_here, std::move(task)); - } - - static void RunTwo(Closure c1, Closure c2) { - c1.Run(); - c2.Run(); - } -}; - -// Ensure the task backtrace populates correctly. -TEST_F(PendingTaskTest, SingleThreadedSimple) { - MessageLoop loop; - const Location& location0 = FROM_HERE; - const Location& location1 = FROM_HERE; - const Location& location2 = FROM_HERE; - const Location& location3 = FROM_HERE; - const Location& location4 = FROM_HERE; - const Location& location5 = FROM_HERE; - - Closure task5 = Bind( - &PendingTaskTest::VerifyTraceAndPost, loop.task_runner(), location4, - location5, - ExpectedTrace({location3.program_counter(), location2.program_counter(), - location1.program_counter(), location0.program_counter()}), - DoNothing()); - Closure task4 = Bind( - &PendingTaskTest::VerifyTraceAndPost, loop.task_runner(), location3, - location4, - ExpectedTrace({location2.program_counter(), location1.program_counter(), - location0.program_counter(), nullptr}), - task5); - Closure task3 = Bind( - &PendingTaskTest::VerifyTraceAndPost, loop.task_runner(), location2, - location3, ExpectedTrace({location1.program_counter(), - location0.program_counter(), nullptr, nullptr}), - task4); - Closure task2 = - Bind(&PendingTaskTest::VerifyTraceAndPost, loop.task_runner(), location1, - location2, ExpectedTrace({location0.program_counter()}), task3); - Closure task1 = Bind(&PendingTaskTest::VerifyTraceAndPost, loop.task_runner(), - location0, location1, ExpectedTrace({}), task2); - - loop.task_runner()->PostTask(location0, task1); - - RunLoop().RunUntilIdle(); -} - -// Post a task onto another thread. Ensure on the other thread, it has the -// right stack trace. -TEST_F(PendingTaskTest, MultipleThreads) { - MessageLoop loop; // Implicitly "thread a." - Thread thread_b("pt_test_b"); - Thread thread_c("pt_test_c"); - thread_b.StartAndWaitForTesting(); - thread_c.StartAndWaitForTesting(); - - const Location& location_a0 = FROM_HERE; - const Location& location_a1 = FROM_HERE; - const Location& location_a2 = FROM_HERE; - const Location& location_a3 = FROM_HERE; - - const Location& location_b0 = FROM_HERE; - const Location& location_b1 = FROM_HERE; - - const Location& location_c0 = FROM_HERE; - - // On thread c, post a task back to thread a that verifies its trace - // and terminates after one more self-post. - Closure task_a2 = - Bind(&PendingTaskTest::VerifyTraceAndPost, loop.task_runner(), - location_a2, location_a3, - ExpectedTrace( - {location_c0.program_counter(), location_b0.program_counter(), - location_a1.program_counter(), location_a0.program_counter()}), - DoNothing()); - Closure task_c0 = Bind(&PendingTaskTest::VerifyTraceAndPost, - loop.task_runner(), location_c0, location_a2, - ExpectedTrace({location_b0.program_counter(), - location_a1.program_counter(), - location_a0.program_counter()}), - task_a2); - - // On thread b run two tasks that conceptually come from the same location - // (managed via RunTwo().) One will post back to thread b and another will - // post to thread c to test spawning multiple tasks on different message - // loops. The task posted to thread c will not get location b1 whereas the - // one posted back to thread b will. - Closure task_b0_fork = - Bind(&PendingTaskTest::VerifyTraceAndPost, - thread_c.message_loop()->task_runner(), location_b0, location_c0, - ExpectedTrace({location_a1.program_counter(), - location_a0.program_counter(), nullptr}), - task_c0); - Closure task_b0_local = - Bind(&PendingTaskTest::VerifyTraceAndPost, - thread_b.message_loop()->task_runner(), location_b0, location_b1, - ExpectedTrace({location_a1.program_counter(), - location_a0.program_counter(), nullptr}), - DoNothing()); - - // Push one frame onto the stack in thread a then pass to thread b. - Closure task_a1 = - Bind(&PendingTaskTest::VerifyTraceAndPost, - thread_b.message_loop()->task_runner(), location_a1, location_b0, - ExpectedTrace({location_a0.program_counter(), nullptr}), - Bind(&PendingTaskTest::RunTwo, task_b0_local, task_b0_fork)); - Closure task_a0 = - Bind(&PendingTaskTest::VerifyTraceAndPost, loop.task_runner(), - location_a0, location_a1, ExpectedTrace({nullptr}), task_a1); - - loop.task_runner()->PostTask(location_a0, task_a0); - - RunLoop().RunUntilIdle(); - - thread_b.FlushForTesting(); - thread_b.Stop(); - - thread_c.FlushForTesting(); - thread_c.Stop(); -} - -} // namespace base
diff --git a/base/sys_info.h b/base/sys_info.h index a2f20c7..6e58715 100644 --- a/base/sys_info.h +++ b/base/sys_info.h
@@ -64,16 +64,6 @@ // on failure. static int64_t AmountOfTotalDiskSpace(const FilePath& path); -#if defined(OS_POSIX) && !defined(OS_ANDROID) - // Returns the total number of inodes on the volume containing |path|, or -1 - // on failure. - static int64_t AmountOfMaxDiskInode(const FilePath& path); - - // Returns the number of inodes available to non-root on the volume containing - // |path|, or -1 on failure. - static int64_t AmountOfAvailableDiskInode(const FilePath& path); -#endif - // Returns system uptime. static TimeDelta Uptime();
diff --git a/base/sys_info_posix.cc b/base/sys_info_posix.cc index 27de28a..f6fcd10 100644 --- a/base/sys_info_posix.cc +++ b/base/sys_info_posix.cc
@@ -237,20 +237,4 @@ return getpagesize(); } -#if !defined(OS_ANDROID) -int64_t SysInfo::AmountOfMaxDiskInode(const FilePath& path) { - struct statvfs stats; - if (HANDLE_EINTR(statvfs(path.value().c_str(), &stats)) != 0) - return -1; - return static_cast<int64_t>(stats.f_files); -} - -int64_t SysInfo::AmountOfAvailableDiskInode(const FilePath& path) { - struct statvfs stats; - if (HANDLE_EINTR(statvfs(path.value().c_str(), &stats)) != 0) - return -1; - return static_cast<int64_t>(stats.f_favail); -} -#endif // !defined(OS_ANDROID) - } // namespace base
diff --git a/base/task_scheduler/task_tracker.cc b/base/task_scheduler/task_tracker.cc index a78e40a..f72a302 100644 --- a/base/task_scheduler/task_tracker.cc +++ b/base/task_scheduler/task_tracker.cc
@@ -8,7 +8,9 @@ #include <string> #include <vector> +#include "base/base_switches.h" #include "base/callback.h" +#include "base/command_line.h" #include "base/json/json_writer.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" @@ -105,6 +107,19 @@ kMaxBlockShutdownTasksPostedDuringShutdown, 50); } +// Returns the maximum number of TaskPriority::BACKGROUND sequences that can be +// scheduled concurrently based on command line flags. +int GetMaxNumScheduledBackgroundSequences() { + // The CommandLine might not be initialized if TaskScheduler is initialized + // in a dynamic library which doesn't have access to argc/argv. + if (CommandLine::InitializedForCurrentProcess() && + CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableBackgroundTasks)) { + return 0; + } + return std::numeric_limits<int>::max(); +} + } // namespace // Atomic internal state used by TaskTracker. Sequential consistency shouldn't @@ -226,6 +241,9 @@ DISALLOW_COPY_AND_ASSIGN(PreemptedBackgroundSequence); }; +TaskTracker::TaskTracker(StringPiece histogram_label) + : TaskTracker(histogram_label, GetMaxNumScheduledBackgroundSequences()) {} + TaskTracker::TaskTracker(StringPiece histogram_label, int max_num_scheduled_background_sequences) : state_(new State),
diff --git a/base/task_scheduler/task_tracker.h b/base/task_scheduler/task_tracker.h index 2da33ff..37de128 100644 --- a/base/task_scheduler/task_tracker.h +++ b/base/task_scheduler/task_tracker.h
@@ -87,12 +87,14 @@ class BASE_EXPORT TaskTracker { public: // |histogram_label| is used as a suffix for histograms, it must not be empty. - // |max_num_scheduled_background_sequences| is the maximum number of - // background sequences that can be scheduled concurrently during normal - // execution (ignored during shutdown). + // The first constructor sets the maximum number of TaskPriority::BACKGROUND + // sequences that can be scheduled concurrently to 0 if the + // --disable-background-tasks flag is specified, max() otherwise. The second + // constructor sets it to |max_num_scheduled_background_sequences|. + TaskTracker(StringPiece histogram_label); TaskTracker(StringPiece histogram_label, - int max_num_scheduled_background_sequences = - std::numeric_limits<int>::max()); + int max_num_scheduled_background_sequences); + virtual ~TaskTracker(); // Synchronously shuts down the scheduler. Once this is called, only tasks
diff --git a/base/task_scheduler/task_tracker_posix.cc b/base/task_scheduler/task_tracker_posix.cc index d929aac..8289d90 100644 --- a/base/task_scheduler/task_tracker_posix.cc +++ b/base/task_scheduler/task_tracker_posix.cc
@@ -11,9 +11,7 @@ namespace base { namespace internal { -TaskTrackerPosix::TaskTrackerPosix(StringPiece name, - int max_num_scheduled_background_sequences) - : TaskTracker(name, max_num_scheduled_background_sequences) {} +TaskTrackerPosix::TaskTrackerPosix(StringPiece name) : TaskTracker(name) {} TaskTrackerPosix::~TaskTrackerPosix() = default; void TaskTrackerPosix::RunOrSkipTask(Task task,
diff --git a/base/task_scheduler/task_tracker_posix.h b/base/task_scheduler/task_tracker_posix.h index 60b7f370..4689f7a1 100644 --- a/base/task_scheduler/task_tracker_posix.h +++ b/base/task_scheduler/task_tracker_posix.h
@@ -5,7 +5,6 @@ #ifndef BASE_TASK_SCHEDULER_TASK_TRACKER_POSIX_H_ #define BASE_TASK_SCHEDULER_TASK_TRACKER_POSIX_H_ -#include <limits> #include <memory> #include "base/base_export.h" @@ -28,10 +27,7 @@ // TaskTracker can run tasks. class BASE_EXPORT TaskTrackerPosix : public TaskTracker { public: - // This must match the signature of TaskTracker() to allow interchangeability. - TaskTrackerPosix(StringPiece name, - int max_num_scheduled_background_sequences = - std::numeric_limits<int>::max()); + TaskTrackerPosix(StringPiece name); ~TaskTrackerPosix() override; // Sets the MessageLoopForIO with which to setup FileDescriptorWatcher in the
diff --git a/base/threading/scoped_blocking_call.h b/base/threading/scoped_blocking_call.h index c8c4b36..e376c308 100644 --- a/base/threading/scoped_blocking_call.h +++ b/base/threading/scoped_blocking_call.h
@@ -24,14 +24,54 @@ class BlockingObserver; } -// This class can be instantiated in a scope where a a blocking call (which -// isn't using local computing resources -- e.g. a synchronous network request) -// is made. Instantiation will hint the BlockingObserver for this thread about -// the scope of the blocking operation. +// This class must be instantiated in every scope where a blocking call is made. +// CPU usage should be minimal within that scope. //base APIs that block +// instantiate their own ScopedBlockingCall; it is not necessary to instantiate +// another ScopedBlockingCall in the scope where these APIs are used. // -// In particular, when instantiated from a TaskScheduler parallel or sequenced -// task, this will allow the thread to be replaced in its pool (more or less -// aggressively depending on BlockingType). +// Good: +// Data data; +// { +// ScopedBlockingCall scoped_blocking_call(BlockingType::WILL_BLOCK); +// data = GetDataFromNetwork(); +// } +// CPUIntensiveProcessing(data); +// +// Bad: +// ScopedBlockingCall scoped_blocking_call(BlockingType::WILL_BLOCK); +// Data data = GetDataFromNetwork(); +// CPUIntensiveProcessing(data); // CPU usage within a ScopedBlockingCall. +// +// Good: +// Data a; +// Data b; +// { +// ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK); +// a = GetDataFromMemoryCacheOrNetwork(); +// b = GetDataFromMemoryCacheOrNetwork(); +// } +// CPUIntensiveProcessing(a); +// CPUIntensiveProcessing(b); +// +// Bad: +// ScopedBlockingCall scoped_blocking_call(BlockingType::MAY_BLOCK); +// Data a = GetDataFromMemoryCacheOrNetwork(); +// Data b = GetDataFromMemoryCacheOrNetwork(); +// CPUIntensiveProcessing(a); // CPU usage within a ScopedBlockingCall. +// CPUIntensiveProcessing(b); // CPU usage within a ScopedBlockingCall. +// +// Good: +// base::WaitableEvent waitable_event(...); +// waitable_event.Wait(); +// +// Bad: +// base::WaitableEvent waitable_event(...); +// ScopedBlockingCall scoped_blocking_call(BlockingType::WILL_BLOCK); +// waitable_event.Wait(); // Wait() instantiates its own ScopedBlockingCall. +// +// When a ScopedBlockingCall is instantiated from a TaskScheduler parallel or +// sequenced task, the thread pool size is incremented to compensate for the +// blocked thread (more or less aggressively depending on BlockingType). class BASE_EXPORT ScopedBlockingCall { public: ScopedBlockingCall(BlockingType blocking_type);
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn index 142982a..f8eb453 100644 --- a/build/toolchain/win/BUILD.gn +++ b/build/toolchain/win/BUILD.gn
@@ -94,15 +94,7 @@ toolchain_uses_clang = is_clang } - if (toolchain_uses_clang && host_os != "win") { - # This toolchain definition uses response files for compilations. GN uses - # the quoting rules of the host OS, while clang-cl always defaults to - # cmd.exe quoting rules for parsing response files. Tell clang-cl to use - # POSIX quoting rules, so it can understand what GN generates. - cl = "${invoker.cl} --rsp-quoting=posix" - } else { - cl = invoker.cl - } + cl = invoker.cl if (toolchain_uses_clang && use_clang_static_analyzer) { analyzer_prefix =
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index ddfcd50..f830cb59 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn
@@ -1492,9 +1492,9 @@ "//chrome/child", "//chrome/common", "//chrome/gpu", - "//chrome/profiling", "//chrome/renderer", "//chrome/utility", + "//components/services/heap_profiling", "//components/sync", "//content/public/child", "//pdf", @@ -1820,10 +1820,10 @@ "//chrome/child", "//chrome/common", "//chrome/gpu", - "//chrome/profiling", "//chrome/renderer", "//chrome/utility", "//components/safe_browsing/android:safe_browsing_mobile", + "//components/services/heap_profiling", "//content/public/app:both", "//content/public/common:service_names", "//services/service_manager/embedder",
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 9480185..4924aa2 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -645,10 +645,12 @@ "javatests/src/org/chromium/chrome/browser/vr_shell/nfc_apk/SimNfcActivity.java", "javatests/src/org/chromium/chrome/browser/vr_shell/rules/ChromeTabbedActivityVrTestRule.java", "javatests/src/org/chromium/chrome/browser/vr_shell/rules/CustomTabActivityVrTestRule.java", + "javatests/src/org/chromium/chrome/browser/vr_shell/rules/HeadTrackingMode.java", "javatests/src/org/chromium/chrome/browser/vr_shell/rules/VrActivityRestriction.java", "javatests/src/org/chromium/chrome/browser/vr_shell/rules/VrActivityRestrictionRule.java", "javatests/src/org/chromium/chrome/browser/vr_shell/rules/VrTestRule.java", "javatests/src/org/chromium/chrome/browser/vr_shell/rules/WebappActivityVrTestRule.java", + "javatests/src/org/chromium/chrome/browser/vr_shell/util/HeadTrackingUtils.java", "javatests/src/org/chromium/chrome/browser/vr_shell/util/NfcSimUtils.java", "javatests/src/org/chromium/chrome/browser/vr_shell/util/TransitionUtils.java", "javatests/src/org/chromium/chrome/browser/vr_shell/util/VrInfoBarUtils.java",
diff --git a/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml b/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml index d020b19..b775b23a 100644 --- a/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml +++ b/chrome/android/java/res/drawable/ic_check_googblue_24dp_animated.xml
@@ -3,9 +3,10 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> -<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" - xmlns:tools="http://schemas.android.com/tools" +<animated-vector + xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt" + xmlns:tools="http://schemas.android.com/tools" tools:targetApi="21"> <aapt:attr name="android:drawable"> @@ -19,27 +20,19 @@ <path android:name="ic_check" android:pathData="M4.12,12.705 l4.88,4.88 l11.295,-11.29" - android:strokeColor="#4285F4" - android:strokeWidth="2" /> + android:strokeWidth="2" + android:strokeColor="#4285F4"/> </vector> </aapt:attr> - <target android:name="ic_check" > + <target android:name="ic_check"> <aapt:attr name="android:animation"> - <set> - <objectAnimator - android:duration="200" - android:propertyName="pathData" - android:valueFrom="M4.12,12.705 l0,0 l0,0" - android:valueTo="M4.12,12.705 l4.88,4.88 l0,0" - android:valueType="pathType"/> - <objectAnimator - android:duration="200" - android:propertyName="pathData" - android:valueFrom="M4.12,12.705 l4.88,4.88 l0,0" - android:valueTo="M4.12,12.705 l4.88,4.88 l11.295,-11.29" - android:valueType="pathType"/> - </set> + <objectAnimator + android:duration="400" + android:propertyName="trimPathEnd" + android:valueFrom="0" + android:valueTo="1" + tools:valueFrom="1"/> </aapt:attr> </target> </animated-vector> \ No newline at end of file
diff --git a/chrome/android/java/res/layout/bottom_toolbar.xml b/chrome/android/java/res/layout/bottom_toolbar.xml new file mode 100644 index 0000000..4e2fd4e --- /dev/null +++ b/chrome/android/java/res/layout/bottom_toolbar.xml
@@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2018 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> + +<org.chromium.chrome.browser.toolbar.ScrollingBottomViewResourceFrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/bottom_toolbar_control_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:minHeight="@dimen/control_container_height" > + + <ImageView + android:id="@+id/bottom_toolbar_top_shadow" + android:layout_width="match_parent" + android:layout_height="@dimen/toolbar_shadow_height" + android:src="@drawable/modern_toolbar_shadow" + android:scaleType="fitXY" + android:scaleY="-1" + android:contentDescription="@null" /> + + <org.chromium.chrome.browser.widget.bottomsheet.TouchRestrictingFrameLayout + android:id="@+id/bottom_toolbar_container" + android:layout_width="match_parent" + android:layout_height="@dimen/control_container_height" + android:layout_marginTop="@dimen/toolbar_shadow_height" > + + <View + android:id="@+id/bottom_sheet_toolbar" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/modern_primary_color" > + </View> + + </org.chromium.chrome.browser.widget.bottomsheet.TouchRestrictingFrameLayout> + +</org.chromium.chrome.browser.toolbar.ScrollingBottomViewResourceFrameLayout>
diff --git a/chrome/android/java/res/layout/main.xml b/chrome/android/java/res/layout/main.xml index 5417220b..c30bacc2 100644 --- a/chrome/android/java/res/layout/main.xml +++ b/chrome/android/java/res/layout/main.xml
@@ -86,6 +86,14 @@ android:visibility="gone" /> <ViewStub + android:id="@+id/bottom_toolbar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="start|bottom" + android:inflatedId="@+id/bottom_toolbar" + android:layout="@layout/bottom_toolbar" /> + + <ViewStub android:id="@+id/control_container_stub" android:layout_width="match_parent" android:layout_height="wrap_content" />
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 4aaf9bb..6fa99d6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -127,6 +127,7 @@ import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; import org.chromium.chrome.browser.tabmodel.TabModelUtils; import org.chromium.chrome.browser.tabmodel.TabWindowManager; +import org.chromium.chrome.browser.toolbar.BottomToolbarController; import org.chromium.chrome.browser.toolbar.Toolbar; import org.chromium.chrome.browser.toolbar.ToolbarControlContainer; import org.chromium.chrome.browser.toolbar.ToolbarManager; @@ -258,6 +259,7 @@ private ToolbarManager mToolbarManager; private FindToolbarManager mFindToolbarManager; private BottomSheetController mBottomSheetController; + private BottomToolbarController mBottomToolbarController; private BottomSheet mBottomSheet; private ContextualSuggestionsCoordinator mContextualSuggestionsCoordinator; private FadingBackgroundView mFadingBackgroundView; @@ -1146,6 +1148,11 @@ mBottomSheet = null; } + if (mBottomToolbarController != null) { + mBottomToolbarController.destroy(); + mBottomToolbarController = null; + } + if (mContextualSuggestionsCoordinator != null) { mContextualSuggestionsCoordinator.destroy(); mContextualSuggestionsCoordinator = null; @@ -1263,6 +1270,13 @@ VrShellDelegate.onNativeLibraryAvailable(); super.finishNativeInitialization(); + if (FeatureUtilities.isChromeDuplexEnabled()) { + ViewGroup coordinator = findViewById(R.id.coordinator); + mBottomToolbarController = new BottomToolbarController(mFullscreenManager, + mCompositorViewHolder.getResourceManager(), + mCompositorViewHolder.getLayoutManager(), coordinator); + } + if (FeatureUtilities.isContextualSuggestionsBottomSheetEnabled(isTablet())) { ViewGroup coordinator = (ViewGroup) findViewById(R.id.coordinator); getLayoutInflater().inflate(R.layout.bottom_sheet, coordinator);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java index e9b7402f..3dc8ba8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
@@ -142,6 +142,16 @@ } /** + * Adds a {@link SceneOverlay} that can be shown in this layout to the first position in the + * scene overlay list, meaning it will be drawn behind all other overlays. + * @param overlay The {@link SceneOverlay} to be added. + */ + void addSceneOverlayToBack(SceneOverlay overlay) { + assert !mSceneOverlays.contains(overlay); + mSceneOverlays.add(0, overlay); + } + + /** * Adds a {@link SceneOverlay} that can potentially be shown on top of this {@link Layout}. The * {@link SceneOverlay}s added to this {@link Layout} will be cascaded in the order they are * added. The {@link SceneOverlay} added first will become the content of the
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java index a4bb1d7..733e144 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManager.java
@@ -903,6 +903,15 @@ } /** + * Add a {@link SceneOverlay} to the back of the list. This means the overlay will be drawn + * first and therefore behind all other overlays currently in the list. + * @param overlay The overlay to be added to the back of the list. + */ + public void addSceneOverlayToBack(SceneOverlay overlay) { + mStaticLayout.addSceneOverlayToBack(overlay); + } + + /** * Clears all content associated with {@code tabId} from the internal caches. * @param tabId The id of the tab to clear. */
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ScrollingBottomViewSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ScrollingBottomViewSceneLayer.java index 070cb70..9684ac5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ScrollingBottomViewSceneLayer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ScrollingBottomViewSceneLayer.java
@@ -35,6 +35,9 @@ /** The current offset of the bottom view in px. */ private int mCurrentOffsetPx; + /** The {@link ViewResourceFrameLayout} that this scene layer represents. */ + private ViewResourceFrameLayout mBottomView; + /** * Build a composited bottom view layer. * @param resourceManager A resource manager for dynamic resource creation. @@ -43,10 +46,11 @@ */ public ScrollingBottomViewSceneLayer(ResourceManager resourceManager, ViewResourceFrameLayout bottomView, int topShadowHeightPx) { - mResourceId = bottomView.getId(); + mBottomView = bottomView; + mResourceId = mBottomView.getId(); mTopShadowHeightPx = topShadowHeightPx; resourceManager.getDynamicResourceLoader().registerResource( - mResourceId, bottomView.getResourceAdapter()); + mResourceId, mBottomView.getResourceAdapter()); } /** @@ -82,7 +86,8 @@ @Override public boolean isSceneOverlayTreeShowing() { - return true; + // If the offset is greater than the toolbar's height, don't draw the layer. + return mCurrentOffsetPx < mBottomView.getHeight() - mTopShadowHeightPx; } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java b/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java index ea2de9e2..8bfbe7c6 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/locale/LocaleManager.java
@@ -31,6 +31,9 @@ import org.chromium.chrome.browser.snackbar.Snackbar; import org.chromium.chrome.browser.snackbar.SnackbarManager; import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarController; +import org.chromium.chrome.browser.vr_shell.OnExitVrRequestListener; +import org.chromium.chrome.browser.vr_shell.VrIntentUtils; +import org.chromium.chrome.browser.vr_shell.VrShellDelegate; import org.chromium.chrome.browser.widget.PromoDialog; import org.chromium.ui.base.PageTransition; @@ -304,10 +307,31 @@ return; } - showPromoDialog(dialogCreator); + if (VrIntentUtils.isVrIntent(activity.getIntent()) || VrShellDelegate.isInVr()) { + showPromoDialogForVr(dialogCreator, activity); + } else { + showPromoDialog(dialogCreator); + } mSearchEnginePromoShownThisSession = true; } + private void showPromoDialogForVr(Callable<PromoDialog> dialogCreator, Activity activity) { + VrShellDelegate.requestToExitVrForSearchEnginePromoDialog(new OnExitVrRequestListener() { + @Override + public void onSucceeded() { + showPromoDialog(dialogCreator); + } + + @Override + public void onDenied() { + // We need to make sure that the dialog shows up even if user denied to + // leave VR. + VrShellDelegate.forceExitVrImmediately(); + showPromoDialog(dialogCreator); + } + }, activity); + } + private void showPromoDialog(Callable<PromoDialog> dialogCreator) { try { dialogCreator.call().show();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modelutil/PropertyModelChangeProcessor.java b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/PropertyModelChangeProcessor.java new file mode 100644 index 0000000..db63de0 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/modelutil/PropertyModelChangeProcessor.java
@@ -0,0 +1,48 @@ +// Copyright 2018 The Chromium 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.modelutil; + +import org.chromium.chrome.browser.modelutil.PropertyObservable.PropertyObserver; + +/** + * A model change processor for use with a {@link PropertyObservable} model. The + * {@link PropertyModelChangeProcessor} should be registered as a property observer of the model. + * Internally uses a view binder to bind model properties to the toolbar view. + * @param <M> The {@link PropertyObservable} model. + * @param <V> The view object that is changing. + * @param <P> The property of the view that changed. + */ +public class PropertyModelChangeProcessor<M extends PropertyObservable<P>, V, P> + implements PropertyObserver<P> { + /** + * A generic view binder that associates a view with a model. + * @param <M> The {@link PropertyObservable} model. + * @param <V> The view object that is changing. + * @param <P> The property of the view that changed. + */ + public interface ViewBinder<M, V, P> { void bind(M model, V view, P propertyKey); } + + private final V mView; + private final M mModel; + private final ViewBinder<M, V, P> mViewBinder; + + /** + * Construct a new PropertyModelChangeProcessor. + * @param model The model containing the data to be bound. + * @param view The view to which data will be bound. + * @param viewBinder A class that binds the model to the view. + */ + public PropertyModelChangeProcessor(M model, V view, ViewBinder<M, V, P> viewBinder) { + mModel = model; + mView = view; + mViewBinder = viewBinder; + } + + @Override + public void onPropertyChanged(PropertyObservable<P> source, P propertyKey) { + // TODO(bauerb): Add support for batching and for full model updates. + mViewBinder.bind(mModel, mView, propertyKey); + } +} \ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java index 31c31f1..45a08d0e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
@@ -102,6 +102,7 @@ @Nullable private URI mCanDedupedApplicationId; private boolean mIsReadyToPayQueried; + private boolean mIsServiceConnected; /** * Builds the point of interaction with a locally installed 3rd party native Android payment @@ -160,6 +161,7 @@ mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { + mIsServiceConnected = true; IsReadyToPayService isReadyToPayService = IsReadyToPayService.Stub.asInterface(service); if (isReadyToPayService == null) { @@ -170,7 +172,9 @@ } @Override - public void onServiceDisconnected(ComponentName name) {} + public void onServiceDisconnected(ComponentName name) { + mIsServiceConnected = false; + } }; mIsReadyToPayIntent.putExtras(buildExtras(null /* id */, null /* merchantName */, @@ -194,7 +198,10 @@ private void respondToGetInstrumentsQuery(final PaymentInstrument instrument) { if (mServiceConnection != null) { - ContextUtils.getApplicationContext().unbindService(mServiceConnection); + if (mIsServiceConnected) { + ContextUtils.getApplicationContext().unbindService(mServiceConnection); + mIsServiceConnected = false; + } mServiceConnection = null; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarController.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarController.java new file mode 100644 index 0000000..37713c2 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarController.java
@@ -0,0 +1,69 @@ +// Copyright 2018 The Chromium 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.toolbar; + +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewStub; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.compositor.layouts.LayoutManager; +import org.chromium.chrome.browser.compositor.scene_layer.ScrollingBottomViewSceneLayer; +import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; +import org.chromium.chrome.browser.toolbar.BottomToolbarModel.PropertyKey; +import org.chromium.chrome.browser.toolbar.BottomToolbarViewBinder.ViewHolder; +import org.chromium.ui.resources.ResourceManager; + +/** + * The controller for the bottom toolbar. This class handles all interactions that the bottom + * toolbar has with the outside world. This class has two primary components, an Android view that + * handles user actions and a composited texture that draws when the controls are being scrolled + * off-screen. The Android version does not draw unless the controls offset is 0. + */ +public class BottomToolbarController { + /** The mediator that handles events from outside the bottom toolbar. */ + private BottomToolbarMediator mMediator; + + /** + * Build the controller that manages the bottom toolbar. + * @param fullscreenManager A {@link ChromeFullscreenManager} to update the bottom controls + * height for the renderer. + * @param resourceManager A {@link ResourceManager} for loading textures into the compositor. + * @param layoutManager A {@link LayoutManager} to attach overlays to. + * @param root The root {@link ViewGroup} for locating the vies to inflate. + */ + public BottomToolbarController(ChromeFullscreenManager fullscreenManager, + ResourceManager resourceManager, LayoutManager layoutManager, ViewGroup root) { + BottomToolbarModel model = new BottomToolbarModel(); + mMediator = new BottomToolbarMediator(model, fullscreenManager, root.getResources()); + + int shadowHeight = + root.getResources().getDimensionPixelOffset(R.dimen.toolbar_shadow_height); + + // This is the Android view component of the views that constitute the bottom toolbar. + View inflatedView = ((ViewStub) root.findViewById(R.id.bottom_toolbar)).inflate(); + final ScrollingBottomViewResourceFrameLayout toolbarRoot = + (ScrollingBottomViewResourceFrameLayout) inflatedView; + toolbarRoot.setTopShadowHeight(shadowHeight); + + // This is the compositor component of the bottom toolbar views. + final ScrollingBottomViewSceneLayer sceneLayer = + new ScrollingBottomViewSceneLayer(resourceManager, toolbarRoot, shadowHeight); + layoutManager.addSceneOverlayToBack(sceneLayer); + + PropertyModelChangeProcessor<BottomToolbarModel, ViewHolder, PropertyKey> processor = + new PropertyModelChangeProcessor<>(model, new ViewHolder(sceneLayer, toolbarRoot), + new BottomToolbarViewBinder()); + model.addObserver(processor); + } + + /** + * Clean up any state when the bottom toolbar is destroyed. + */ + public void destroy() { + mMediator.destroy(); + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarMediator.java new file mode 100644 index 0000000..64648a55 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarMediator.java
@@ -0,0 +1,70 @@ +// Copyright 2018 The Chromium 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.toolbar; + +import android.content.res.Resources; +import android.view.View; + +import org.chromium.chrome.R; +import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager; +import org.chromium.chrome.browser.fullscreen.ChromeFullscreenManager.FullscreenListener; + +/** + * This class is responsible for reacting to events from the outside world, interacting with other + * coordinators, running most of the business logic associated with the bottom toolbar, and updating + * the model accordingly. + */ +class BottomToolbarMediator implements FullscreenListener { + /** The model for the bottom toolbar that holds all of its state. */ + private BottomToolbarModel mModel; + + /** The fullscreen manager to observe browser controls events. */ + private ChromeFullscreenManager mFullscreenManager; + + /** + * Build a new mediator that handles events from outside the bottom toolbar. + * @param model The {@link BottomToolbarModel} that holds all the state for the bottom toolbar. + * @param fullscreenManager A {@link ChromeFullscreenManager} for events related to the browser + * controls. + * @param resources Android {@link Resources} to pull dimensions from. + */ + public BottomToolbarMediator(BottomToolbarModel model, + ChromeFullscreenManager fullscreenManager, Resources resources) { + mModel = model; + mFullscreenManager = fullscreenManager; + mFullscreenManager.addListener(this); + + // Notify the fullscreen manager that the bottom controls now have a height. + fullscreenManager.setBottomControlsHeight( + resources.getDimensionPixelOffset(R.dimen.control_container_height)); + fullscreenManager.updateViewportSize(); + } + + /** + * Clean up anything that needs to be when the bottom toolbar is destroyed. + */ + public void destroy() { + mFullscreenManager.removeListener(this); + } + + @Override + public void onContentOffsetChanged(float offset) {} + + @Override + public void onControlsOffsetChanged(float topOffset, float bottomOffset, boolean needsAnimate) { + mModel.setYOffset((int) bottomOffset); + if (bottomOffset > 0) { + mModel.setAndroidViewVisibility(View.INVISIBLE); + } else { + mModel.setAndroidViewVisibility(View.VISIBLE); + } + } + + @Override + public void onToggleOverlayVideoMode(boolean enabled) {} + + @Override + public void onBottomControlsHeightChanged(int bottomControlsHeight) {} +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarModel.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarModel.java new file mode 100644 index 0000000..6d4fe75 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarModel.java
@@ -0,0 +1,59 @@ +// Copyright 2018 The Chromium 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.toolbar; + +import org.chromium.chrome.browser.modelutil.PropertyObservable; + +/** + * All of the state for the bottom toolbar, updated by the {@link BottomToolbarController}. + */ +public class BottomToolbarModel extends PropertyObservable<BottomToolbarModel.PropertyKey> { + /** The different properties that can change on the bottom toolbar. */ + public static class PropertyKey { + public static final PropertyKey Y_OFFSET = new PropertyKey(); + public static final PropertyKey ANDROID_VIEW_VISIBILITY = new PropertyKey(); + + private PropertyKey() {} + } + + /** The Y offset of the view in px. */ + private int mYOffsetPx; + + /** The visibility of the Android view version of the toolbar. */ + private int mAndroidViewVisibility; + + /** Default constructor. */ + public BottomToolbarModel() {} + + /** + * @param offsetPx The current Y offset in px. + */ + public void setYOffset(int offsetPx) { + mYOffsetPx = offsetPx; + notifyPropertyChanged(PropertyKey.Y_OFFSET); + } + + /** + * @return The current Y offset in px. + */ + public int getYOffset() { + return mYOffsetPx; + } + + /** + * @param visibility The visibility of the Android view version of the toolbar. + */ + public void setAndroidViewVisibility(int visibility) { + mAndroidViewVisibility = visibility; + notifyPropertyChanged(PropertyKey.ANDROID_VIEW_VISIBILITY); + } + + /** + * @return The visibility of the Android view version of the toolbar. + */ + public int getAndroidViewVisibility() { + return mAndroidViewVisibility; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarViewBinder.java new file mode 100644 index 0000000..3005f00 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarViewBinder.java
@@ -0,0 +1,59 @@ +// Copyright 2018 The Chromium 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.toolbar; + +import android.view.ViewGroup; + +import org.chromium.chrome.browser.compositor.scene_layer.ScrollingBottomViewSceneLayer; +import org.chromium.chrome.browser.modelutil.PropertyModelChangeProcessor; +import org.chromium.chrome.browser.toolbar.BottomToolbarModel.PropertyKey; + +/** + * This class is responsible for pushing updates to both the Android view and the compositor + * component of the bottom toolbar. These updates are pulled from the {@link BottomToolbarModel} + * when a notification of an update is received. + */ +public class BottomToolbarViewBinder + implements PropertyModelChangeProcessor.ViewBinder<BottomToolbarModel, + BottomToolbarViewBinder.ViewHolder, BottomToolbarModel.PropertyKey> { + /** + * A wrapper class that holds a {@link ViewGroup} (the toolbar view) and a composited layer to + * be used with the {@link BottomToolbarViewBinder}. + */ + public static class ViewHolder { + /** A handle to the composited bottom toolbar layer. */ + public final ScrollingBottomViewSceneLayer sceneLayer; + + /** A handle to the Android {@link ViewGroup} version of the toolbar. */ + public final ViewGroup toolbarRoot; + + /** + * @param compositedSceneLayer The composited bottom toolbar view. + * @param toolbarRootView The Android {@link ViewGroup} toolbar. + */ + public ViewHolder( + ScrollingBottomViewSceneLayer compositedSceneLayer, ViewGroup toolbarRootView) { + sceneLayer = compositedSceneLayer; + toolbarRoot = toolbarRootView; + } + } + + /** + * Build a binder that handles interaction between the model and the views that make up the + * bottom toolbar. + */ + public BottomToolbarViewBinder() {} + + @Override + public final void bind(BottomToolbarModel model, ViewHolder view, PropertyKey propertyKey) { + if (PropertyKey.Y_OFFSET == propertyKey) { + view.sceneLayer.setYOffset(model.getYOffset()); + } else if (PropertyKey.ANDROID_VIEW_VISIBILITY == propertyKey) { + view.toolbarRoot.setVisibility(model.getAndroidViewVisibility()); + } else { + assert false : "Unhandled property detected in BottomToolbarViewBinder!"; + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ScrollingBottomViewResourceFrameLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ScrollingBottomViewResourceFrameLayout.java new file mode 100644 index 0000000..3eef70e0 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ScrollingBottomViewResourceFrameLayout.java
@@ -0,0 +1,61 @@ +// Copyright 2018 The Chromium 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.toolbar; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.util.AttributeSet; + +import org.chromium.chrome.browser.widget.ViewResourceFrameLayout; +import org.chromium.ui.resources.dynamics.ViewResourceAdapter; + +/** + * A {@link ViewResourceFrameLayout} that specifically handles redraw of the top shadow of the view + * it represents. + */ +public class ScrollingBottomViewResourceFrameLayout extends ViewResourceFrameLayout { + /** A cached rect to avoid extra allocations. */ + private final Rect mCachedRect = new Rect(); + + /** The height of the shadow sitting above the bottom view in px. */ + private int mTopShadowHeightPx; + + public ScrollingBottomViewResourceFrameLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected ViewResourceAdapter createResourceAdapter() { + return new ViewResourceAdapter(this) { + @Override + public void onCaptureStart(Canvas canvas, Rect dirtyRect) { + mCachedRect.set(dirtyRect); + if (mCachedRect.intersect(0, 0, getWidth(), mTopShadowHeightPx)) { + canvas.save(); + + // Clip the canvas to only the section of the dirty rect that contains the top + // shadow of the view. + canvas.clipRect(mCachedRect); + + // Clear the shadow so redrawing does not make it progressively darker. + canvas.drawColor(0, PorterDuff.Mode.CLEAR); + + canvas.restore(); + } + + super.onCaptureStart(canvas, dirtyRect); + } + }; + } + + /** + * @param height The height of the view's top shadow in px. + */ + public void setTopShadowHeight(int height) { + mTopShadowHeightPx = height; + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrInputConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrInputConnection.java index a8c14e65..a84bac1f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrInputConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrInputConnection.java
@@ -43,7 +43,7 @@ public void requestTextState() { if (DEBUG_LOGS) Log.i(TAG, "requestTextState"); InputConnection ic = mImeAdapter.getActiveInputConnection(); - assert ic != null; + if (ic == null) return; if (mImeThreadResponseHandler == null) { mImeThreadResponseHandler = new Handler(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java index 166550f..784b11dd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShell.java
@@ -6,8 +6,6 @@ import android.widget.FrameLayout; -import org.chromium.chrome.browser.tab.Tab; - /** * Abstracts away the VrShell class, which may or may not be present at runtime depending on * compile flags. @@ -16,8 +14,7 @@ /** * Performs native VrShell initialization. */ - void initializeNative( - Tab currentTab, boolean forWebVr, boolean webVrAutopresentationExpected, boolean inCct); + void initializeNative(boolean forWebVr, boolean webVrAutopresentationExpected, boolean inCct); /** * Pauses VrShell. @@ -67,7 +64,7 @@ /** * Requests to exit VR. */ - void requestToExitVr(@UiUnsupportedMode int reason); + void requestToExitVr(@UiUnsupportedMode int reason, boolean showExitPromptBeforeDoff); /** * Triggers VrShell to navigate forward.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java index bbf4e260..b2f3f84 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -184,6 +184,7 @@ // Listener to be called once we exited VR due to to an unsupported mode, e.g. the user clicked // the URL bar security icon. private OnExitVrRequestListener mOnExitVrRequestListener; + private Runnable mPendingExitVrRequest; private boolean mExitedDueToUnsupportedMode; private boolean mExitingCct; private boolean mPaused; @@ -365,6 +366,11 @@ sVrModeObservers.remove(observer); } + public static void forceExitVrImmediately() { + if (sInstance == null) return; + sInstance.shutdownVr(true, true); + } + /** * See {@link Activity#onActivityResult}. */ @@ -521,6 +527,35 @@ } } + public static void requestToExitVrForSearchEnginePromoDialog( + OnExitVrRequestListener listener, Activity activity) { + // When call site requests to exit VR, depend on the timing, Chrome may not in VR yet + // (Chrome only enter VR after onNewIntentWithNative is called in the cold start case). + // While not in VR, calling requestToExitVr would immediately notify listener that exit VR + // succeed (without showing DOFF screen). If call site decide to show 2D UI when exit VR + // succeeded, it leads to case that 2D UI is showing on top of VR when Chrome eventually + // enters VR. To prevent this from happening, we set mPendingExitVrRequest which should be + // executed at runPendingExitVrTask. runPendingExitVrTask is called after it is safe to + // request exit VR. + if (isInVr()) { + sInstance.requestToExitVrInternal( + listener, UiUnsupportedMode.SEARCH_ENGINE_PROMO, false); + } else { + // Making sure that we response to this request as it is very important that search + // engine promo dialog isn't ignored due to VR. + assert VrIntentUtils.isVrIntent(activity.getIntent()); + VrShellDelegate instance = getInstance(); + if (instance == null) { + listener.onDenied(); + return; + } + sInstance.mPendingExitVrRequest = () -> { + sInstance.requestToExitVrInternal( + listener, UiUnsupportedMode.SEARCH_ENGINE_PROMO, false); + }; + } + } + public static void requestToExitVr(OnExitVrRequestListener listener) { requestToExitVr(listener, UiUnsupportedMode.GENERIC_UNSUPPORTED_FEATURE); } @@ -544,7 +579,7 @@ listener.onSucceeded(); return; } - sInstance.requestToExitVrInternal(listener, reason); + sInstance.requestToExitVrInternal(listener, reason, true); } /** @@ -617,10 +652,13 @@ public static void maybeHandleVrIntentPreNative(ChromeActivity activity, Intent intent) { if (!VrIntentUtils.isVrIntent(intent)) return; - if (sInstance != null) sInstance.swapHostActivity(activity); + if (sInstance != null && !sInstance.mInternalIntentUsedToStartVr) { + sInstance.swapHostActivity(activity, false /* disableVrMode */); + // If the user has launched Chrome from the launcher, rather than resuming from the + // dashboard, we don't want to launch into presentation. + sInstance.exitWebVRAndClearState(); + } - // If we're already in VR, nothing to do here. - if (sInstance != null && sInstance.mInVr) return; if (DEBUG_LOGS) Log.i(TAG, "maybeHandleVrIntentPreNative: preparing for transition"); // We add a black overlay view so that we can show black while the VR UI is loading. @@ -1016,16 +1054,9 @@ if (activity == mActivity) onStart(); break; case ActivityState.RESUMED: - if (mInVr && activity != mActivity) { - if (mShowingDaydreamDoff) { - onExitVrResult(true); - } else { - shutdownVr(true /* disableVrMode */, false /* stayingInChrome */); - } - } if (!activitySupportsPresentation(activity)) return; if (!(activity instanceof ChromeActivity)) return; - swapHostActivity((ChromeActivity) activity); + swapHostActivity((ChromeActivity) activity, true /* disableVrMode */); onResume(); break; default: @@ -1035,9 +1066,10 @@ // Called when an activity that supports VR is resumed, and attaches VrShellDelegate to that // activity. - private void swapHostActivity(ChromeActivity activity) { + private void swapHostActivity(ChromeActivity activity, boolean disableVrMode) { assert mActivity != null; if (mActivity == activity) return; + if (mInVr) shutdownVr(disableVrMode, false /* stayingInChrome */); mActivity = activity; mListeningForWebVrActivateBeforePause = false; if (mVrDaydreamApi != null) mVrDaydreamApi.close(); @@ -1196,8 +1228,8 @@ addVrViews(); boolean webVrMode = mRequestedWebVr || tentativeWebVrMode || mAutopresentWebVr; - mVrShell.initializeNative(mActivity.getActivityTab(), webVrMode, mAutopresentWebVr, - mActivity instanceof CustomTabActivity); + mVrShell.initializeNative( + webVrMode, mAutopresentWebVr, mActivity instanceof CustomTabActivity); mVrShell.setWebVrModeEnabled(webVrMode); // We're entering VR, but not in WebVr mode. @@ -1237,19 +1269,19 @@ } private void onVrIntent() { - if (mInVr) return; - if (USE_HIDE_ANIMATION) mNeedsAnimationCancel = true; - mEnterVrOnStartup = true; + mInVrAtChromeLaunch = true; + + assert !mInternalIntentUsedToStartVr; + nativeRecordVrStartAction(mNativeVrShellDelegate, VrStartAction.INTENT_LAUNCH); + + if (mInVr) return; // TODO(mthiesse): Assuming we've gone through DON flow saves ~2 seconds on VR entry. See // the comments in enterVr(). This may not always be the case in the future, but for now // it's a reasonable assumption. mDonSucceeded = true; - mInVrAtChromeLaunch = true; - - nativeRecordVrStartAction(mNativeVrShellDelegate, VrStartAction.INTENT_LAUNCH); - + mEnterVrOnStartup = true; if (!mPaused) enterVrAfterDon(); } @@ -1353,6 +1385,20 @@ } } } + // If canceling entry animation started, the activity is paused first and then expect a + // onResume is called next. We don't want to disrupt this process by calling + // runPendingExitVrTask which will show DOFF sceeen. DOFF might trigger onStop before + // onResume which will crash Chrome. So if we know that we are canceling animation, we don't + // call runPendingExitVrTask. + if (!mCancellingEntryAnimation) { + runPendingExitVrTask(); + } + } + + private void runPendingExitVrTask() { + if (mPendingExitVrRequest == null) return; + mPendingExitVrRequest.run(); + mPendingExitVrRequest = null; } @Override @@ -1493,8 +1539,8 @@ return ENTER_VR_REQUESTED; } - private void requestToExitVrInternal( - OnExitVrRequestListener listener, @UiUnsupportedMode int reason) { + private void requestToExitVrInternal(OnExitVrRequestListener listener, + @UiUnsupportedMode int reason, boolean showExitPromptBeforeDoff) { assert listener != null; // If we are currently processing another request, deny the request. if (mOnExitVrRequestListener != null) { @@ -1502,8 +1548,15 @@ return; } mOnExitVrRequestListener = listener; - mShowingExitVrPrompt = true; - mVrShell.requestToExitVr(reason); + mShowingExitVrPrompt = showExitPromptBeforeDoff; + mVrShell.requestToExitVr(reason, showExitPromptBeforeDoff); + } + + private void exitWebVRAndClearState() { + exitWebVRPresent(); + mAutopresentWebVr = false; + mRequestedWebVr = false; + mListeningForWebVrActivateBeforePause = false; } @CalledByNative @@ -1602,12 +1655,15 @@ }); } - mCancellingEntryAnimation = false; + if (mCancellingEntryAnimation) { + // If we know this onResume is called after cancel animation finished, it is safe to + // request exit VR and show DOFF. + runPendingExitVrTask(); + mCancellingEntryAnimation = false; + } if (mEnterVrOnStartup) { // This means that Chrome was started with a VR intent, so we should enter VR. - // TODO(crbug.com/776235): The launcher should ensure that the DON flow has been run - // prior to starting Chrome. assert !mProbablyInDon; if (DEBUG_LOGS) Log.i(TAG, "onResume: entering VR mode for VR intent"); enterVrAfterDon(); @@ -1662,10 +1718,6 @@ // are safe. if (mInVr) mVrShell.pause(); if (mShowingDaydreamDoff || mProbablyInDon) return; - - // TODO(mthiesse): When the user resumes Chrome in a 2D context, we don't want to tear down - // VR UI, so for now, exit VR. - shutdownVr(true /* disableVrMode */, false /* stayingInChrome */); } protected void onPause() { @@ -1676,10 +1728,6 @@ unregisterDaydreamIntent(mVrDaydreamApi); if (mVrSupportLevel == VrSupportLevel.VR_NOT_AVAILABLE) return; - // TODO(ymalik): We should be able to remove this if we handle it for multi-window in - // {@link onMultiWindowModeChanged} since we're calling it in onStop. - if (!mInVr && !mProbablyInDon) cancelPendingVrEntry(); - // When the active web page has a vrdisplayactivate event handler, // mListeningForWebVrActivate should be set to true, which means a vrdisplayactive event // should be fired once DON flow finished. However, DON flow will pause our activity, @@ -1699,12 +1747,12 @@ if (maybeCloseVrCct()) return; mStopped = false; if (mDonSucceeded) setWindowModeForVr(); + if (mInVr && !mVrDaydreamApi.isInVrSession()) shutdownVr(true, false); } private void onStop() { if (DEBUG_LOGS) Log.i(TAG, "onStop"); mStopped = true; - if (!mProbablyInDon) cancelPendingVrEntry(); assert !mCancellingEntryAnimation; } @@ -1890,10 +1938,10 @@ */ /* package */ Runnable getVrCloseButtonListener() { if (mCloseButtonListener != null) return mCloseButtonListener; - final boolean startedForAutopresentation = mAutopresentWebVr; mCloseButtonListener = new Runnable() { @Override public void run() { + boolean startedForAutopresentation = mAutopresentWebVr; // Avoid launching DD home when we shutdown VR. mAutopresentWebVr = false;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java index 75b9626b..7790f40 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -313,8 +313,8 @@ @Override @TargetApi(Build.VERSION_CODES.N) - public void initializeNative(Tab currentTab, boolean forWebVr, - boolean webVrAutopresentationExpected, boolean inCct) { + public void initializeNative( + boolean forWebVr, boolean webVrAutopresentationExpected, boolean inCct) { Tab tab = mActivity.getActivityTab(); if (mActivity.isInOverviewMode() || tab == null) { launchNTP(); @@ -356,7 +356,7 @@ getGvrApi().getNativeGvrContext(), mReprojectedRendering, displayWidthMeters, displayHeightMeters, dm.widthPixels, dm.heightPixels, pauseContent); - swapToTab(currentTab); + swapToTab(tab); createTabList(); mActivity.getTabModelSelector().addObserver(mTabModelSelectorObserver); createTabModelSelectorTabObserver(); @@ -908,8 +908,14 @@ } @Override - public void requestToExitVr(@UiUnsupportedMode int reason) { - if (mNativeVrShell != 0) nativeRequestToExitVr(mNativeVrShell, reason); + public void requestToExitVr(@UiUnsupportedMode int reason, boolean showExitPromptBeforeDoff) { + if (mNativeVrShell == 0) return; + if (showExitPromptBeforeDoff) { + nativeRequestToExitVr(mNativeVrShell, reason); + } else { + nativeLogUnsupportedModeUserMetric(mNativeVrShell, reason); + mDelegate.onExitVrRequestResult(true); + } } @CalledByNative
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index a9e76b2..f36aa9d 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -673,6 +673,7 @@ "java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java", "java/src/org/chromium/chrome/browser/modaldialog/TabModalPresenter.java", "java/src/org/chromium/chrome/browser/modelutil/ListObservable.java", + "java/src/org/chromium/chrome/browser/modelutil/PropertyModelChangeProcessor.java", "java/src/org/chromium/chrome/browser/modelutil/PropertyObservable.java", "java/src/org/chromium/chrome/browser/modelutil/RecyclerViewModelChangeProcessor.java", "java/src/org/chromium/chrome/browser/modelutil/RecyclerViewAdapter.java", @@ -1271,10 +1272,15 @@ "java/src/org/chromium/chrome/browser/tabmodel/document/StorageDelegate.java", "java/src/org/chromium/chrome/browser/tabmodel/document/TabDelegate.java", "java/src/org/chromium/chrome/browser/toolbar/ActionModeController.java", + "java/src/org/chromium/chrome/browser/toolbar/BottomToolbarController.java", + "java/src/org/chromium/chrome/browser/toolbar/BottomToolbarMediator.java", + "java/src/org/chromium/chrome/browser/toolbar/BottomToolbarModel.java", + "java/src/org/chromium/chrome/browser/toolbar/BottomToolbarViewBinder.java", "java/src/org/chromium/chrome/browser/toolbar/CustomTabToolbar.java", "java/src/org/chromium/chrome/browser/toolbar/CustomTabToolbarAnimationDelegate.java", "java/src/org/chromium/chrome/browser/toolbar/HomePageButton.java", "java/src/org/chromium/chrome/browser/toolbar/KeyboardNavigationListener.java", + "java/src/org/chromium/chrome/browser/toolbar/ScrollingBottomViewResourceFrameLayout.java", "java/src/org/chromium/chrome/browser/toolbar/TabSwitcherCallout.java", "java/src/org/chromium/chrome/browser/toolbar/TabSwitcherDrawable.java", "java/src/org/chromium/chrome/browser/toolbar/Toolbar.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBlobUrlTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBlobUrlTest.java index 7398a9af..7ee1266f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBlobUrlTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestBlobUrlTest.java
@@ -33,7 +33,6 @@ mPaymentRequestTestRule.openPageAndClickNode("buy"); mPaymentRequestTestRule.assertWaitForPageScaleFactorMatch(2); mPaymentRequestTestRule.expectResultContains( - new String[] {"SecurityError: Failed to construct 'PaymentRequest': " - + "Must be in a secure context"}); + new String[] {"PaymentRequest is not defined"}); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDataUrlTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDataUrlTest.java index 1312e18e..f46c17f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDataUrlTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestDataUrlTest.java
@@ -46,7 +46,6 @@ public void test() throws InterruptedException, ExecutionException, TimeoutException { mPaymentRequestTestRule.openPageAndClickNode("buy"); mPaymentRequestTestRule.expectResultContains( - new String[] {"SecurityError: Failed to construct 'PaymentRequest': " - + "Must be in a secure context"}); + new String[] {"PaymentRequest is not defined"}); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellDialogTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellDialogTest.java index 01d9564..c79ad76 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellDialogTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/VrShellDialogTest.java
@@ -27,6 +27,7 @@ import org.chromium.base.test.util.UrlUtils; import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.vr_shell.rules.ChromeTabbedActivityVrTestRule; +import org.chromium.chrome.browser.vr_shell.rules.HeadTrackingMode; import org.chromium.chrome.browser.vr_shell.util.TransitionUtils; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -95,6 +96,7 @@ @Test @Manual @LargeTest + @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN) public void microphoneDialogTest() throws InterruptedException, TimeoutException { // Display audio permissions prompt. displayDialog( @@ -110,6 +112,7 @@ @Test @Manual @LargeTest + @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN) public void cameraDialogTest() throws InterruptedException, TimeoutException { // Display Camera permissions prompt. displayDialog( @@ -125,6 +128,7 @@ @Test @Manual @LargeTest + @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN) public void locationDialogTest() throws InterruptedException, TimeoutException { // Display Location permissions prompt. displayDialog("test_navigation_2d_page", @@ -140,6 +144,7 @@ @Test @Manual @LargeTest + @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN) public void notificationDialogTest() throws InterruptedException, TimeoutException { // Display Notification permissions prompt. displayDialog("test_navigation_2d_page", "Notification.requestPermission(()=>{})"); @@ -154,6 +159,7 @@ @Test @Manual @LargeTest + @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN) public void midiDialogTest() throws InterruptedException, TimeoutException { // Display MIDI permissions prompt. displayDialog("test_navigation_2d_page", "navigator.requestMIDIAccess({sysex: true})");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/ChromeTabbedActivityVrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/ChromeTabbedActivityVrTestRule.java index becc01ef..8a3fc20 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/ChromeTabbedActivityVrTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/ChromeTabbedActivityVrTestRule.java
@@ -9,6 +9,7 @@ import org.chromium.chrome.browser.vr_shell.TestVrShellDelegate; import org.chromium.chrome.browser.vr_shell.rules.VrActivityRestriction.SupportedActivity; +import org.chromium.chrome.browser.vr_shell.util.HeadTrackingUtils; import org.chromium.chrome.test.ChromeTabbedActivityTestRule; /** @@ -17,14 +18,22 @@ */ public class ChromeTabbedActivityVrTestRule extends ChromeTabbedActivityTestRule implements VrTestRule { + private boolean mTrackerDirty; + @Override - public Statement apply(final Statement base, Description desc) { + public Statement apply(final Statement base, final Description desc) { return super.apply(new Statement() { @Override public void evaluate() throws Throwable { + HeadTrackingUtils.checkForAndApplyHeadTrackingModeAnnotation( + ChromeTabbedActivityVrTestRule.this, desc); startMainActivityOnBlankPage(); TestVrShellDelegate.createTestVrShellDelegate(getActivity()); - base.evaluate(); + try { + base.evaluate(); + } finally { + if (isTrackerDirty()) HeadTrackingUtils.revertTracker(); + } } }, desc); } @@ -33,4 +42,14 @@ public SupportedActivity getRestriction() { return SupportedActivity.CTA; } + + @Override + public boolean isTrackerDirty() { + return mTrackerDirty; + } + + @Override + public void setTrackerDirty() { + mTrackerDirty = true; + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/CustomTabActivityVrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/CustomTabActivityVrTestRule.java index d5caf40..801ba67 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/CustomTabActivityVrTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/CustomTabActivityVrTestRule.java
@@ -13,21 +13,30 @@ import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; import org.chromium.chrome.browser.vr_shell.TestVrShellDelegate; import org.chromium.chrome.browser.vr_shell.rules.VrActivityRestriction.SupportedActivity; +import org.chromium.chrome.browser.vr_shell.util.HeadTrackingUtils; /** * VR extension of CustomTabActivityTestRule. Applies CustomTabActivityTestRule then * opens up a CustomTabActivity to a blank page. */ public class CustomTabActivityVrTestRule extends CustomTabActivityTestRule implements VrTestRule { + private boolean mTrackerDirty; + @Override - public Statement apply(final Statement base, Description desc) { + public Statement apply(final Statement base, final Description desc) { return super.apply(new Statement() { @Override public void evaluate() throws Throwable { + HeadTrackingUtils.checkForAndApplyHeadTrackingModeAnnotation( + CustomTabActivityVrTestRule.this, desc); startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent( InstrumentationRegistry.getTargetContext(), "about:blank")); TestVrShellDelegate.createTestVrShellDelegate(getActivity()); - base.evaluate(); + try { + base.evaluate(); + } finally { + if (isTrackerDirty()) HeadTrackingUtils.revertTracker(); + } } }, desc); } @@ -36,4 +45,14 @@ public SupportedActivity getRestriction() { return SupportedActivity.CCT; } + + @Override + public boolean isTrackerDirty() { + return mTrackerDirty; + } + + @Override + public void setTrackerDirty() { + mTrackerDirty = true; + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/HeadTrackingMode.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/HeadTrackingMode.java new file mode 100644 index 0000000..bcfb2de5 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/HeadTrackingMode.java
@@ -0,0 +1,45 @@ +// Copyright 2018 The Chromium 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.vr_shell.rules; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * An annotation for setting the VrCore head tracking service's tracking mode during pre-test setup. + * + * The benefit of setting the mode this way instead of via HeadTrackingUtils during a test is that + * starting services is asynchronous with no good way of waiting until whatever the service does + * takes effect. When set during a test, the test must idle long enough to safely assume that the + * service has taken effect. When applied during test setup, the Chrome startup period acts as the + * wait, as Chrome startup is slow enough that it's safe to assume the service has started by the + * time Chrome is ready. + * + * For example, the following would cause a test to start with its head position locked looking + * straight forward: + * <code> + * @HeadTrackingMode(HeadTrackingMode.SupportedMode.FROZEN) + * </code> + * If a test is not annotated with this, it will use whatever mode is currently set. This should + * usually be the normal, sensor-based tracker, but is not guaranteed. + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface HeadTrackingMode { + public enum SupportedMode { + FROZEN, // Locked looking straight forward. + SWEEP, // Rotates back and forth horizontally in a 180 degree arc. + ROTATE, // Rotates 360 degrees. + CIRCLE_STRAFE, // Rotates 360 degrees, and if 6DOF is supported, changes position. + MOTION_SICKNESS // Moves in a figure-eight-like pattern. + } + + /** + * @return The supported mode. + */ + public SupportedMode value(); +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/VrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/VrTestRule.java index 0bee04cb1..d3b8135 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/VrTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/VrTestRule.java
@@ -15,4 +15,14 @@ * Get the VrActivityRestriction.SupportedActivity that this rule is restricted to running in. */ public SupportedActivity getRestriction(); + + /** + * Whether the head tracking mode has been changed. + */ + public boolean isTrackerDirty(); + + /** + * Tells the rule that the head tracking mode has been changed. + */ + public void setTrackerDirty(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/WebappActivityVrTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/WebappActivityVrTestRule.java index ada20011..9dbb9525 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/WebappActivityVrTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/rules/WebappActivityVrTestRule.java
@@ -9,6 +9,7 @@ import org.chromium.chrome.browser.vr_shell.TestVrShellDelegate; import org.chromium.chrome.browser.vr_shell.rules.VrActivityRestriction.SupportedActivity; +import org.chromium.chrome.browser.vr_shell.util.HeadTrackingUtils; import org.chromium.chrome.browser.webapps.WebappActivityTestRule; /** @@ -16,14 +17,22 @@ * up a WebappActivity to a blank page. */ public class WebappActivityVrTestRule extends WebappActivityTestRule implements VrTestRule { + private boolean mTrackerDirty; + @Override - public Statement apply(final Statement base, Description desc) { + public Statement apply(final Statement base, final Description desc) { return super.apply(new Statement() { @Override public void evaluate() throws Throwable { + HeadTrackingUtils.checkForAndApplyHeadTrackingModeAnnotation( + WebappActivityVrTestRule.this, desc); startWebappActivity(); TestVrShellDelegate.createTestVrShellDelegate(getActivity()); - base.evaluate(); + try { + base.evaluate(); + } finally { + if (isTrackerDirty()) HeadTrackingUtils.revertTracker(); + } } }, desc); } @@ -32,4 +41,14 @@ public SupportedActivity getRestriction() { return SupportedActivity.WAA; } + + @Override + public boolean isTrackerDirty() { + return mTrackerDirty; + } + + @Override + public void setTrackerDirty() { + mTrackerDirty = true; + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/HeadTrackingUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/HeadTrackingUtils.java new file mode 100644 index 0000000..ac38f42d --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/util/HeadTrackingUtils.java
@@ -0,0 +1,209 @@ +// Copyright 2018 The Chromium 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.vr_shell.util; + +import android.content.ComponentName; +import android.content.Intent; +import android.os.SystemClock; +import android.support.test.InstrumentationRegistry; + +import org.junit.Assert; +import org.junit.runner.Description; + +import org.chromium.chrome.browser.vr_shell.rules.HeadTrackingMode; +import org.chromium.chrome.browser.vr_shell.rules.HeadTrackingMode.SupportedMode; +import org.chromium.chrome.browser.vr_shell.rules.VrTestRule; + +import java.util.Arrays; + +/** + * Utility class for interacting with the VrCore head tracking service, which allows fake head + * poses to be submitted instead of using actual sensor data. + * + * Requires that either the O2 rendering path is enabled or EnableVrCoreHeadTracking is set to true + * in the shared prefs file in order to actually work. + */ +public class HeadTrackingUtils { + private static final ComponentName HEAD_TRACKING_COMPONENT = new ComponentName( + "com.google.vr.vrcore", "com.google.vr.vrcore.tracking.HeadTrackingService"); + + private static final String ACTION_SET_TRACKER_TYPE = "com.google.vr.vrcore.SET_TRACKER_TYPE"; + private static final String ACTION_SET_FAKE_TRACKER_MODE = + "com.google.vr.vrcore.SET_FAKE_TRACKER_MODE"; + private static final String ACTION_SET_FAKE_TRACKER_POSE = + "com.google.vr.vrcore.SET_FAKE_TRACKER_POSE"; + private static final String EXTRA_FAKE_TRACKER_MODE = "com.google.vr.vrcore.FAKE_TRACKER_MODE"; + private static final String EXTRA_FAKE_TRACKER_POSE = "com.google.vr.vrcore.FAKE_TRACKER_POSE"; + private static final String EXTRA_TRACKER_TYPE = "com.google.vr.vrcore.TRACKER_TYPE"; + + private static final int HEAD_TRACKING_APPLICATION_DELAY_MS = 500; + + /** + * Class for holding data necessary to set the head tracking service's head pose to an + * arbitarary, static value. Contains either a quaternion or set of rotation Euler angles + * describing the direction to look in and an optional position in room space if 6DOF is + * supported. + */ + public static class FakePose { + private float[] mQuaternion; + private float[] mRotationEulerAngles; + private float[] mRoomSpacePosition; + + public FakePose setQuaternion(float x, float y, float z, float w) { + mQuaternion = new float[] {x, y, z, w}; + mRotationEulerAngles = null; + return this; + } + + public FakePose setRotationEulerAngles(float rollDeg, float pitchDeg, float yawDeg) { + mRotationEulerAngles = new float[] {rollDeg, pitchDeg, yawDeg}; + mQuaternion = null; + return this; + } + + public FakePose setRoomSpacePosition(float x, float y, float z) { + mRoomSpacePosition = new float[] {x, y, z}; + return this; + } + + public FakePose clearRoomSpacePosition() { + mRoomSpacePosition = null; + return this; + } + + public float[] getDataForExtra() { + if (mQuaternion == null && mRotationEulerAngles == null) { + throw new IllegalArgumentException( + "Tried to get FakePose data without setting either quaternion/angle data"); + } + float[] orientationArray = + mRotationEulerAngles == null ? mQuaternion : mRotationEulerAngles; + if (mRoomSpacePosition == null) return orientationArray; + float[] combinedArray = Arrays.copyOf( + orientationArray, orientationArray.length + mRoomSpacePosition.length); + for (int i = 0; i < mRoomSpacePosition.length; i++) { + combinedArray[i + orientationArray.length] = mRoomSpacePosition[i]; + } + return combinedArray; + } + } + + /** + * Checks for the presence of a HeadTrackingMode annotation, and if found, sets the tracking + * mode to the specified value. If no annotation is found, the tracking mode is left at whatever + * the existing value is. + * + * @param rule The VrTestRule used by the current test case. + * @param desc The JUnit4 Description for the current test case. + */ + public static void checkForAndApplyHeadTrackingModeAnnotation( + VrTestRule rule, Description desc) { + // Check if the test has a HeadTrackingMode annotation + HeadTrackingMode annotation = desc.getAnnotation(HeadTrackingMode.class); + if (annotation == null) return; + applyHeadTrackingModeInternal(rule, annotation.value()); + } + + /** + * Sets the tracker type to the given mode and waits long enough to safely assume that the + * service has started. + * + * @param rule The VrTestRule used by the current test case. + * @param mode The HeadTrackingMode.SupportedMode value to set the fake head tracker mode to. + */ + public static void applyHeadTrackingMode(VrTestRule rule, SupportedMode mode) { + applyHeadTrackingModeInternal(rule, mode); + // TODO(bsheedy): Remove this sleep if the head tracking service ever exposes a way to be + // notified when a setting has been applied. + SystemClock.sleep(HEAD_TRACKING_APPLICATION_DELAY_MS); + } + + /** + * Sets the head pose to the pose described by the given FakePose and waits long enough to + * safely assume that the pose has taken effect. + * + * @param rule The VrTestRule used by the current test case. + * @param pose The FakePose instance containing the pose data that will be sent to the head + * tracking service. + */ + public static void setHeadPose(VrTestRule rule, FakePose pose) { + restartHeadTrackingServiceIfNecessary(rule); + // Set the head pose to the given value + Intent poseIntent = new Intent(ACTION_SET_FAKE_TRACKER_POSE); + poseIntent.putExtra(EXTRA_FAKE_TRACKER_POSE, pose.getDataForExtra()); + poseIntent.setComponent(HEAD_TRACKING_COMPONENT); + Assert.assertTrue(InstrumentationRegistry.getContext().startService(poseIntent) != null); + rule.setTrackerDirty(); + // TODO(bsheedy): Remove this sleep. Could either expose poses up to Java and wait until + // we receive a pose that's the same as the one we set or see if the head tracking service + // adds the requested functionality of sending a notification when it's done applying + // settings. + SystemClock.sleep(HEAD_TRACKING_APPLICATION_DELAY_MS); + } + + /** + * Reverts the tracking type back to values that a regular user would have (using real sensor + * data). + * + * Only meant to be called by rules after a test has run. Reseting the tracker to use sensor + * data during a test technically works, but messes up orientation if done while still in VR. + * until VR is exited and re-entered. + */ + public static void revertTracker() { + Intent typeIntent = new Intent(ACTION_SET_TRACKER_TYPE); + typeIntent.putExtra(EXTRA_TRACKER_TYPE, "sensor"); + typeIntent.setComponent(HEAD_TRACKING_COMPONENT); + InstrumentationRegistry.getContext().startService(typeIntent); + } + + public static String supportedModeToString(SupportedMode mode) { + switch (mode) { + case FROZEN: + return "frozen"; + case SWEEP: + return "sweep"; + case ROTATE: + return "rotate"; + case CIRCLE_STRAFE: + return "circle_strafe"; + case MOTION_SICKNESS: + return "motion_sickness"; + default: + return "unknown_mode"; + } + } + + private static void applyHeadTrackingModeInternal(VrTestRule rule, SupportedMode mode) { + restartHeadTrackingServiceIfNecessary(rule); + // Set the fake tracker mode to the given value. + Intent modeIntent = new Intent(ACTION_SET_FAKE_TRACKER_MODE); + modeIntent.putExtra(EXTRA_FAKE_TRACKER_MODE, supportedModeToString(mode)); + modeIntent.setComponent(HEAD_TRACKING_COMPONENT); + Assert.assertTrue(InstrumentationRegistry.getContext().startService(modeIntent) != null); + rule.setTrackerDirty(); + } + + private static void restartHeadTrackingServiceIfNecessary(VrTestRule rule) { + // If the tracker has already been dirtied, then we can assume that the tracker type + // has already been set to "fake". + if (rule.isTrackerDirty()) return; + + // VR sessions from previous tests can somehow interfere with the setting of the tracker + // type, even if said previous sessions did not touch the head tracking service. Killing + // the service before attempting to set the tracker type appears to work around this + // issue. + // TODO(https://crbug.com/829127): Remove this once the root cause is fixed. + Intent stopIntent = new Intent(); + stopIntent.setComponent(HEAD_TRACKING_COMPONENT); + InstrumentationRegistry.getContext().stopService(stopIntent); + + // Set the tracker tracker type to "fake". + Intent typeIntent = new Intent(ACTION_SET_TRACKER_TYPE); + typeIntent.putExtra(EXTRA_TRACKER_TYPE, "fake"); + typeIntent.setComponent(HEAD_TRACKING_COMPONENT); + Assert.assertTrue(InstrumentationRegistry.getContext().startService(typeIntent) != null); + rule.setTrackerDirty(); + } +} \ No newline at end of file
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index 6a4237b..d66d411 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -386,7 +386,7 @@ chrome_packaged_services = [ ":chrome_manifest", - "//chrome/profiling:manifest", + "//components/services/heap_profiling:manifest", "//components/services/patch:manifest", "//components/services/unzip:manifest", "//chrome/services/file_util:manifest",
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 8b4cb14..4c92453 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -10619,18 +10619,6 @@ <message name="IDS_BLUETOOTH_DEVICE_CHOOSER_PROMPT_EXTENSION_NAME" desc="The label that is used to introduce Bluetooth chooser details to the user in a popup when it is from a Chrome extension."> "<ph name="CHROME_EXTENSION_NAME">$1<ex>Chrome Extension Name</ex></ph>" wants to pair </message> - <message name="IDS_USB_DEVICE_CHOOSER_PROMPT_ORIGIN" desc="The label that is used to introduce USB chooser details to the user in a popup when it is from a website."> - <ph name="Origin">$1<ex>www.google.com</ex></ph> wants to connect - </message> - <message name="IDS_USB_DEVICE_CHOOSER_PROMPT_EXTENSION_NAME" desc="The label that is used to introduce USB chooser details to the user in a popup when it is from a Chrome extension."> - "<ph name="CHROME_EXTENSION_NAME">$1<ex>Chrome Extension Name</ex></ph>" wants to connect - </message> - <message name="IDS_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT" desc="The label shown to the user to inform them that no USB devices were found matching the requirements that the application provided."> - No compatible devices found. - </message> - <message name="IDS_DEVICE_CHOOSER_DEVICE_NAME_WITH_ID" desc="To distinguish devices with the same name, the device chooser shows the device name with id."> - <ph name="DEVICE_NAME">$1<ex>device name</ex></ph> (<ph name="DEVICE_ID">$2<ex>device id</ex></ph>) - </message> <message name="IDS_BLUETOOTH_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT" desc="The label shown to the user to inform them that no Bluetooth devices were found matching the requirements that the application provided."> No compatible devices found. </message> @@ -10658,9 +10646,6 @@ <message name="IDS_BLUETOOTH_DEVICE_CHOOSER_PAIR_BUTTON_TEXT" desc="Label on the button that closes the Bluetooth chooser popup and pairs the selected device."> Pair </message> - <message name="IDS_USB_DEVICE_CHOOSER_CONNECT_BUTTON_TEXT" desc="Label on the button that closes the USB chooser popup and connects the selected device."> - Connect - </message> <message name="IDS_DEVICE_CHOOSER_CANCEL_BUTTON_TEXT" desc="Label on the button that closes the chooser popup without selecting an option."> Cancel </message> @@ -10677,6 +10662,21 @@ <ph name="DEVICE_NAME">$1<ex>device name</ex></ph> - Paired </message> </if> + <message name="IDS_USB_DEVICE_CHOOSER_PROMPT_ORIGIN" desc="The label that is used to introduce USB chooser details to the user in a popup when it is from a website."> + <ph name="Origin">$1<ex>www.google.com</ex></ph> wants to connect + </message> + <message name="IDS_USB_DEVICE_CHOOSER_PROMPT_EXTENSION_NAME" desc="The label that is used to introduce USB chooser details to the user in a popup when it is from a Chrome extension."> + "<ph name="CHROME_EXTENSION_NAME">$1<ex>Chrome Extension Name</ex></ph>" wants to connect + </message> + <message name="IDS_DEVICE_CHOOSER_DEVICE_NAME_WITH_ID" desc="To distinguish devices with the same name, the device chooser shows the device name with id."> + <ph name="DEVICE_NAME">$1<ex>device name</ex></ph> (<ph name="DEVICE_ID">$2<ex>device id</ex></ph>) + </message> + <message name="IDS_DEVICE_CHOOSER_NO_DEVICES_FOUND_PROMPT" desc="The label shown to the user to inform them that no USB devices were found matching the requirements that the application provided."> + No compatible devices found. + </message> + <message name="IDS_USB_DEVICE_CHOOSER_CONNECT_BUTTON_TEXT" desc="Label on the button that closes the USB chooser popup and connects the selected device."> + Connect + </message> <!-- Device Chooser Device Name Unknown --> <message name="IDS_DEVICE_CHOOSER_DEVICE_NAME_UNKNOWN_DEVICE_WITH_VENDOR_NAME" desc="String describing an unknown device by its vendor name."> @@ -10877,9 +10877,6 @@ <message name="IDS_PRESS_APP_TO_EXIT" desc="Text displayed in a transient bubble to tell users how to return from presentation mode (where the WebVR page occupies the entire screen) to normal mode."> Press App button to exit </message> - <message name="IDS_PRESS_APP_TO_EXIT_FULLSCREEN" desc="Text displayed in a transient bubble to tell users how to return from cinema mode (where the page displayed in a cinema like environment)."> - Press App button to exit fullscreen - </message> <message name="IDS_VR_SHELL_SITE_IS_TRACKING_LOCATION" desc="Text displayed in a transient bubble to inform the user that the page is tracking location."> Site is tracking your location </message>
diff --git a/chrome/app/nibs/InfoBar.xib b/chrome/app/nibs/InfoBar.xib index 95b2216..5f506ec9 100644 --- a/chrome/app/nibs/InfoBar.xib +++ b/chrome/app/nibs/InfoBar.xib
@@ -23,7 +23,7 @@ <rect key="frame" x="0.0" y="0.0" width="480" height="48"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <subviews> - <customView id="1" customClass="InfoBarGradientView"> + <customView id="1" customClass="InfoBarBackgroundView"> <rect key="frame" x="0.0" y="0.0" width="480" height="48"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMaxY="YES"/> <subviews>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 51bb02e..7661789 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -226,6 +226,8 @@ "budget_service/budget_service_impl.h", "cache_stats_recorder.cc", "cache_stats_recorder.h", + "chooser_controller/chooser_controller.cc", + "chooser_controller/chooser_controller.h", "chrome_browser_application_mac.h", "chrome_browser_application_mac.mm", "chrome_browser_field_trials.cc", @@ -1510,10 +1512,14 @@ "usb/usb_chooser_context.h", "usb/usb_chooser_context_factory.cc", "usb/usb_chooser_context_factory.h", + "usb/usb_chooser_controller.cc", + "usb/usb_chooser_controller.h", "usb/usb_tab_helper.cc", "usb/usb_tab_helper.h", "usb/usb_util.cc", "usb/usb_util.h", + "usb/web_usb_chooser_service.cc", + "usb/web_usb_chooser_service.h", "usb/web_usb_histograms.cc", "usb/web_usb_histograms.h", "usb/web_usb_permission_provider.cc", @@ -2377,8 +2383,6 @@ "bookmarks/bookmark_html_writer.cc", "bookmarks/bookmark_html_writer.h", "certificate_viewer.h", - "chooser_controller/chooser_controller.cc", - "chooser_controller/chooser_controller.h", "chrome_browser_field_trials_desktop.cc", "chrome_browser_field_trials_desktop.h", "chrome_browser_main_posix.cc", @@ -2776,10 +2780,6 @@ "upgrade_detector.cc", "upgrade_detector.h", "upgrade_observer.h", - "usb/usb_chooser_controller.cc", - "usb/usb_chooser_controller.h", - "usb/web_usb_chooser_service.cc", - "usb/web_usb_chooser_service.h", "usb/web_usb_chooser_service_desktop.cc", "usb/web_usb_chooser_service_desktop.h", "usb/web_usb_detector.cc",
diff --git a/chrome/browser/android/data_usage/data_use_tab_helper.cc b/chrome/browser/android/data_usage/data_use_tab_helper.cc index 5b16cde..2bfe421 100644 --- a/chrome/browser/android/data_usage/data_use_tab_helper.cc +++ b/chrome/browser/android/data_usage/data_use_tab_helper.cc
@@ -44,8 +44,8 @@ android::DataUseUITabModel* data_use_ui_tab_model = android::DataUseUITabModelFactory::GetForBrowserContext( Profile::FromBrowserContext(web_contents()->GetBrowserContext())); - SessionID::id_type tab_id = SessionTabHelper::IdForTab(web_contents()); - if (!data_use_ui_tab_model || tab_id < 0) + SessionID tab_id = SessionTabHelper::IdForTab(web_contents()); + if (!data_use_ui_tab_model || !tab_id.is_valid()) return; // The last committed navigation entry should correspond to the current @@ -74,7 +74,7 @@ android::DataUseUITabModel* data_use_ui_tab_model = android::DataUseUITabModelFactory::GetForBrowserContext( Profile::FromBrowserContext(web_contents()->GetBrowserContext())); - SessionID::id_type tab_id = SessionTabHelper::IdForTab(web_contents()); - if (data_use_ui_tab_model && tab_id >= 0) + SessionID tab_id = SessionTabHelper::IdForTab(web_contents()); + if (data_use_ui_tab_model && tab_id.is_valid()) data_use_ui_tab_model->ReportTabClosure(tab_id); }
diff --git a/chrome/browser/android/data_usage/data_use_tab_model.cc b/chrome/browser/android/data_usage/data_use_tab_model.cc index 91b961e..27e5d1b 100644 --- a/chrome/browser/android/data_usage/data_use_tab_model.cc +++ b/chrome/browser/android/data_usage/data_use_tab_model.cc
@@ -75,11 +75,6 @@ END_REASON_MAX = 4 }; -// Returns true if |tab_id| is a valid tab ID. -bool IsValidTabID(SessionID::id_type tab_id) { - return tab_id >= 0; -} - // Returns various parameters from the values specified in the field trial. size_t GetMaxTabEntries() { size_t max_tab_entries = kDefaultMaxTabEntries; @@ -250,13 +245,13 @@ } void DataUseTabModel::OnNavigationEvent( - SessionID::id_type tab_id, + SessionID tab_id, TransitionType transition, const GURL& url, const std::string& package, content::NavigationEntry* navigation_entry) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(IsValidTabID(tab_id)); + DCHECK(tab_id.is_valid()); DCHECK(!navigation_entry || (navigation_entry->GetURL() == url)); std::string current_label, new_label; @@ -286,9 +281,9 @@ } } -void DataUseTabModel::OnTabCloseEvent(SessionID::id_type tab_id) { +void DataUseTabModel::OnTabCloseEvent(SessionID tab_id) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(IsValidTabID(tab_id)); + DCHECK(tab_id.is_valid()); TabEntryMap::iterator tab_entry_iterator = active_tabs_.find(tab_id); if (tab_entry_iterator == active_tabs_.end()) @@ -306,7 +301,7 @@ } bool DataUseTabModel::GetTrackingInfoForTabAtTime( - SessionID::id_type tab_id, + SessionID tab_id, const base::TimeTicks timestamp, TrackingInfo* output_tracking_info) const { DCHECK(thread_checker_.CalledOnValidThread()); @@ -314,7 +309,7 @@ output_tracking_info->label = ""; // Data use that cannot be attributed to a tab will not be labeled. - if (!IsValidTabID(tab_id)) + if (!tab_id.is_valid()) return false; TabEntryMap::const_iterator tab_entry_iterator = active_tabs_.find(tab_id); @@ -334,12 +329,12 @@ } bool DataUseTabModel::WouldNavigationEventEndTracking( - SessionID::id_type tab_id, + SessionID tab_id, TransitionType transition, const GURL& url, const content::NavigationEntry* navigation_entry) const { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(IsValidTabID(tab_id)); + DCHECK(tab_id.is_valid()); std::string current_label, new_label; bool is_package_match; GetCurrentAndNewLabelForNavigationEvent( @@ -402,22 +397,20 @@ return tick_clock_->NowTicks(); } -bool DataUseTabModel::IsCustomTabPackageMatch(SessionID::id_type tab_id) const { +bool DataUseTabModel::IsCustomTabPackageMatch(SessionID tab_id) const { DCHECK(thread_checker_.CalledOnValidThread()); TabEntryMap::const_iterator tab_entry_iterator = active_tabs_.find(tab_id); return (tab_entry_iterator != active_tabs_.end()) && tab_entry_iterator->second.is_custom_tab_package_match(); } -void DataUseTabModel::NotifyObserversOfTrackingStarting( - SessionID::id_type tab_id) { +void DataUseTabModel::NotifyObserversOfTrackingStarting(SessionID tab_id) { DCHECK(thread_checker_.CalledOnValidThread()); for (TabDataUseObserver& observer : observers_) observer.NotifyTrackingStarting(tab_id); } -void DataUseTabModel::NotifyObserversOfTrackingEnding( - SessionID::id_type tab_id) { +void DataUseTabModel::NotifyObserversOfTrackingEnding(SessionID tab_id) { DCHECK(thread_checker_.CalledOnValidThread()); for (TabDataUseObserver& observer : observers_) observer.NotifyTrackingEnding(tab_id); @@ -430,7 +423,7 @@ } void DataUseTabModel::GetCurrentAndNewLabelForNavigationEvent( - SessionID::id_type tab_id, + SessionID tab_id, TransitionType transition, const GURL& url, const std::string& package, @@ -439,7 +432,7 @@ std::string* new_label, bool* is_package_match) const { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(IsValidTabID(tab_id)); + DCHECK(tab_id.is_valid()); TabEntryMap::const_iterator tab_entry_iterator = active_tabs_.find(tab_id); *current_label = @@ -520,7 +513,7 @@ } void DataUseTabModel::StartTrackingDataUse(TransitionType transition, - SessionID::id_type tab_id, + SessionID tab_id, const std::string& label, bool is_custom_tab_package_match) { DCHECK(thread_checker_.CalledOnValidThread()); @@ -550,7 +543,7 @@ } void DataUseTabModel::EndTrackingDataUse(TransitionType transition, - SessionID::id_type tab_id) { + SessionID tab_id) { DCHECK(thread_checker_.CalledOnValidThread()); TabEntryMap::iterator tab_entry_iterator = active_tabs_.find(tab_id);
diff --git a/chrome/browser/android/data_usage/data_use_tab_model.h b/chrome/browser/android/data_usage/data_use_tab_model.h index 7b51b04..fc5320f4 100644 --- a/chrome/browser/android/data_usage/data_use_tab_model.h +++ b/chrome/browser/android/data_usage/data_use_tab_model.h
@@ -90,8 +90,8 @@ virtual ~TabDataUseObserver() {} // Notification callbacks when tab tracking sessions are started and ended. - virtual void NotifyTrackingStarting(SessionID::id_type tab_id) = 0; - virtual void NotifyTrackingEnding(SessionID::id_type tab_id) = 0; + virtual void NotifyTrackingStarting(SessionID tab_id) = 0; + virtual void NotifyTrackingEnding(SessionID tab_id) = 0; // Notification callback that DataUseTabModel is ready to process the UI // navigation events. @@ -124,7 +124,7 @@ // |navigation_entry| can be null in some cases where it cannot be retrieved // such as buffered navigation events or when support for back-forward // navigations is not needed such as custom tab navigation. - void OnNavigationEvent(SessionID::id_type tab_id, + void OnNavigationEvent(SessionID tab_id, TransitionType transition, const GURL& url, const std::string& package, @@ -133,7 +133,7 @@ // Notifies the DataUseTabModel that tab with |tab_id| is closed. Any active // tracking sessions for the tab are terminated, and the tab is marked as // closed. - void OnTabCloseEvent(SessionID::id_type tab_id); + void OnTabCloseEvent(SessionID tab_id); // Notifies the DataUseTabModel that tracking label |label| is removed. Any // active tracking sessions with the label are ended, without notifying any of @@ -146,7 +146,7 @@ // |output_tracking_info| is populated with its information. Otherwise, // returns false. virtual bool GetTrackingInfoForTabAtTime( - SessionID::id_type tab_id, + SessionID tab_id, base::TimeTicks timestamp, TrackingInfo* output_tracking_info) const; @@ -156,7 +156,7 @@ // navigation entry of the current navigation in back-forward navigation // history. bool WouldNavigationEventEndTracking( - SessionID::id_type tab_id, + SessionID tab_id, TransitionType transition, const GURL& url, const content::NavigationEntry* navigation_entry) const; @@ -193,7 +193,7 @@ // Returns true if the |tab_id| is a custom tab and started tracking due to // package name match. - bool IsCustomTabPackageMatch(SessionID::id_type tab_id) const; + bool IsCustomTabPackageMatch(SessionID tab_id) const; // Returns true if DataUseTabModel is ready to process UI navigation events. bool is_ready_for_navigation_event() const { @@ -203,11 +203,11 @@ protected: // Notifies the observers that a data usage tracking session started for // |tab_id|. Protected for testing. - void NotifyObserversOfTrackingStarting(SessionID::id_type tab_id); + void NotifyObserversOfTrackingStarting(SessionID tab_id); // Notifies the observers that an active data usage tracking session ended for // |tab_id|. Protected for testing. - void NotifyObserversOfTrackingEnding(SessionID::id_type tab_id); + void NotifyObserversOfTrackingEnding(SessionID tab_id); // Notifies the observers that DataUseTabModel is ready to process navigation // events. @@ -237,7 +237,7 @@ FRIEND_TEST_ALL_PREFIXES(ExternalDataUseObserverTest, MatchingRuleFetchOnControlAppInstall); - using TabEntryMap = std::map<SessionID::id_type, TabDataUseEntry>; + using TabEntryMap = std::map<SessionID, TabDataUseEntry>; // Gets the current label of a tab, and the new label if a navigation event // occurs in the tab. |tab_id| is the source tab of the generated event, @@ -252,7 +252,7 @@ // tracking session if the navigation happens. |is_package_match| will be set // to true if a tracking session will start due to package name match. void GetCurrentAndNewLabelForNavigationEvent( - SessionID::id_type tab_id, + SessionID tab_id, TransitionType transition, const GURL& url, const std::string& package, @@ -265,12 +265,12 @@ // |is_custom_tab_package_match| is true if |tab_id| is a custom tab and // started tracking due to package name match. void StartTrackingDataUse(TransitionType transition, - SessionID::id_type tab_id, + SessionID tab_id, const std::string& label, bool is_custom_tab_package_match); // Ends the current tracking session for tab with id |tab_id|. - void EndTrackingDataUse(TransitionType transition, SessionID::id_type tab_id); + void EndTrackingDataUse(TransitionType transition, SessionID tab_id); // Compacts the tab entry map |active_tabs_| by removing expired tab entries. // After removing expired tab entries, if the size of |active_tabs_| exceeds
diff --git a/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc b/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc index a5f7960..1e04844 100644 --- a/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc +++ b/chrome/browser/android/data_usage/data_use_tab_model_unittest.cc
@@ -44,9 +44,9 @@ const char kTestLabel2[] = "label_2"; const char kTestLabel3[] = "label_3"; -const int kTabID1 = 1; -const int kTabID2 = 2; -const int kTabID3 = 3; +const SessionID kTabID1 = SessionID::FromSerializedValue(1); +const SessionID kTabID2 = SessionID::FromSerializedValue(2); +const SessionID kTabID3 = SessionID::FromSerializedValue(3); const char kURLFoo[] = "http://foo.com/"; const char kURLBar[] = "http://bar.com/"; @@ -71,8 +71,8 @@ class MockTabDataUseObserver : public android::DataUseTabModel::TabDataUseObserver { public: - MOCK_METHOD1(NotifyTrackingStarting, void(SessionID::id_type tab_id)); - MOCK_METHOD1(NotifyTrackingEnding, void(SessionID::id_type tab_id)); + MOCK_METHOD1(NotifyTrackingStarting, void(SessionID tab_id)); + MOCK_METHOD1(NotifyTrackingEnding, void(SessionID tab_id)); MOCK_METHOD0(OnDataUseTabModelReady, void()); }; @@ -130,7 +130,7 @@ } // Returns true if tab entry for |tab_id| exists in |active_tabs_|. - bool IsTabEntryExists(SessionID::id_type tab_id) const { + bool IsTabEntryExists(SessionID tab_id) const { return data_use_tab_model_->active_tabs_.find(tab_id) != data_use_tab_model_->active_tabs_.end(); } @@ -143,7 +143,7 @@ // Returns true if |tab_id| is a custom tab and started tracking due to // package match. - bool IsCustomTabPackageMatch(SessionID::id_type tab_id) const { + bool IsCustomTabPackageMatch(SessionID tab_id) const { auto tab_entry_iterator = data_use_tab_model_->active_tabs_.find(tab_id); return (tab_entry_iterator != data_use_tab_model_->active_tabs_.end()) && tab_entry_iterator->second.is_custom_tab_package_match(); @@ -151,7 +151,7 @@ // Returns true if the tracking session for tab with id |tab_id| is currently // active. - bool IsTrackingDataUse(SessionID::id_type tab_id) const { + bool IsTrackingDataUse(SessionID tab_id) const { const auto& tab_entry_iterator = data_use_tab_model_->active_tabs_.find(tab_id); if (tab_entry_iterator == data_use_tab_model_->active_tabs_.end()) @@ -161,7 +161,7 @@ // Checks if the DataUse object for the given |tab_id| with request start time // |at_time| is labeled as an empty tracking info. - void ExpectEmptyTrackingInfoAtTime(SessionID::id_type tab_id, + void ExpectEmptyTrackingInfoAtTime(SessionID tab_id, const base::TimeTicks& at_time) const { ExpectTrackingInfoAtTimeWithReturn(tab_id, at_time, false, DataUseTabModel::TrackingInfo()); @@ -169,14 +169,14 @@ // Checks if the DataUse object for the given |tab_id| is labeled as an empty // tracking info. - void ExpectEmptyTrackingInfo(SessionID::id_type tab_id) { + void ExpectEmptyTrackingInfo(SessionID tab_id) { ExpectTrackingInfoAtTimeWithReturn(tab_id, tick_clock_.NowTicks(), false, DataUseTabModel::TrackingInfo()); } // Checks if the DataUse object for given |tab_id| is labeled as // |expected_label| with custom tab indicated by |expected_is_custom_tab|. - void ExpectTrackingInfo(SessionID::id_type tab_id, + void ExpectTrackingInfo(SessionID tab_id, const std::string& expected_label, const std::string& expected_tag) { DataUseTabModel::TrackingInfo expected_tracking_info; @@ -191,7 +191,7 @@ // DataUse object for |tab_id| with request start time |at_time|, as // |expected_tracking_info| and returns |expected_return|. void ExpectTrackingInfoAtTimeWithReturn( - SessionID::id_type tab_id, + SessionID tab_id, const base::TimeTicks& at_time, bool expected_return, const DataUseTabModel::TrackingInfo& expected_tracking_info) const { @@ -205,13 +205,12 @@ } } - void StartTrackingDataUse(SessionID::id_type tab_id, - const std::string& label) { + void StartTrackingDataUse(SessionID tab_id, const std::string& label) { data_use_tab_model_->StartTrackingDataUse( DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, tab_id, label, false); } - void EndTrackingDataUse(SessionID::id_type tab_id) { + void EndTrackingDataUse(SessionID tab_id) { data_use_tab_model_->EndTrackingDataUse( DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, tab_id); } @@ -424,29 +423,31 @@ TEST_F(DataUseTabModelTest, CompactTabEntriesWithinMaxLimit) { const int32_t max_tab_entries = static_cast<int32_t>(data_use_tab_model_->max_tab_entries_); - SessionID::id_type tab_id = 1; + std::list<SessionID> tab_ids; ExpectTabEntrySize(TabEntrySize::ZERO); - while (tab_id <= max_tab_entries) { - std::string tab_label = base::StringPrintf("label_%d", tab_id); + for (int i = 0; i < max_tab_entries; ++i) { + SessionID tab_id = SessionID::NewUnique(); + tab_ids.push_back(tab_id); + std::string tab_label = base::StringPrintf("label_%d", tab_id.id()); StartTrackingDataUse(tab_id, tab_label); tick_clock_.Advance(base::TimeDelta::FromSeconds(1)); EndTrackingDataUse(tab_id); tick_clock_.Advance(base::TimeDelta::FromSeconds(1)); - ExpectTabEntrySize(tab_id); - ++tab_id; + ExpectTabEntrySize(i + 1); } - // Oldest tab entry that will be removed first. - SessionID::id_type oldest_tab_id = 1; - // Starting and ending more tracking tab entries does not increase the size of // |active_tabs_|. - while (tab_id < max_tab_entries + 10) { + for (int i = 0; i < 10; ++i) { + SessionID oldest_tab_id = tab_ids.front(); + EXPECT_TRUE(IsTabEntryExists(oldest_tab_id)); - std::string tab_label = base::StringPrintf("label_%d", tab_id); + SessionID tab_id = SessionID::NewUnique(); + tab_ids.push_back(tab_id); + std::string tab_label = base::StringPrintf("label_%d", tab_id.id()); StartTrackingDataUse(tab_id, tab_label); tick_clock_.Advance(base::TimeDelta::FromSeconds(1)); EndTrackingDataUse(tab_id); @@ -456,15 +457,17 @@ EXPECT_FALSE(IsTabEntryExists(oldest_tab_id)); ExpectTabEntrySize(max_tab_entries); - ++tab_id; - ++oldest_tab_id; // next oldest tab entry. + tab_ids.pop_front(); // next oldest tab entry. } // Starting and not ending more tracking tab entries does not increase the // size of |active_tabs_|. - while (tab_id < max_tab_entries + 20) { + for (int i = 0; i < 10; ++i) { + SessionID oldest_tab_id = tab_ids.front(); EXPECT_TRUE(IsTabEntryExists(oldest_tab_id)); - std::string tab_label = base::StringPrintf("label_%d", tab_id); + SessionID tab_id = SessionID::NewUnique(); + tab_ids.push_back(tab_id); + std::string tab_label = base::StringPrintf("label_%d", tab_id.id()); StartTrackingDataUse(tab_id, tab_label); tick_clock_.Advance(base::TimeDelta::FromSeconds(1)); @@ -472,8 +475,7 @@ EXPECT_FALSE(IsTabEntryExists(oldest_tab_id)); ExpectTabEntrySize(max_tab_entries); - ++tab_id; - ++oldest_tab_id; // next oldest tab entry. + tab_ids.pop_front(); // next oldest tab entry. } } @@ -513,20 +515,20 @@ base::HistogramTester histogram_tester; const int32_t max_tab_entries = static_cast<int32_t>(data_use_tab_model_->max_tab_entries_); - SessionID::id_type tab_id = 1; - while (tab_id <= max_tab_entries) { - std::string tab_label = base::StringPrintf("label_%d", tab_id); + for (int i = 0; i < max_tab_entries; ++i) { + SessionID tab_id = SessionID::NewUnique(); + std::string tab_label = base::StringPrintf("label_%d", tab_id.id()); StartTrackingDataUse(tab_id, tab_label); EndTrackingDataUse(tab_id); - ++tab_id; } // Fast forward 10 minutes. tick_clock_.Advance(base::TimeDelta::FromMinutes(10)); // Adding another tab entry triggers CompactTabEntries. - std::string tab_label = base::StringPrintf("label_%d", tab_id); + SessionID tab_id = SessionID::NewUnique(); + std::string tab_label = base::StringPrintf("label_%d", tab_id.id()); StartTrackingDataUse(tab_id, tab_label); EndTrackingDataUse(tab_id); @@ -653,7 +655,6 @@ {DataUseTabModel::TRANSITION_RELOAD, kURLFoo, std::string(), kTestLabel2}, }; std::vector<std::string> app_package_names, domain_regexes, labels; - SessionID::id_type tab_id = 1; app_package_names.push_back(kPackageFoo); domain_regexes.push_back(std::string()); @@ -667,7 +668,9 @@ RegisterURLRegexes(app_package_names, domain_regexes, labels); + int num_tabs = 0; for (const auto& test : all_enter_transition_tests) { + SessionID tab_id = SessionID::NewUnique(); EXPECT_FALSE(IsTrackingDataUse(tab_id)); ExpectEmptyTrackingInfo(tab_id); @@ -692,11 +695,9 @@ tab_id, DataUseTabModel::TRANSITION_OMNIBOX_NAVIGATION, GURL(kURLBar), navigation_entry_bar.get())); } - ExpectTabEntrySize(tab_id); + ExpectTabEntrySize(++num_tabs); EXPECT_EQ(test.transition == DataUseTabModel::TRANSITION_CUSTOM_TAB, IsCustomTabPackageMatch(tab_id)); - - ++tab_id; } } @@ -712,7 +713,6 @@ {DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, kURLFooBar}, }; std::vector<std::string> app_package_names, domain_regexes, labels; - SessionID::id_type tab_id = 1; app_package_names.push_back(std::string()); domain_regexes.push_back(kURLFoo); @@ -720,7 +720,9 @@ RegisterURLRegexes(app_package_names, domain_regexes, labels); + int num_tabs = 0; for (const auto& test : all_exit_transition_tests) { + SessionID tab_id = SessionID::NewUnique(); EXPECT_FALSE(IsTrackingDataUse(tab_id)); auto navigation_entry = CreateNavigationEntry(kURLFoo); data_use_tab_model_->OnNavigationEvent( @@ -741,8 +743,7 @@ ExpectDataUseLabelInNavigationEntry(*navigation_entry, std::string()); EXPECT_FALSE(IsTrackingDataUse(tab_id)); - ExpectTabEntrySize(tab_id); - ++tab_id; + ExpectTabEntrySize(++num_tabs); } } @@ -753,7 +754,6 @@ DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, DataUseTabModel::TRANSITION_OMNIBOX_NAVIGATION}; std::vector<std::string> app_package_names, domain_regexes, labels; - SessionID::id_type tab_id = 1; app_package_names.push_back(std::string()); domain_regexes.push_back(kURLFoo); @@ -761,7 +761,9 @@ RegisterURLRegexes(app_package_names, domain_regexes, labels); + int num_tabs = 0; for (const auto& transition : all_test_transitions) { + SessionID tab_id = SessionID::NewUnique(); EXPECT_FALSE(IsTrackingDataUse(tab_id)); auto navigation_entry = CreateNavigationEntry(kURLFoo); data_use_tab_model_->OnNavigationEvent(tab_id, transition, GURL(kURLFoo), @@ -793,8 +795,7 @@ tab_id, transition, GURL(), std::string(), navigation_entry.get()); EXPECT_FALSE(IsTrackingDataUse(tab_id)); - ExpectTabEntrySize(tab_id); - ++tab_id; + ExpectTabEntrySize(++num_tabs); } }
diff --git a/chrome/browser/android/data_usage/data_use_tab_ui_manager_android.cc b/chrome/browser/android/data_usage/data_use_tab_ui_manager_android.cc index b7ed836..8c828b7 100644 --- a/chrome/browser/android/data_usage/data_use_tab_ui_manager_android.cc +++ b/chrome/browser/android/data_usage/data_use_tab_ui_manager_android.cc
@@ -69,7 +69,8 @@ const JavaParamRef<jclass>& clazz, jint tab_id, const JavaParamRef<jobject>& jprofile) { - DCHECK_LE(0, static_cast<SessionID::id_type>(tab_id)); + SessionID casted_tab_id = SessionID::FromSerializedValue(tab_id); + DCHECK(casted_tab_id.is_valid()); Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile); android::DataUseUITabModel* data_use_ui_tab_model = @@ -78,7 +79,7 @@ return false; return data_use_ui_tab_model->CheckAndResetDataUseTrackingStarted( - static_cast<SessionID::id_type>(tab_id)); + casted_tab_id); } // static @@ -87,7 +88,8 @@ const JavaParamRef<jclass>& clazz, jint tab_id, const JavaParamRef<jobject>& jprofile) { - DCHECK_LE(0, static_cast<SessionID::id_type>(tab_id)); + SessionID casted_tab_id = SessionID::FromSerializedValue(tab_id); + DCHECK(casted_tab_id.is_valid()); Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile); android::DataUseUITabModel* data_use_ui_tab_model = @@ -96,7 +98,7 @@ return false; return data_use_ui_tab_model->CheckAndResetDataUseTrackingEnded( - static_cast<SessionID::id_type>(tab_id)); + casted_tab_id); } // static @@ -105,7 +107,8 @@ const JavaParamRef<jclass>& clazz, jint tab_id, const JavaParamRef<jobject>& jprofile) { - DCHECK_LE(0, static_cast<SessionID::id_type>(tab_id)); + SessionID casted_tab_id = SessionID::FromSerializedValue(tab_id); + DCHECK(casted_tab_id.is_valid()); Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile); android::DataUseUITabModel* data_use_ui_tab_model = @@ -113,8 +116,7 @@ if (!data_use_ui_tab_model) return; - data_use_ui_tab_model->UserClickedContinueOnDialogBox( - static_cast<SessionID::id_type>(tab_id)); + data_use_ui_tab_model->UserClickedContinueOnDialogBox(casted_tab_id); } // static @@ -126,7 +128,8 @@ const JavaParamRef<jstring>& url, jint transition_type, const JavaParamRef<jobject>& jprofile) { - DCHECK_LE(0, static_cast<SessionID::id_type>(tab_id)); + SessionID casted_tab_id = SessionID::FromSerializedValue(tab_id); + DCHECK(casted_tab_id.is_valid()); content::WebContents* web_contents = content::WebContents::FromJavaWebContents(j_web_contents); DCHECK(web_contents); @@ -138,8 +141,7 @@ return false; return data_use_ui_tab_model->WouldDataUseTrackingEnd( - ConvertJavaStringToUTF8(env, url), transition_type, - static_cast<SessionID::id_type>(tab_id), + ConvertJavaStringToUTF8(env, url), transition_type, casted_tab_id, web_contents->GetController().GetPendingEntry()); } @@ -151,7 +153,8 @@ const JavaParamRef<jstring>& jpackage_name, const JavaParamRef<jstring>& jurl, const JavaParamRef<jobject>& jprofile) { - DCHECK_LE(0, static_cast<SessionID::id_type>(tab_id)); + SessionID casted_tab_id = SessionID::FromSerializedValue(tab_id); + DCHECK(casted_tab_id.is_valid()); Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile); android::DataUseUITabModel* data_use_ui_tab_model = @@ -167,8 +170,8 @@ if (!jpackage_name.is_null()) ConvertJavaStringToUTF8(env, jpackage_name, &package_name); - data_use_ui_tab_model->ReportCustomTabInitialNavigation( - static_cast<SessionID::id_type>(tab_id), package_name, url); + data_use_ui_tab_model->ReportCustomTabInitialNavigation(casted_tab_id, + package_name, url); } // static
diff --git a/chrome/browser/android/data_usage/data_use_ui_tab_model.cc b/chrome/browser/android/data_usage/data_use_ui_tab_model.cc index 546797d..2f173af 100644 --- a/chrome/browser/android/data_usage/data_use_ui_tab_model.cc +++ b/chrome/browser/android/data_usage/data_use_ui_tab_model.cc
@@ -21,6 +21,21 @@ namespace android { +DataUseUITabModel::DataUseUINavigationEvent::DataUseUINavigationEvent( + SessionID tab_id, + DataUseTabModel::TransitionType transition_type, + GURL url, + std::string package) + : tab_id(tab_id), + transition_type(transition_type), + url(url), + package(package) {} + +DataUseUITabModel::DataUseUINavigationEvent::DataUseUINavigationEvent( + const DataUseUINavigationEvent&) = default; + +DataUseUITabModel::DataUseUINavigationEvent::~DataUseUINavigationEvent() {} + DataUseUITabModel::DataUseUITabModel() : data_use_ui_navigations_(new std::vector<DataUseUINavigationEvent>()), weak_factory_(this) { @@ -37,10 +52,10 @@ void DataUseUITabModel::ReportBrowserNavigation( const GURL& gurl, ui::PageTransition page_transition, - SessionID::id_type tab_id, + SessionID tab_id, content::NavigationEntry* navigation_entry) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_LE(0, tab_id); + DCHECK(tab_id.is_valid()); DCHECK_EQ(navigation_entry->GetURL(), gurl); DataUseTabModel::TransitionType transition_type; @@ -59,9 +74,9 @@ } } -void DataUseUITabModel::ReportTabClosure(SessionID::id_type tab_id) { +void DataUseUITabModel::ReportTabClosure(SessionID tab_id) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK_LE(0, tab_id); + DCHECK(tab_id.is_valid()); if (data_use_tab_model_) data_use_tab_model_->OnTabCloseEvent(tab_id); @@ -73,12 +88,12 @@ } void DataUseUITabModel::ReportCustomTabInitialNavigation( - SessionID::id_type tab_id, + SessionID tab_id, const std::string& package_name, const std::string& url) { DCHECK(thread_checker_.CalledOnValidThread()); - if (tab_id <= 0) + if (!tab_id.is_valid()) return; if (data_use_ui_navigations_) { @@ -116,7 +131,7 @@ return weak_factory_.GetWeakPtr(); } -void DataUseUITabModel::NotifyTrackingStarting(SessionID::id_type tab_id) { +void DataUseUITabModel::NotifyTrackingStarting(SessionID tab_id) { DCHECK(thread_checker_.CalledOnValidThread()); // Do not show tracking started UI for custom tabs with package match. @@ -135,7 +150,7 @@ RemoveTabEvent(tab_id, DATA_USE_TRACKING_ENDED); } -void DataUseUITabModel::NotifyTrackingEnding(SessionID::id_type tab_id) { +void DataUseUITabModel::NotifyTrackingEnding(SessionID tab_id) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!data_use_tab_model_->IsCustomTabPackageMatch(tab_id)); @@ -154,8 +169,7 @@ RemoveTabEvent(tab_id, DATA_USE_CONTINUE_CLICKED); } -bool DataUseUITabModel::CheckAndResetDataUseTrackingStarted( - SessionID::id_type tab_id) { +bool DataUseUITabModel::CheckAndResetDataUseTrackingStarted(SessionID tab_id) { DCHECK(thread_checker_.CalledOnValidThread()); TabEvents::iterator it = tab_events_.find(tab_id); @@ -168,7 +182,7 @@ bool DataUseUITabModel::WouldDataUseTrackingEnd( const std::string& url, int page_transition, - SessionID::id_type tab_id, + SessionID tab_id, const content::NavigationEntry* navigation_entry) const { DCHECK(thread_checker_.CalledOnValidThread()); @@ -199,8 +213,7 @@ tab_id, transition_type, GURL(url), navigation_entry); } -void DataUseUITabModel::UserClickedContinueOnDialogBox( - SessionID::id_type tab_id) { +void DataUseUITabModel::UserClickedContinueOnDialogBox(SessionID tab_id) { DCHECK(thread_checker_.CalledOnValidThread()); TabEvents::iterator it = tab_events_.find(tab_id); @@ -210,8 +223,7 @@ MaybeCreateTabEvent(tab_id, DATA_USE_CONTINUE_CLICKED); } -bool DataUseUITabModel::CheckAndResetDataUseTrackingEnded( - SessionID::id_type tab_id) { +bool DataUseUITabModel::CheckAndResetDataUseTrackingEnded(SessionID tab_id) { DCHECK(thread_checker_.CalledOnValidThread()); TabEvents::iterator it = tab_events_.find(tab_id); @@ -221,13 +233,13 @@ return RemoveTabEvent(tab_id, DATA_USE_TRACKING_ENDED); } -bool DataUseUITabModel::MaybeCreateTabEvent(SessionID::id_type tab_id, +bool DataUseUITabModel::MaybeCreateTabEvent(SessionID tab_id, DataUseTrackingEvent event) { DCHECK(thread_checker_.CalledOnValidThread()); return tab_events_.insert(std::make_pair(tab_id, event)).second; } -bool DataUseUITabModel::RemoveTabEvent(SessionID::id_type tab_id, +bool DataUseUITabModel::RemoveTabEvent(SessionID tab_id, DataUseTrackingEvent event) { DCHECK(thread_checker_.CalledOnValidThread()); TabEvents::iterator it = tab_events_.find(tab_id); @@ -309,7 +321,7 @@ } void DataUseUITabModel::BufferNavigationEvent( - SessionID::id_type tab_id, + SessionID tab_id, DataUseTabModel::TransitionType transition, const GURL& url, const std::string& package) {
diff --git a/chrome/browser/android/data_usage/data_use_ui_tab_model.h b/chrome/browser/android/data_usage/data_use_ui_tab_model.h index a4e11ce..4d1c1ef9 100644 --- a/chrome/browser/android/data_usage/data_use_ui_tab_model.h +++ b/chrome/browser/android/data_usage/data_use_ui_tab_model.h
@@ -53,27 +53,27 @@ // back-forward navigation history, and should not be null. void ReportBrowserNavigation(const GURL& gurl, ui::PageTransition page_transition, - SessionID::id_type tab_id, + SessionID tab_id, content::NavigationEntry* navigation_entry); // Reports a tab closure for the tab with |tab_id| to the DataUseTabModel on // IO thread. The tab could either have been closed or evicted from the memory // by Android. - void ReportTabClosure(SessionID::id_type tab_id); + void ReportTabClosure(SessionID tab_id); // Reports a custom tab navigation to the DataUseTabModel on the IO thread. // Includes the |tab_id|, |url|, and |package_name| for the navigation. - void ReportCustomTabInitialNavigation(SessionID::id_type tab_id, + void ReportCustomTabInitialNavigation(SessionID tab_id, const std::string& package_name, const std::string& url); // Returns true if data use tracking has been started for the tab with id // |tab_id|. Calling this function resets the state of the tab. - bool CheckAndResetDataUseTrackingStarted(SessionID::id_type tab_id); + bool CheckAndResetDataUseTrackingStarted(SessionID tab_id); // Returns true if data use tracking has ended for the tab with id |tab_id|. // Calling this function resets the state of the tab. - bool CheckAndResetDataUseTrackingEnded(SessionID::id_type tab_id); + bool CheckAndResetDataUseTrackingEnded(SessionID tab_id); // Sets the pointer to DataUseTabModel. |data_use_tab_model| is owned by the // caller. @@ -88,14 +88,14 @@ bool WouldDataUseTrackingEnd( const std::string& url, int page_transition, - SessionID::id_type tab_id, + SessionID tab_id, const content::NavigationEntry* navigation_entry) const; // Notifies that user clicked "Continue" when the dialog box with data use // warning was shown. Includes the |tab_id| on which the warning was shown. // When the user clicks "Continue", additional UI warnings about exiting data // use tracking are not shown to the user. - void UserClickedContinueOnDialogBox(SessionID::id_type tab_id); + void UserClickedContinueOnDialogBox(SessionID tab_id); base::WeakPtr<DataUseUITabModel> GetWeakPtr(); @@ -119,37 +119,34 @@ // Contains the details of a single UI navigation event. struct DataUseUINavigationEvent { - DataUseUINavigationEvent(SessionID::id_type tab_id, + DataUseUINavigationEvent(SessionID tab_id, DataUseTabModel::TransitionType transition_type, GURL url, - std::string package) - : tab_id(tab_id), - transition_type(transition_type), - url(url), - package(package) {} + std::string package); + DataUseUINavigationEvent(const DataUseUINavigationEvent&); + ~DataUseUINavigationEvent(); - const SessionID::id_type tab_id; + const SessionID tab_id; const DataUseTabModel::TransitionType transition_type; const GURL url; const std::string package; }; - typedef std::map<SessionID::id_type, DataUseTrackingEvent> TabEvents; + typedef std::map<SessionID, DataUseTrackingEvent> TabEvents; // DataUseTabModel::TabDataUseObserver implementation: - void NotifyTrackingStarting(SessionID::id_type tab_id) override; - void NotifyTrackingEnding(SessionID::id_type tab_id) override; + void NotifyTrackingStarting(SessionID tab_id) override; + void NotifyTrackingEnding(SessionID tab_id) override; void OnDataUseTabModelReady() override; // Creates |event| for tab with id |tab_id| and value |event|, if there is no // existing entry for |tab_id|, and returns true. Otherwise, returns false // without modifying the entry. - bool MaybeCreateTabEvent(SessionID::id_type tab_id, - DataUseTrackingEvent event); + bool MaybeCreateTabEvent(SessionID tab_id, DataUseTrackingEvent event); // Removes event entry for |tab_id|, if the entry is equal to |event|, and // returns true. Otherwise, returns false without modifying the entry. - bool RemoveTabEvent(SessionID::id_type tab_id, DataUseTrackingEvent event); + bool RemoveTabEvent(SessionID tab_id, DataUseTrackingEvent event); // Converts |page_transition| to page with GURL |gurl| to // DataUseTabModel::TransitionType enum. Returns true if conversion was @@ -161,7 +158,7 @@ DataUseTabModel::TransitionType* transition_type) const; // Buffers the navigation event for later processing. - void BufferNavigationEvent(SessionID::id_type tab_id, + void BufferNavigationEvent(SessionID tab_id, DataUseTabModel::TransitionType transition, const GURL& url, const std::string& package);
diff --git a/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc b/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc index 1e06bc3..0676e384 100644 --- a/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc +++ b/chrome/browser/android/data_usage/data_use_ui_tab_model_unittest.cc
@@ -42,9 +42,9 @@ const char kFooLabel[] = "foo_label"; const char kFooPackage[] = "com.foo"; -const SessionID::id_type kTabIDFoo = 1; -const SessionID::id_type kTabIDBar = 2; -const SessionID::id_type kTabIDBaz = 3; +const SessionID kTabIDFoo = SessionID::FromSerializedValue(1); +const SessionID kTabIDBar = SessionID::FromSerializedValue(2); +const SessionID kTabIDBaz = SessionID::FromSerializedValue(3); const char kURLFoo[] = "https://www.foo.com/#q=abc"; const char kURLBar[] = "https://www.bar.com/#q=abc"; @@ -61,8 +61,8 @@ // Mock observer to track the calls to start and end tracking events. class MockTabDataUseObserver : public DataUseTabModel::TabDataUseObserver { public: - MOCK_METHOD1(NotifyTrackingStarting, void(SessionID::id_type tab_id)); - MOCK_METHOD1(NotifyTrackingEnding, void(SessionID::id_type tab_id)); + MOCK_METHOD1(NotifyTrackingStarting, void(SessionID tab_id)); + MOCK_METHOD1(NotifyTrackingEnding, void(SessionID tab_id)); MOCK_METHOD0(OnDataUseTabModelReady, void()); }; @@ -100,7 +100,7 @@ label); } - void ExpectDataUseTrackingInfo(SessionID::id_type tab_id, + void ExpectDataUseTrackingInfo(SessionID tab_id, const base::TimeTicks& at_time, const std::string& expected_label, const std::string& expected_tag) const { @@ -185,11 +185,9 @@ {ui::PageTransition::PAGE_TRANSITION_RELOAD, kFooLabel}, }; - SessionID::id_type foo_tab_id = 100; - for (size_t i = 0; i < arraysize(tests); ++i) { // Start a new tab. - ++foo_tab_id; + SessionID foo_tab_id = SessionID::FromSerializedValue(100 + i); auto navigation_entry = CreateNavigationEntry(kURLFoo); data_use_ui_tab_model()->ReportBrowserNavigation( GURL(kURLFoo), tests[i].transition_type, foo_tab_id, @@ -225,7 +223,7 @@ // Start a custom tab with matching package name and verify if tracking // started is not being set. - const SessionID::id_type bar_tab_id = foo_tab_id + 1; + const SessionID bar_tab_id = SessionID::FromSerializedValue(200); EXPECT_FALSE( data_use_ui_tab_model()->CheckAndResetDataUseTrackingStarted(bar_tab_id)); data_use_ui_tab_model()->ReportCustomTabInitialNavigation( @@ -245,9 +243,9 @@ TEST_F(DataUseUITabModelTest, EntranceExitState) { SetUpDataUseUITabModel(); - const SessionID::id_type kFooTabId = 1; - const SessionID::id_type kBarTabId = 2; - const SessionID::id_type kBazTabId = 3; + const SessionID kFooTabId = SessionID::FromSerializedValue(1); + const SessionID kBarTabId = SessionID::FromSerializedValue(2); + const SessionID kBazTabId = SessionID::FromSerializedValue(3); // CheckAndResetDataUseTrackingStarted should return true only once. data_use_tab_model()->NotifyObserversOfTrackingStarting(kFooTabId); @@ -322,8 +320,6 @@ TEST_F(DataUseUITabModelTest, EntranceExitStateForDialog) { SetUpDataUseUITabModel(); - const SessionID::id_type kFooTabId = 1; - std::vector<std::string> url_regexes; url_regexes.push_back( "http://www[.]foo[.]com/#q=.*|https://www[.]foo[.]com/#q=.*"); @@ -331,8 +327,6 @@ url_regexes, std::vector<std::string>(url_regexes.size(), kFooLabel)); - SessionID::id_type foo_tab_id = kFooTabId; - const struct { // True if a dialog box was shown to the user. It may not be shown if the // user has previously selected the option to opt out. @@ -344,7 +338,7 @@ for (size_t i = 0; i < arraysize(tests); ++i) { // Start a new tab. - ++foo_tab_id; + SessionID foo_tab_id = SessionID::FromSerializedValue(100 + i); auto navigation_entry_foo = CreateNavigationEntry(kURLFoo); data_use_ui_tab_model()->ReportBrowserNavigation( GURL(kURLFoo), ui::PAGE_TRANSITION_GENERATED, foo_tab_id,
diff --git a/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc b/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc index 67e2904..bca89fe 100644 --- a/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc +++ b/chrome/browser/android/data_usage/external_data_use_observer_unittest.cc
@@ -34,7 +34,7 @@ namespace { const char kDefaultLabel[] = "label"; -const SessionID::id_type kDefaultTabId = 0; +const SessionID kDefaultTabId = SessionID::FromSerializedValue(1); const char kDefaultURL[] = "http://www.google.com/#q=abc"; } // namespace
diff --git a/chrome/browser/android/data_usage/external_data_use_reporter.h b/chrome/browser/android/data_usage/external_data_use_reporter.h index cdc473c..53711b8 100644 --- a/chrome/browser/android/data_usage/external_data_use_reporter.h +++ b/chrome/browser/android/data_usage/external_data_use_reporter.h
@@ -39,9 +39,8 @@ // must only be accessed on UI thread. class ExternalDataUseReporter { public: - typedef base::Callback<bool(SessionID::id_type, - const base::TimeTicks, - DataUseTabModel::TrackingInfo*)> + typedef base::Callback< + bool(SessionID, const base::TimeTicks, DataUseTabModel::TrackingInfo*)> GetTrackingInfoCallback; typedef base::Callback<void(const std::string&,
diff --git a/chrome/browser/android/data_usage/external_data_use_reporter_unittest.cc b/chrome/browser/android/data_usage/external_data_use_reporter_unittest.cc index 5213765..9f6ba873 100644 --- a/chrome/browser/android/data_usage/external_data_use_reporter_unittest.cc +++ b/chrome/browser/android/data_usage/external_data_use_reporter_unittest.cc
@@ -41,7 +41,7 @@ "DataUsage.Perf.ReportSubmissionDuration"; const char kDefaultLabel[] = "label"; -const SessionID::id_type kDefaultTabId = 0; +const SessionID kDefaultTabId = SessionID::FromSerializedValue(1); const char kDefaultURL[] = "http://www.google.com/#q=abc"; const char kFooMccMnc[] = "foo_mccmnc"; @@ -312,8 +312,9 @@ kDefaultTabId, DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, GURL("http://www.foo.com/#q=abc"), std::string(), nullptr); + const SessionID kTabIdBar = SessionID::FromSerializedValue(2); data_use_tab_model()->OnNavigationEvent( - kDefaultTabId + 1, DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, + kTabIdBar, DataUseTabModel::TRANSITION_OMNIBOX_SEARCH, GURL("http://www.bar.com/#q=abc"), std::string(), nullptr); EXPECT_EQ(0U, external_data_use_reporter()->buffered_data_reports_.size()); @@ -328,7 +329,7 @@ // Check |kLabelBar| matching rule. data_usage::DataUse data_bar = default_data_use(); - data_bar.tab_id = kDefaultTabId + 1; + data_bar.tab_id = kTabIdBar; data_bar.url = GURL("http://www.bar.com/#q=abc"); data_bar.mcc_mnc = kBarMccMnc; OnDataUse(data_bar);
diff --git a/chrome/browser/android/foreign_session_helper.cc b/chrome/browser/android/foreign_session_helper.cc index 3ed8093..7a3c719 100644 --- a/chrome/browser/android/foreign_session_helper.cc +++ b/chrome/browser/android/foreign_session_helper.cc
@@ -246,26 +246,9 @@ ConvertUTF8ToJavaString(env, session.session_name), session.device_type, session.modified_time.ToJavaTime())); - const std::string group_name = - base::FieldTrialList::FindFullName("TabSyncByRecency"); - if (group_name == "Enabled") { - // Create a custom window with tabs from all windows included and ordered - // by recency (GetForeignSessionTabs will do ordering automatically). - std::vector<const sessions::SessionTab*> tabs; - open_tabs->GetForeignSessionTabs(session.session_tag, &tabs); - ScopedJavaLocalRef<jobject> last_pushed_window( - Java_ForeignSessionHelper_pushWindow( - env, last_pushed_session, session.modified_time.ToJavaTime(), 0)); - for (const sessions::SessionTab* tab : tabs) { - if (ShouldSkipTab(*tab)) - continue; - JNI_ForeignSessionHelper_CopyTabToJava(env, *tab, last_pushed_window); - } - } else { - // Push the full session, with tabs ordered by visual position. - JNI_ForeignSessionHelper_CopySessionToJava(env, session, - last_pushed_session); - } + // Push the full session, with tabs ordered by visual position. + JNI_ForeignSessionHelper_CopySessionToJava(env, session, + last_pushed_session); } return true;
diff --git a/chrome/browser/android/sessions/session_tab_helper_android.cc b/chrome/browser/android/sessions/session_tab_helper_android.cc index 6111044..03b79736 100644 --- a/chrome/browser/android/sessions/session_tab_helper_android.cc +++ b/chrome/browser/android/sessions/session_tab_helper_android.cc
@@ -17,5 +17,5 @@ content::WebContents* web_contents = content::WebContents::FromJavaWebContents(java_web_contents); CHECK(web_contents); - return SessionTabHelper::IdForTab(web_contents); + return SessionTabHelper::IdForTab(web_contents).id(); }
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc index 02fa6de..4818ce8 100644 --- a/chrome/browser/android/tab_android.cc +++ b/chrome/browser/android/tab_android.cc
@@ -266,8 +266,8 @@ env, weak_java_tab_.get(env), reinterpret_cast<intptr_t>(&predicate)); } -void TabAndroid::SetWindowSessionID(SessionID::id_type window_id) { - session_window_id_.set_id(window_id); +void TabAndroid::SetWindowSessionID(SessionID window_id) { + session_window_id_ = window_id; if (!web_contents()) return; @@ -415,7 +415,7 @@ AttachTabHelpers(web_contents_.get()); WebContentsObserver::Observe(web_contents_.get()); - SetWindowSessionID(session_window_id_.id()); + SetWindowSessionID(session_window_id_); session_tab_id_.set_id( SessionTabHelper::FromWebContents(web_contents())->session_id().id());
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h index c53cdbea..716c7a95 100644 --- a/chrome/browser/android/tab_android.h +++ b/chrome/browser/android/tab_android.h
@@ -120,7 +120,7 @@ void DeleteFrozenNavigationEntries( const WebContentsState::DeletionPredicate& predicate); - void SetWindowSessionID(SessionID::id_type window_id); + void SetWindowSessionID(SessionID window_id); void SetSyncId(int sync_id); void HandlePopupNavigation(NavigateParams* params);
diff --git a/chrome/browser/android/usb/web_usb_chooser_service_android.cc b/chrome/browser/android/usb/web_usb_chooser_service_android.cc index f38f1ab..539f47c8 100644 --- a/chrome/browser/android/usb/web_usb_chooser_service_android.cc +++ b/chrome/browser/android/usb/web_usb_chooser_service_android.cc
@@ -7,27 +7,23 @@ #include <utility> #include "chrome/browser/ui/android/usb_chooser_dialog_android.h" +#include "chrome/browser/usb/usb_chooser_controller.h" #include "content/public/browser/browser_thread.h" WebUsbChooserServiceAndroid::WebUsbChooserServiceAndroid( content::RenderFrameHost* render_frame_host) - : render_frame_host_(render_frame_host) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - DCHECK(render_frame_host_); -} + : WebUsbChooserService(render_frame_host) {} WebUsbChooserServiceAndroid::~WebUsbChooserServiceAndroid() {} -void WebUsbChooserServiceAndroid::GetPermission( - std::vector<device::mojom::UsbDeviceFilterPtr> device_filters, - GetPermissionCallback callback) { - usb_chooser_dialog_android_.push_back( - std::make_unique<UsbChooserDialogAndroid>( - std::move(device_filters), render_frame_host_, std::move(callback))); +void WebUsbChooserServiceAndroid::ShowChooser( + std::unique_ptr<UsbChooserController> controller) { + dialog_ = UsbChooserDialogAndroid::Create( + render_frame_host(), std::move(controller), + base::BindOnce(&WebUsbChooserServiceAndroid::OnDialogClosed, + base::Unretained(this))); } -void WebUsbChooserServiceAndroid::Bind( - mojo::InterfaceRequest<device::mojom::UsbChooserService> request) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - bindings_.AddBinding(this, std::move(request)); +void WebUsbChooserServiceAndroid::OnDialogClosed() { + dialog_.reset(); }
diff --git a/chrome/browser/android/usb/web_usb_chooser_service_android.h b/chrome/browser/android/usb/web_usb_chooser_service_android.h index 0d6ed26..00ab9f1 100644 --- a/chrome/browser/android/usb/web_usb_chooser_service_android.h +++ b/chrome/browser/android/usb/web_usb_chooser_service_android.h
@@ -9,38 +9,28 @@ #include <vector> #include "base/macros.h" -#include "device/usb/public/mojom/chooser_service.mojom.h" -#include "mojo/public/cpp/bindings/binding_set.h" -#include "mojo/public/cpp/bindings/interface_request.h" +#include "chrome/browser/usb/web_usb_chooser_service.h" +class UsbChooserController; class UsbChooserDialogAndroid; -namespace content { -class RenderFrameHost; -} - // Implementation of the public device::usb::ChooserService interface. // This interface can be used by a webpage to request permission from user // to access a certain device. -class WebUsbChooserServiceAndroid : public device::mojom::UsbChooserService { +class WebUsbChooserServiceAndroid : public WebUsbChooserService { public: explicit WebUsbChooserServiceAndroid( content::RenderFrameHost* render_frame_host); - ~WebUsbChooserServiceAndroid() override; - // device::usb::ChooserService: - void GetPermission( - std::vector<device::mojom::UsbDeviceFilterPtr> device_filters, - GetPermissionCallback callback) override; - - void Bind(mojo::InterfaceRequest<device::mojom::UsbChooserService> request); + // WebUsbChooserService implementation + void ShowChooser(std::unique_ptr<UsbChooserController> controller) override; private: - content::RenderFrameHost* const render_frame_host_; - mojo::BindingSet<device::mojom::UsbChooserService> bindings_; - std::vector<std::unique_ptr<UsbChooserDialogAndroid>> - usb_chooser_dialog_android_; + void OnDialogClosed(); + + // Only a single dialog can be shown at a time. + std::unique_ptr<UsbChooserDialogAndroid> dialog_; DISALLOW_COPY_AND_ASSIGN(WebUsbChooserServiceAndroid); };
diff --git a/chrome/browser/android/vr/vr_shell.cc b/chrome/browser/android/vr/vr_shell.cc index 72260bc..adbaaf413 100644 --- a/chrome/browser/android/vr/vr_shell.cc +++ b/chrome/browser/android/vr/vr_shell.cc
@@ -772,6 +772,13 @@ } } +void VrShell::RecordPresentationStartAction(PresentationStartAction action) { + SessionMetricsHelper* metrics_helper = + SessionMetricsHelper::FromWebContents(web_contents_); + if (metrics_helper) + metrics_helper->RecordPresentationStartAction(action); +} + void VrShell::ShowSoftInput(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, bool show) { @@ -832,6 +839,9 @@ Java_VrShellImpl_onNeedsKeyboardUpdate(env, j_vr_shell_); return; } + // kSearchEnginePromo should directly DOFF without showing a promo. So it + // should never be used from VR ui thread. + case UiUnsupportedMode::kSearchEnginePromo: case UiUnsupportedMode::kCount: NOTREACHED(); // Should never be used as a mode. return;
diff --git a/chrome/browser/android/vr/vr_shell.h b/chrome/browser/android/vr/vr_shell.h index 6e6c89c..0160747 100644 --- a/chrome/browser/android/vr/vr_shell.h +++ b/chrome/browser/android/vr/vr_shell.h
@@ -187,6 +187,7 @@ void ExitFullscreen(); void LogUnsupportedModeUserMetric(UiUnsupportedMode mode); void RecordVrStartAction(VrStartAction action); + void RecordPresentationStartAction(PresentationStartAction action); void OnUnsupportedMode(UiUnsupportedMode mode); void OnExitVrPromptResult(UiUnsupportedMode reason, ExitVrPromptChoice choice);
diff --git a/chrome/browser/android/vr/vr_shell_delegate.cc b/chrome/browser/android/vr/vr_shell_delegate.cc index a50d0ea7..6fa8055 100644 --- a/chrome/browser/android/vr/vr_shell_delegate.cc +++ b/chrome/browser/android/vr/vr_shell_delegate.cc
@@ -132,12 +132,21 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, jint start_action) { + VrStartAction action = static_cast<VrStartAction>(start_action); + + if (action == VrStartAction::kDeepLinkedApp) { + // If this is a deep linked app we expect a DisplayActivate to be coming + // down the pipeline shortly. + possible_presentation_start_action_ = + PresentationStartAction::kDeepLinkedApp; + } + if (!vr_shell_) { - pending_vr_start_action_ = static_cast<VrStartAction>(start_action); + pending_vr_start_action_ = action; return; } - vr_shell_->RecordVrStartAction(static_cast<VrStartAction>(start_action)); + vr_shell_->RecordVrStartAction(action); } void VrShellDelegate::OnPresentResult( @@ -149,6 +158,7 @@ bool success) { if (!success) { std::move(callback).Run(false, nullptr); + possible_presentation_start_action_ = base::nullopt; return; } @@ -163,6 +173,15 @@ return; } + // If possible_presentation_start_action_ is not set at this point, then this + // request present probably came from blink, and has already been reported + // from there. + if (possible_presentation_start_action_) { + vr_shell_->RecordPresentationStartAction( + *possible_presentation_start_action_); + possible_presentation_start_action_ = base::nullopt; + } + vr_shell_->ConnectPresentingService( std::move(submit_client), std::move(request), std::move(display_info), std::move(present_options)); @@ -174,6 +193,16 @@ const JavaParamRef<jobject>& obj) { device::GvrDevice* device = static_cast<device::GvrDevice*>(GetDevice()); if (device) { + if (!possible_presentation_start_action_ || + possible_presentation_start_action_ != + PresentationStartAction::kDeepLinkedApp) { + // The only possible sources for DisplayActivate are at the moment DLAs + // and HeadsetActivations. Therefore if it's not a DLA it must be a + // HeadsetActivation. + possible_presentation_start_action_ = + PresentationStartAction::kHeadsetActivation; + } + device->Activate( device::mojom::VRDisplayEventReason::MOUNTED, base::BindRepeating(&VrShellDelegate::OnActivateDisplayHandled, @@ -268,6 +297,8 @@ // WebVR page didn't request presentation in the vrdisplayactivate handler. // Tell VrShell that we are in VR Browsing Mode. ExitWebVRPresent(); + // Reset possible_presentation_start_action_ as it may have been set. + possible_presentation_start_action_ = base::nullopt; } }
diff --git a/chrome/browser/android/vr/vr_shell_delegate.h b/chrome/browser/android/vr/vr_shell_delegate.h index e396ecd..914d322 100644 --- a/chrome/browser/android/vr/vr_shell_delegate.h +++ b/chrome/browser/android/vr/vr_shell_delegate.h
@@ -99,6 +99,7 @@ base::OnceCallback<void(bool)> on_present_result_callback_; bool pending_successful_present_request_ = false; base::Optional<VrStartAction> pending_vr_start_action_; + base::Optional<PresentationStartAction> possible_presentation_start_action_; base::CancelableClosure clear_activate_task_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/chrome/browser/autocomplete/search_provider_unittest.cc b/chrome/browser/autocomplete/search_provider_unittest.cc index 64240b4f..c98d1eb 100644 --- a/chrome/browser/autocomplete/search_provider_unittest.cc +++ b/chrome/browser/autocomplete/search_provider_unittest.cc
@@ -3587,9 +3587,21 @@ // Inject a scored result, which will trigger answer retrieval. base::string16 query = base::ASCIIToUTF16("weather los angeles"); SearchSuggestionParser::SuggestResult suggest_result( - query, AutocompleteMatchType::SEARCH_HISTORY, 0, query, base::string16(), - base::string16(), base::string16(), base::string16(), nullptr, - std::string(), std::string(), false, 1200, false, false, query); + query, AutocompleteMatchType::SEARCH_HISTORY, + /*subtype_identifier=*/0, + /*match_contents=*/query, + /*match_contents_prefix=*/base::string16(), + /*annotation=*/base::string16(), + /*answer_contents=*/base::string16(), + /*answer_type=*/base::string16(), + /*answer=*/nullptr, + /*suggest_query_params=*/std::string(), + /*deletion_url=*/std::string(), + /*from_keyword_provider=*/false, + /*relevance=*/1200, + /*relevance_from_server=*/false, + /*should_prefetch=*/false, + /*input_text=*/query); QueryForInput(ASCIIToUTF16("weather l"), false, false); provider_->transformed_default_history_results_.push_back(suggest_result); answer = provider_->FindAnswersPrefetchData();
diff --git a/chrome/browser/browsing_data/counters/site_data_counting_helper.cc b/chrome/browser/browsing_data/counters/site_data_counting_helper.cc index dc77ed3..e08f007 100644 --- a/chrome/browser/browsing_data/counters/site_data_counting_helper.cc +++ b/chrome/browser/browsing_data/counters/site_data_counting_helper.cc
@@ -233,11 +233,11 @@ DCHECK(tasks_ > 0); for (const GURL& origin : origins) { if (BrowsingDataHelper::HasWebScheme(origin)) - unique_origins_.insert(origin); + unique_hosts_.insert(origin.host()); } if (--tasks_ > 0) return; base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(completion_callback_, unique_origins_.size())); + FROM_HERE, base::BindOnce(completion_callback_, unique_hosts_.size())); base::ThreadTaskRunnerHandle::Get()->DeleteSoon(FROM_HERE, this); }
diff --git a/chrome/browser/browsing_data/counters/site_data_counting_helper.h b/chrome/browser/browsing_data/counters/site_data_counting_helper.h index 22ebb8a5..604e066 100644 --- a/chrome/browser/browsing_data/counters/site_data_counting_helper.h +++ b/chrome/browser/browsing_data/counters/site_data_counting_helper.h
@@ -68,7 +68,7 @@ base::Time begin_; base::Callback<void(int)> completion_callback_; int tasks_; - std::set<GURL> unique_origins_; + std::set<std::string> unique_hosts_; scoped_refptr<BrowsingDataFlashLSOHelper> flash_lso_helper_; };
diff --git a/chrome/browser/browsing_data/counters/site_data_counting_helper_unittest.cc b/chrome/browser/browsing_data/counters/site_data_counting_helper_unittest.cc index 7d2593aa..e45d0539 100644 --- a/chrome/browser/browsing_data/counters/site_data_counting_helper_unittest.cc +++ b/chrome/browser/browsing_data/counters/site_data_counting_helper_unittest.cc
@@ -115,8 +115,8 @@ cookie_store->SetCanonicalCookieAsync( net::CanonicalCookie::CreateSanitizedCookie( url, "name", "A=1", url.host(), url.path(), time, base::Time(), - time, true, false, net::CookieSameSite::DEFAULT_MODE, - net::COOKIE_PRIORITY_DEFAULT), + time, url.SchemeIsCryptographic(), false, + net::CookieSameSite::DEFAULT_MODE, net::COOKIE_PRIORITY_DEFAULT), url.SchemeIsCryptographic(), true /*modify_http_only*/, base::BindOnce(&SiteDataCountingHelperTest::DoneOnIOThread, base::Unretained(this))); @@ -195,7 +195,7 @@ TEST_F(SiteDataCountingHelperTest, CookiesAndLocalStorage) { base::Time now = base::Time::Now(); - CreateCookies(now, {"https://example.com", "https://google.com"}); + CreateCookies(now, {"http://example.com", "https://google.com"}); CreateLocalStorage(now, {FILE_PATH_LITERAL("https_example.com_443.localstorage"), FILE_PATH_LITERAL("https_bing.com_443.localstorage")}); @@ -205,3 +205,15 @@ WaitForTasksOnIOThread(); DCHECK_EQ(3, GetResult()); } + +TEST_F(SiteDataCountingHelperTest, SameHostDifferentScheme) { + base::Time now = base::Time::Now(); + CreateCookies(now, {"http://google.com", "https://google.com"}); + CreateLocalStorage(now, + {FILE_PATH_LITERAL("https_google.com_443.localstorage"), + FILE_PATH_LITERAL("http_google.com_80.localstorage")}); + WaitForTasksOnIOThread(); + CountEntries(base::Time()); + WaitForTasksOnIOThread(); + DCHECK_EQ(1, GetResult()); +}
diff --git a/chrome/browser/chooser_controller/chooser_controller.cc b/chrome/browser/chooser_controller/chooser_controller.cc index a792688f..2694473 100644 --- a/chrome/browser/chooser_controller/chooser_controller.cc +++ b/chrome/browser/chooser_controller/chooser_controller.cc
@@ -9,11 +9,15 @@ #include "components/url_formatter/elide_url.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" -#include "extensions/browser/extension_registry.h" -#include "extensions/common/constants.h" +#include "extensions/buildflags/buildflags.h" #include "ui/base/l10n/l10n_util.h" #include "url/origin.h" +#if BUILDFLAG(ENABLE_EXTENSIONS) +#include "extensions/browser/extension_registry.h" +#include "extensions/common/constants.h" +#endif + namespace { base::string16 CreateTitle(content::RenderFrameHost* render_frame_host, @@ -21,6 +25,7 @@ int title_string_id_extension) { url::Origin origin = render_frame_host->GetLastCommittedOrigin(); +#if BUILDFLAG(ENABLE_EXTENSIONS) if (origin.scheme() == extensions::kExtensionScheme) { content::WebContents* web_contents = content::WebContents::FromRenderFrameHost(render_frame_host); @@ -37,6 +42,7 @@ } } } +#endif return l10n_util::GetStringFUTF16( title_string_id_origin,
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc index 3ba0472..f3fafb84 100644 --- a/chrome/browser/chrome_browser_main.cc +++ b/chrome/browser/chrome_browser_main.cc
@@ -715,7 +715,7 @@ #if !defined(OS_ANDROID) // A TaskRunner that defers tasks until the real task runner is up and running. // This is used during early initialization, before the real task runner has -// been created. DeferredTaskRunner has the following states. +// been created. DeferringTaskRunner has the following states. // // . kInstalled: the initial state. Tasks are added to |deferred_runner_|. In // this state this is installed as the active ThreadTaskRunnerHandle.
diff --git a/chrome/browser/chrome_content_browser_manifest_overlay.json b/chrome/browser/chrome_content_browser_manifest_overlay.json index fc235c55..d3e35e18 100644 --- a/chrome/browser/chrome_content_browser_manifest_overlay.json +++ b/chrome/browser/chrome_content_browser_manifest_overlay.json
@@ -51,7 +51,7 @@ "patch": [ "patch_file" ], "pdf_compositor": [ "compositor" ], "profile_import": [ "import" ], - "profiling": [ "profiling", "heap_profiler" ], + "heap_profiling": [ "profiling", "heap_profiler" ], "proxy_resolver": [ "factory" ], "preferences": [ "pref_client", "pref_control" ], "removable_storage_writer": [ "removable_storage_writer" ],
diff --git a/chrome/browser/chromeos/arc/arc_optin_uma.cc b/chrome/browser/chromeos/arc/arc_optin_uma.cc index 2f2138e..e4bf7795 100644 --- a/chrome/browser/chromeos/arc/arc_optin_uma.cc +++ b/chrome/browser/chromeos/arc/arc_optin_uma.cc
@@ -9,6 +9,7 @@ #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h" +#include "chrome/browser/profiles/profile.h" #include "components/arc/arc_util.h" namespace arc { @@ -18,11 +19,12 @@ // Adds a suffix to the name based on the account type. std::string GetHistogramName(const std::string& base_name, const Profile* profile) { + if (IsRobotAccountMode()) + return base_name + "RobotAccount"; + if (profile->IsChild()) + return base_name + "Child"; return base_name + - (IsRobotAccountMode() - ? "RobotAccount" - : (policy_util::IsAccountManaged(profile) ? "Managed" - : "Unmanaged")); + (policy_util::IsAccountManaged(profile) ? "Managed" : "Unmanaged"); } } // namespace
diff --git a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc index 445de5e..f62d473d0 100644 --- a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc +++ b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.cc
@@ -1881,6 +1881,31 @@ base::Bind(&OnRemoveServiceRecordError, repeating_callback)); } +template <typename... Args> +void ArcBluetoothBridge::AddAdvertisementTask( + base::OnceCallback<void(base::OnceCallback<void(Args...)>)> task, + base::OnceCallback<void(Args...)> callback) { + advertisement_task_queue_.emplace(base::BindOnce( + std::move(task), + base::BindOnce(&ArcBluetoothBridge::CompleteAdvertisementTask<Args...>, + weak_factory_.GetWeakPtr(), std::move(callback)))); + if (advertisement_task_queue_.size() != 1) + return; + // No task pending, run immediately. + std::move(advertisement_task_queue_.front()).Run(); +} + +template <typename... Args> +void ArcBluetoothBridge::CompleteAdvertisementTask( + base::OnceCallback<void(Args...)> callback, + Args... args) { + std::move(callback).Run(std::forward<Args>(args)...); + advertisement_task_queue_.pop(); // Current task is done. Pop it from queue. + if (advertisement_task_queue_.empty()) + return; + std::move(advertisement_task_queue_.front()).Run(); // Run next task. +} + bool ArcBluetoothBridge::GetAdvertisementHandle(int32_t* adv_handle) { for (int i = 0; i < kMaxAdvertisements; i++) { if (advertisements_.find(i) == advertisements_.end()) { @@ -1893,6 +1918,14 @@ void ArcBluetoothBridge::ReserveAdvertisementHandle( ReserveAdvertisementHandleCallback callback) { + AddAdvertisementTask( + base::BindOnce(&ArcBluetoothBridge::ReserveAdvertisementHandleImpl, + weak_factory_.GetWeakPtr()), + std::move(callback)); +} + +void ArcBluetoothBridge::ReserveAdvertisementHandleImpl( + ReserveAdvertisementHandleCallback callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Find an empty advertisement slot. @@ -1912,37 +1945,96 @@ std::move(callback).Run(mojom::BluetoothGattStatus::GATT_SUCCESS, adv_handle); } -void ArcBluetoothBridge::BroadcastAdvertisement( +void ArcBluetoothBridge::EnableAdvertisement( int32_t adv_handle, std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement, - BroadcastAdvertisementCallback callback) { + EnableAdvertisementCallback callback) { + AddAdvertisementTask( + base::BindOnce(&ArcBluetoothBridge::EnableAdvertisementImpl, + weak_factory_.GetWeakPtr(), adv_handle, + std::move(advertisement)), + std::move(callback)); +} + +void ArcBluetoothBridge::EnableAdvertisementImpl( + int32_t adv_handle, + std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement, + EnableAdvertisementCallback callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - if (advertisements_.find(adv_handle) == advertisements_.end()) { - std::move(callback).Run(mojom::BluetoothGattStatus::GATT_FAILURE); - return; - } - if (!advertisements_[adv_handle]) { - OnReadyToRegisterAdvertisement(std::move(callback), adv_handle, - std::move(advertisement)); - return; - } - - // TODO(crbug.com/730593): Remove AdaptCallbackForRepeating() by updating - // the callee interface. + // TODO(crbug.com/730593): Remove AdaptCallbackForRepeating() by + // updating the callee interface. auto repeating_callback = base::AdaptCallbackForRepeating(std::move(callback)); - advertisements_[adv_handle]->Unregister( + base::Callback<void(void)> done_callback = base::Bind(&ArcBluetoothBridge::OnReadyToRegisterAdvertisement, weak_factory_.GetWeakPtr(), repeating_callback, adv_handle, - base::Passed(std::move(advertisement))), + base::Passed(std::move(advertisement))); + base::Callback<void(BluetoothAdvertisement::ErrorCode)> error_callback = base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError, - weak_factory_.GetWeakPtr(), repeating_callback, adv_handle)); + weak_factory_.GetWeakPtr(), repeating_callback, adv_handle); + + auto it = advertisements_.find(adv_handle); + if (it == advertisements_.end()) { + repeating_callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); + return; + } + if (it->second == nullptr) { + done_callback.Run(); + return; + } + it->second->Unregister(done_callback, error_callback); +} + +void ArcBluetoothBridge::DisableAdvertisement( + int32_t adv_handle, + EnableAdvertisementCallback callback) { + AddAdvertisementTask( + base::BindOnce(&ArcBluetoothBridge::DisableAdvertisementImpl, + weak_factory_.GetWeakPtr(), adv_handle), + std::move(callback)); +} + +void ArcBluetoothBridge::DisableAdvertisementImpl( + int32_t adv_handle, + EnableAdvertisementCallback callback) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + + // TODO(crbug.com/730593): Remove AdaptCallbackForRepeating() by + // updating the callee interface. + auto repeating_callback = + base::AdaptCallbackForRepeating(std::move(callback)); + base::Callback<void(void)> done_callback = + base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementDone, + weak_factory_.GetWeakPtr(), repeating_callback, adv_handle); + base::Callback<void(BluetoothAdvertisement::ErrorCode)> error_callback = + base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementError, + weak_factory_.GetWeakPtr(), repeating_callback, adv_handle); + + auto it = advertisements_.find(adv_handle); + if (it == advertisements_.end()) { + repeating_callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); + return; + } + if (it->second == nullptr) { + done_callback.Run(); + return; + } + it->second->Unregister(done_callback, error_callback); } void ArcBluetoothBridge::ReleaseAdvertisementHandle( int32_t adv_handle, ReleaseAdvertisementHandleCallback callback) { + AddAdvertisementTask( + base::BindOnce(&ArcBluetoothBridge::ReleaseAdvertisementHandleImpl, + weak_factory_.GetWeakPtr(), adv_handle), + std::move(callback)); +} + +void ArcBluetoothBridge::ReleaseAdvertisementHandleImpl( + int32_t adv_handle, + ReleaseAdvertisementHandleCallback callback) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); if (advertisements_.find(adv_handle) == advertisements_.end()) { std::move(callback).Run(mojom::BluetoothGattStatus::GATT_FAILURE); @@ -1955,14 +2047,14 @@ return; } - // TODO(crbug.com/730593): Remove AdaptCallbackForRepeating() by updating - // the callee interface. + // TODO(crbug.com/730593): Remove AdaptCallbackForRepeating() by + // updating the callee interface. auto repeating_callback = base::AdaptCallbackForRepeating(std::move(callback)); advertisements_[adv_handle]->Unregister( - base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementDone, + base::Bind(&ArcBluetoothBridge::OnReleaseAdvertisementHandleDone, weak_factory_.GetWeakPtr(), repeating_callback, adv_handle), - base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementError, + base::Bind(&ArcBluetoothBridge::OnReleaseAdvertisementHandleError, weak_factory_.GetWeakPtr(), repeating_callback, adv_handle)); } @@ -2007,7 +2099,7 @@ ArcBluetoothBridge::GattStatusCallback callback, int32_t adv_handle) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - advertisements_.erase(adv_handle); + advertisements_[adv_handle] = nullptr; std::move(callback).Run(mojom::BluetoothGattStatus::GATT_SUCCESS); } @@ -2018,6 +2110,25 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); LOG(WARNING) << "Failed to unregister advertisement for handle " << adv_handle << ", error code = " << error_code; + advertisements_[adv_handle] = nullptr; + std::move(callback).Run(mojom::BluetoothGattStatus::GATT_FAILURE); +} + +void ArcBluetoothBridge::OnReleaseAdvertisementHandleDone( + ArcBluetoothBridge::GattStatusCallback callback, + int32_t adv_handle) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + advertisements_.erase(adv_handle); + std::move(callback).Run(mojom::BluetoothGattStatus::GATT_SUCCESS); +} + +void ArcBluetoothBridge::OnReleaseAdvertisementHandleError( + ArcBluetoothBridge::GattStatusCallback callback, + int32_t adv_handle, + BluetoothAdvertisement::ErrorCode error_code) { + DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); + LOG(WARNING) << "Failed to relase advertisement handle " << adv_handle + << ", error code = " << error_code; advertisements_.erase(adv_handle); std::move(callback).Run(mojom::BluetoothGattStatus::GATT_FAILURE); }
diff --git a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.h b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.h index 68508c3..d5ce371 100644 --- a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.h +++ b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge.h
@@ -301,15 +301,36 @@ // Set up or disable multiple advertising. void ReserveAdvertisementHandle( ReserveAdvertisementHandleCallback callback) override; - void BroadcastAdvertisement( + void EnableAdvertisement( int32_t adv_handle, std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement, - BroadcastAdvertisementCallback callback) override; + EnableAdvertisementCallback callback) override; + void DisableAdvertisement(int32_t adv_handle, + DisableAdvertisementCallback callback) override; void ReleaseAdvertisementHandle( int32_t adv_handle, ReleaseAdvertisementHandleCallback callback) override; private: + template <typename... Args> + void AddAdvertisementTask( + base::OnceCallback<void(base::OnceCallback<void(Args...)>)> task, + base::OnceCallback<void(Args...)> callback); + template <typename... Args> + void CompleteAdvertisementTask(base::OnceCallback<void(Args...)> callback, + Args... args); + void ReserveAdvertisementHandleImpl( + ReserveAdvertisementHandleCallback callback); + void EnableAdvertisementImpl( + int32_t adv_handle, + std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement, + EnableAdvertisementCallback callback); + void DisableAdvertisementImpl(int32_t adv_handle, + DisableAdvertisementCallback callback); + void ReleaseAdvertisementHandleImpl( + int32_t adv_handle, + ReleaseAdvertisementHandleCallback callback); + template <typename InstanceType, typename HostType> class ConnectionObserverImpl; @@ -466,16 +487,21 @@ GattStatusCallback callback, int32_t adv_handle, device::BluetoothAdvertisement::ErrorCode error_code); - // Both of the following are called after we've tried to unregister - // the advertisement for |adv_handle|. Either way, we will no - // longer be broadcasting this advertisement, so in either case, the - // handle can be released. void OnUnregisterAdvertisementDone(GattStatusCallback callback, int32_t adv_handle); void OnUnregisterAdvertisementError( GattStatusCallback callback, int32_t adv_handle, device::BluetoothAdvertisement::ErrorCode error_code); + // Both of the following are called after we've tried to release |adv_handle|. + // Either way, we will no longer be broadcasting this advertisement, so in + // either case, the handle can be released. + void OnReleaseAdvertisementHandleDone(GattStatusCallback callback, + int32_t adv_handle); + void OnReleaseAdvertisementHandleError( + GattStatusCallback callback, + int32_t adv_handle, + device::BluetoothAdvertisement::ErrorCode error_code); // Find the next free advertisement handle and put it in *adv_handle, // or return false if the advertisement map is full. bool GetAdvertisementHandle(int32_t* adv_handle); @@ -544,6 +570,7 @@ enum { kMaxAdvertisements = 1 }; std::map<int32_t, scoped_refptr<device::BluetoothAdvertisement>> advertisements_; + base::queue<base::OnceClosure> advertisement_task_queue_; THREAD_CHECKER(thread_checker_);
diff --git a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc index 67e54b15..fa7a896 100644 --- a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
@@ -127,11 +127,11 @@ return last_adv_handle_; } - mojom::BluetoothGattStatus BroadcastAdvertisement( + mojom::BluetoothGattStatus EnableAdvertisement( int adv_handle, std::unique_ptr<device::BluetoothAdvertisement::Data> data) { last_status_ = mojom::BluetoothGattStatus::GATT_REQUEST_NOT_SUPPORTED; - arc_bluetooth_bridge_->BroadcastAdvertisement( + arc_bluetooth_bridge_->EnableAdvertisement( adv_handle, std::move(data), base::BindOnce(&ArcBluetoothBridgeTest::StatusSetterCallback, base::Unretained(this))); @@ -142,6 +142,19 @@ return last_status_; } + mojom::BluetoothGattStatus DisableAdvertisement(int adv_handle) { + last_status_ = mojom::BluetoothGattStatus::GATT_REQUEST_NOT_SUPPORTED; + arc_bluetooth_bridge_->DisableAdvertisement( + adv_handle, + base::BindOnce(&ArcBluetoothBridgeTest::StatusSetterCallback, + base::Unretained(this))); + + base::RunLoop().RunUntilIdle(); + EXPECT_NE(mojom::BluetoothGattStatus::GATT_REQUEST_NOT_SUPPORTED, + last_status_); + return last_status_; + } + mojom::BluetoothGattStatus ReleaseAdvertisementHandle(int adv_handle) { last_status_ = mojom::BluetoothGattStatus::GATT_REQUEST_NOT_SUPPORTED; arc_bluetooth_bridge_->ReleaseAdvertisementHandle( @@ -331,10 +344,14 @@ auto adv_data = std::make_unique<device::BluetoothAdvertisement::Data>( device::BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST); mojom::BluetoothGattStatus status = - BroadcastAdvertisement(handle, std::move(adv_data)); + EnableAdvertisement(handle, std::move(adv_data)); EXPECT_EQ(mojom::BluetoothGattStatus::GATT_SUCCESS, status); EXPECT_EQ(1, NumActiveAdvertisements()); + status = DisableAdvertisement(handle); + EXPECT_EQ(mojom::BluetoothGattStatus::GATT_SUCCESS, status); + EXPECT_EQ(0, NumActiveAdvertisements()); + status = ReleaseAdvertisementHandle(handle); EXPECT_EQ(mojom::BluetoothGattStatus::GATT_SUCCESS, status); EXPECT_EQ(0, NumActiveAdvertisements());
diff --git a/chrome/browser/chromeos/dbus/chrome_component_updater_service_provider_delegate.cc b/chrome/browser/chromeos/dbus/chrome_component_updater_service_provider_delegate.cc index 8be6aa2..4a3ff6e 100644 --- a/chrome/browser/chromeos/dbus/chrome_component_updater_service_provider_delegate.cc +++ b/chrome/browser/chromeos/dbus/chrome_component_updater_service_provider_delegate.cc
@@ -26,6 +26,8 @@ case component_updater::CrOSComponentManager::Error:: COMPATIBILITY_CHECK_FAILED: return "COMPATIBILITY_CHECK_FAILED"; + case component_updater::CrOSComponentManager::Error::ERROR_MAX: + return "ERROR_MAX"; } return "Unknown error code"; }
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc index d606c99..1c0b365 100644 --- a/chrome/browser/chromeos/policy/active_directory_policy_manager.cc +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager.cc
@@ -14,10 +14,11 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "components/policy/core/common/cloud/cloud_external_data_manager.h" #include "components/policy/core/common/policy_bundle.h" -#include "components/policy/core/common/policy_types.h" +#include "components/policy/core/common/policy_namespace.h" #include "components/policy/policy_constants.h" #include "net/url_request/url_request_context_getter.h" +namespace policy { namespace { // Fetch policy every 90 minutes which matches the Windows default: @@ -29,35 +30,20 @@ std::move(callback).Run(error == authpolicy::ERROR_NONE); } +// Gets the AuthPolicy D-Bus interface. +chromeos::AuthPolicyClient* GetAuthPolicyClient() { + chromeos::DBusThreadManager* thread_manager = + chromeos::DBusThreadManager::Get(); + DCHECK(thread_manager); + chromeos::AuthPolicyClient* auth_policy_client = + thread_manager->GetAuthPolicyClient(); + DCHECK(auth_policy_client); + return auth_policy_client; +} + } // namespace -namespace policy { - -ActiveDirectoryPolicyManager::~ActiveDirectoryPolicyManager() {} - -// static -std::unique_ptr<ActiveDirectoryPolicyManager> -ActiveDirectoryPolicyManager::CreateForDevicePolicy( - std::unique_ptr<CloudPolicyStore> store) { - // Can't use MakeUnique<> because the constructor is private. - return base::WrapUnique(new ActiveDirectoryPolicyManager( - EmptyAccountId(), base::TimeDelta(), base::OnceClosure(), - std::move(store), nullptr /* external_data_manager */)); -} - -// static -std::unique_ptr<ActiveDirectoryPolicyManager> -ActiveDirectoryPolicyManager::CreateForUserPolicy( - const AccountId& account_id, - base::TimeDelta initial_policy_fetch_timeout, - base::OnceClosure exit_session, - std::unique_ptr<CloudPolicyStore> store, - std::unique_ptr<CloudExternalDataManager> external_data_manager) { - // Can't use MakeUnique<> because the constructor is private. - return base::WrapUnique(new ActiveDirectoryPolicyManager( - account_id, initial_policy_fetch_timeout, std::move(exit_session), - std::move(store), std::move(external_data_manager))); -} +ActiveDirectoryPolicyManager::~ActiveDirectoryPolicyManager() = default; void ActiveDirectoryPolicyManager::Init(SchemaRegistry* registry) { ConfigurationPolicyProvider::Init(registry); @@ -96,12 +82,8 @@ bool ActiveDirectoryPolicyManager::IsInitializationComplete( PolicyDomain domain) const { - if (waiting_for_initial_policy_fetch_) { - return false; - } - if (domain == POLICY_DOMAIN_CHROME) { + if (domain == POLICY_DOMAIN_CHROME) return store_->is_initialized(); - } return true; } @@ -133,36 +115,11 @@ } } -void ActiveDirectoryPolicyManager::ForceTimeoutForTest() { - DCHECK(initial_policy_timeout_.IsRunning()); - // Stop the timer to mimic what happens when a real timer fires, then invoke - // the timer callback directly. - initial_policy_timeout_.Stop(); - OnBlockingFetchTimeout(); -} - ActiveDirectoryPolicyManager::ActiveDirectoryPolicyManager( - const AccountId& account_id, - base::TimeDelta initial_policy_fetch_timeout, - base::OnceClosure exit_session, std::unique_ptr<CloudPolicyStore> store, std::unique_ptr<CloudExternalDataManager> external_data_manager) - : account_id_(account_id), - waiting_for_initial_policy_fetch_( - !initial_policy_fetch_timeout.is_zero()), - initial_policy_fetch_may_fail_(!initial_policy_fetch_timeout.is_max()), - exit_session_(std::move(exit_session)), - store_(std::move(store)), - external_data_manager_(std::move(external_data_manager)) { - // Delaying initialization complete is intended for user policy only. - DCHECK(account_id != EmptyAccountId() || !waiting_for_initial_policy_fetch_); - if (waiting_for_initial_policy_fetch_ && initial_policy_fetch_may_fail_) { - initial_policy_timeout_.Start( - FROM_HERE, initial_policy_fetch_timeout, - base::Bind(&ActiveDirectoryPolicyManager::OnBlockingFetchTimeout, - weak_ptr_factory_.GetWeakPtr())); - } -} + : store_(std::move(store)), + external_data_manager_(std::move(external_data_manager)) {} void ActiveDirectoryPolicyManager::PublishPolicy() { if (!store_->is_initialized()) { @@ -181,23 +138,6 @@ UpdatePolicy(std::move(bundle)); } -void ActiveDirectoryPolicyManager::DoPolicyFetch( - base::OnceCallback<void(bool success)> callback) { - chromeos::DBusThreadManager* thread_manager = - chromeos::DBusThreadManager::Get(); - DCHECK(thread_manager); - chromeos::AuthPolicyClient* auth_policy_client = - thread_manager->GetAuthPolicyClient(); - DCHECK(auth_policy_client); - if (account_id_ == EmptyAccountId()) { - auth_policy_client->RefreshDevicePolicy( - base::BindOnce(&RunRefreshCallback, std::move(callback))); - } else { - auth_policy_client->RefreshUserPolicy( - account_id_, base::BindOnce(&RunRefreshCallback, std::move(callback))); - } -} - void ActiveDirectoryPolicyManager::OnPolicyFetched(bool success) { fetch_ever_completed_ = true; if (success) { @@ -215,14 +155,54 @@ store_->Load(); } -void ActiveDirectoryPolicyManager::OnBlockingFetchTimeout() { - DCHECK(waiting_for_initial_policy_fetch_); - LOG(WARNING) << "Timed out while waiting for the policy fetch. " - << "The session will start with the cached policy."; - CancelWaitForInitialPolicy(false); +UserActiveDirectoryPolicyManager::UserActiveDirectoryPolicyManager( + const AccountId& account_id, + base::TimeDelta initial_policy_fetch_timeout, + base::OnceClosure exit_session, + std::unique_ptr<CloudPolicyStore> store, + std::unique_ptr<CloudExternalDataManager> external_data_manager) + : ActiveDirectoryPolicyManager(std::move(store), + std::move(external_data_manager)), + account_id_(account_id), + waiting_for_initial_policy_fetch_( + !initial_policy_fetch_timeout.is_zero()), + initial_policy_fetch_may_fail_(!initial_policy_fetch_timeout.is_max()), + exit_session_(std::move(exit_session)) { + // Delaying initialization complete is intended for user policy only. + if (waiting_for_initial_policy_fetch_ && initial_policy_fetch_may_fail_) { + initial_policy_timeout_.Start( + FROM_HERE, initial_policy_fetch_timeout, + base::Bind(&UserActiveDirectoryPolicyManager::OnBlockingFetchTimeout, + weak_ptr_factory_.GetWeakPtr())); + } } -void ActiveDirectoryPolicyManager::CancelWaitForInitialPolicy(bool success) { +UserActiveDirectoryPolicyManager::~UserActiveDirectoryPolicyManager() = default; + +bool UserActiveDirectoryPolicyManager::IsInitializationComplete( + PolicyDomain domain) const { + if (waiting_for_initial_policy_fetch_) + return false; + + return ActiveDirectoryPolicyManager::IsInitializationComplete(domain); +} + +void UserActiveDirectoryPolicyManager::ForceTimeoutForTesting() { + DCHECK(initial_policy_timeout_.IsRunning()); + // Stop the timer to mimic what happens when a real timer fires, then invoke + // the timer callback directly. + initial_policy_timeout_.Stop(); + OnBlockingFetchTimeout(); +} + +void UserActiveDirectoryPolicyManager::DoPolicyFetch( + PolicyScheduler::TaskCallback callback) { + GetAuthPolicyClient()->RefreshUserPolicy( + account_id_, base::BindOnce(&RunRefreshCallback, std::move(callback))); +} + +void UserActiveDirectoryPolicyManager::CancelWaitForInitialPolicy( + bool success) { if (!waiting_for_initial_policy_fetch_) return; @@ -231,7 +211,7 @@ // If the conditions to continue profile initialization are not met, the user // session is exited and initialization is not set as completed. // TODO(tnagel): Maybe add code to retry policy fetch? - if (!store_->has_policy()) { + if (!store()->has_policy()) { // If there's no policy at all (not even cached) the user session must not // continue. LOG(ERROR) << "Policy could not be obtained. " @@ -260,4 +240,25 @@ PublishPolicy(); } +void UserActiveDirectoryPolicyManager::OnBlockingFetchTimeout() { + DCHECK(waiting_for_initial_policy_fetch_); + LOG(WARNING) << "Timed out while waiting for the policy fetch. " + << "The session will start with the cached policy."; + CancelWaitForInitialPolicy(false /* success */); +} + +DeviceActiveDirectoryPolicyManager::DeviceActiveDirectoryPolicyManager( + std::unique_ptr<CloudPolicyStore> store) + : ActiveDirectoryPolicyManager(std::move(store), + nullptr /* external_data_manager */) {} + +DeviceActiveDirectoryPolicyManager::~DeviceActiveDirectoryPolicyManager() = + default; + +void DeviceActiveDirectoryPolicyManager::DoPolicyFetch( + base::OnceCallback<void(bool success)> callback) { + GetAuthPolicyClient()->RefreshDevicePolicy( + base::BindOnce(&RunRefreshCallback, std::move(callback))); +} + } // namespace policy
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager.h b/chrome/browser/chromeos/policy/active_directory_policy_manager.h index ebcf0cd..135868a 100644 --- a/chrome/browser/chromeos/policy/active_directory_policy_manager.h +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager.h
@@ -21,9 +21,8 @@ class CloudExternalDataManager; -// ConfigurationPolicyProvider for device or user policy from Active Directory. -// The choice of constructor determines whether device or user policy is -// provided. +// ConfigurationPolicyProvider for policy from Active Directory. +// Derived classes implement specializations for user and device policy. // Data flow: Triggered by DoPolicyFetch(), policy is fetched by authpolicyd and // stored in session manager with completion indicated by OnPolicyFetched(). // From there policy load from session manager is triggered, completion of which @@ -33,18 +32,6 @@ public: ~ActiveDirectoryPolicyManager() override; - // Create manager for device policy. - static std::unique_ptr<ActiveDirectoryPolicyManager> CreateForDevicePolicy( - std::unique_ptr<CloudPolicyStore> store); - - // Create manager for |accound_id| user policy. - static std::unique_ptr<ActiveDirectoryPolicyManager> CreateForUserPolicy( - const AccountId& account_id, - base::TimeDelta initial_policy_fetch_timeout, - base::OnceClosure exit_session, - std::unique_ptr<CloudPolicyStore> store, - std::unique_ptr<CloudExternalDataManager> external_data_manager); - // ConfigurationPolicyProvider: void Init(SchemaRegistry* registry) override; void Shutdown() override; @@ -56,28 +43,13 @@ void OnStoreError(CloudPolicyStore* cloud_policy_store) override; CloudPolicyStore* store() const { return store_.get(); } + CloudExternalDataManager* external_data_manager() const { + return external_data_manager_.get(); + } PolicyScheduler* scheduler() { return scheduler_.get(); } - // Helper function to force a policy fetch timeout. - void ForceTimeoutForTest(); - - private: - // |account_id| specifies the user to manage policy for. If |account_id| is - // empty, device policy is managed. - // - // The following applies to user policy only: If - // |initial_policy_fetch_timeout| is non-zero, IsInitializationComplete() is - // forced to false until either there has been a successful policy fetch from - // the server and a subsequent successful load from session manager or - // |initial_policy_fetch_timeout| has expired and there has been a successful - // load from session manager. The timeout may be set to TimeDelta::Max() to - // enforce successful policy fetch. In case the conditions for signaling - // initialization complete are not met, the user session is aborted by calling - // |exit_session|. + protected: ActiveDirectoryPolicyManager( - const AccountId& account_id, - base::TimeDelta initial_policy_fetch_timeout, - base::OnceClosure exit_session, std::unique_ptr<CloudPolicyStore> store, std::unique_ptr<CloudExternalDataManager> external_data_manager); @@ -86,48 +58,27 @@ // Calls into authpolicyd to fetch policy. Reports success or failure via // |callback|. - void DoPolicyFetch(PolicyScheduler::TaskCallback callback); + virtual void DoPolicyFetch(PolicyScheduler::TaskCallback callback) = 0; + // Allows derived classes to cancel waiting for the initial policy fetch/load + // and to flag the ConfigurationPolicyProvider ready (assuming all other + // initialization tasks have completed) or to exit the session in case the + // requirements to continue have not been met. |success| denotes whether the + // policy fetch was successful. + virtual void CancelWaitForInitialPolicy(bool success) {} + + private: // Called by scheduler with result of policy fetch. This covers policy // download, parsing and storing into session manager. (To access and publish // the policy, the store needs to be reloaded from session manager.) void OnPolicyFetched(bool success); - // Called when |initial_policy_timeout_| times out, to cancel the blocking - // wait for the initial policy fetch. - void OnBlockingFetchTimeout(); - - // Cancels waiting for the initial policy fetch/load and flags the - // ConfigurationPolicyProvider ready (assuming all other initialization tasks - // have completed) or exits the session in case the requirements to continue - // have not been met. |success| denotes whether the policy fetch was - // successful. - void CancelWaitForInitialPolicy(bool success); - - const AccountId account_id_; - - // Whether we're waiting for a policy fetch to complete before reporting - // IsInitializationComplete(). - bool waiting_for_initial_policy_fetch_; - - // Whether the user session is continued in case of failure of initial policy - // fetch. - bool initial_policy_fetch_may_fail_; - // Whether policy fetch has ever been reported as completed by authpolicyd. bool fetch_ever_completed_ = false; // Whether policy fetch has ever been reported as successful by authpolicyd. bool fetch_ever_succeeded_ = false; - // A timer that puts a hard limit on the maximum time to wait for the initial - // policy fetch/load. - base::Timer initial_policy_timeout_{false /* retain_user_task */, - false /* is_repeating */}; - - // Callback to exit the session. - base::OnceClosure exit_session_; - // Store used to serialize policy, usually sends data to Session Manager. std::unique_ptr<CloudPolicyStore> store_; @@ -142,6 +93,82 @@ DISALLOW_COPY_AND_ASSIGN(ActiveDirectoryPolicyManager); }; +// Manages user policy for Active Directory managed devices. +class UserActiveDirectoryPolicyManager : public ActiveDirectoryPolicyManager { + public: + // If |initial_policy_fetch_timeout| is non-zero, IsInitializationComplete() + // is forced to false until either there has been a successful policy fetch + // from the server and a subsequent successful load from session manager or + // |initial_policy_fetch_timeout| has expired and there has been a successful + // load from session manager. The timeout may be set to TimeDelta::Max() to + // enforce successful policy fetch. In case the conditions for signaling + // initialization complete are not met, the user session is aborted by calling + // |exit_session|. + UserActiveDirectoryPolicyManager( + const AccountId& account_id, + base::TimeDelta initial_policy_fetch_timeout, + base::OnceClosure exit_session, + std::unique_ptr<CloudPolicyStore> store, + std::unique_ptr<CloudExternalDataManager> external_data_manager); + + ~UserActiveDirectoryPolicyManager() override; + + // ConfigurationPolicyProvider: + bool IsInitializationComplete(PolicyDomain domain) const override; + + // Helper function to force a policy fetch timeout. + void ForceTimeoutForTesting(); + + protected: + // ActiveDirectoryPolicyManager: + void DoPolicyFetch(PolicyScheduler::TaskCallback callback) override; + void CancelWaitForInitialPolicy(bool success) override; + + private: + // Called when |initial_policy_timeout_| times out, to cancel the blocking + // wait for the initial policy fetch. + void OnBlockingFetchTimeout(); + + // The user's account id. + AccountId account_id_; + + // Whether we're waiting for a policy fetch to complete before reporting + // IsInitializationComplete(). + bool waiting_for_initial_policy_fetch_ = false; + + // Whether the user session is continued in case of failure of initial policy + // fetch. + bool initial_policy_fetch_may_fail_ = false; + + // A timer that puts a hard limit on the maximum time to wait for the initial + // policy fetch/load. + base::Timer initial_policy_timeout_{false /* retain_user_task */, + false /* is_repeating */}; + + // Callback to exit the session. + base::OnceClosure exit_session_; + + // Must be last member. + base::WeakPtrFactory<UserActiveDirectoryPolicyManager> weak_ptr_factory_{ + this}; + + DISALLOW_COPY_AND_ASSIGN(UserActiveDirectoryPolicyManager); +}; + +// Manages device policy for Active Directory managed devices. +class DeviceActiveDirectoryPolicyManager : public ActiveDirectoryPolicyManager { + public: + DeviceActiveDirectoryPolicyManager(std::unique_ptr<CloudPolicyStore> store); + ~DeviceActiveDirectoryPolicyManager() override; + + protected: + // ActiveDirectoryPolicyManager: + void DoPolicyFetch(PolicyScheduler::TaskCallback callback) override; + + private: + DISALLOW_COPY_AND_ASSIGN(DeviceActiveDirectoryPolicyManager); +}; + } // namespace policy #endif // CHROME_BROWSER_CHROMEOS_POLICY_ACTIVE_DIRECTORY_POLICY_MANAGER_H_
diff --git a/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc b/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc index 53f0c21..7188d96 100644 --- a/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc +++ b/chrome/browser/chromeos/policy/active_directory_policy_manager_unittest.cc
@@ -87,70 +87,92 @@ // been fired. class ActiveDirectoryPolicyManagerTest : public testing::Test { public: - ActiveDirectoryPolicyManagerTest() { + ActiveDirectoryPolicyManagerTest() = default; + + // testing::Test overrides: + void SetUp() override { auto mock_client_unique_ptr = std::make_unique<TestAuthPolicyClient>(); mock_client_ = mock_client_unique_ptr.get(); chromeos::DBusThreadManager::GetSetterForTesting()->SetAuthPolicyClient( std::move(mock_client_unique_ptr)); } - ~ActiveDirectoryPolicyManagerTest() override { - EXPECT_EQ(session_exit_expected_, session_exited_); - if (mock_external_data_manager_) - EXPECT_CALL(*mock_external_data_manager_, Disconnect()); + void TearDown() override { + if (mock_external_data_manager()) + EXPECT_CALL(*mock_external_data_manager(), Disconnect()); policy_manager_->Shutdown(); } protected: - // Creates |mock_store_|, |mock_external_data_manager_| and |policy_manager_| - // with fake AD account id and |initial_policy_fetch_timeout| as timeout. - void CreateUserPolicyManager(base::TimeDelta initial_policy_fetch_timeout) { - auto account_id = AccountId::AdFromUserEmailObjGuid("bla", "ble"); - - auto mock_store_unique_ptr = std::make_unique<MockCloudPolicyStore>(); - mock_store_ = mock_store_unique_ptr.get(); - - auto mock_external_data_manager_unique_ptr = - std::make_unique<MockCloudExternalDataManager>(); - mock_external_data_manager_ = mock_external_data_manager_unique_ptr.get(); - - base::OnceClosure exit_session = base::BindOnce( - &ActiveDirectoryPolicyManagerTest::ExitSession, base::Unretained(this)); - - policy_manager_ = ActiveDirectoryPolicyManager::CreateForUserPolicy( - account_id, initial_policy_fetch_timeout, std::move(exit_session), - std::move(mock_store_unique_ptr), - std::move(mock_external_data_manager_unique_ptr)); - - ASSERT_TRUE(policy_manager_); - EXPECT_FALSE( - policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + // Gets the store passed to the policy manager during construction. + MockCloudPolicyStore* mock_store() { + DCHECK(policy_manager_); + return static_cast<MockCloudPolicyStore*>(policy_manager_->store()); } - // Creates |mock_store_| and |policy_manager_|. - void CreateDevicePolicyManager() { - auto mock_store_unique_ptr = std::make_unique<MockCloudPolicyStore>(); - mock_store_ = mock_store_unique_ptr.get(); - - policy_manager_ = ActiveDirectoryPolicyManager::CreateForDevicePolicy( - std::move(mock_store_unique_ptr)); - - ASSERT_TRUE(policy_manager_); - EXPECT_FALSE( - policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + // Gets the store passed to the policy manager during construction. + MockCloudExternalDataManager* mock_external_data_manager() { + DCHECK(policy_manager_); + return static_cast<MockCloudExternalDataManager*>( + policy_manager_->external_data_manager()); } // Initializes the policy manager and verifies expectations on mock classes. void InitPolicyManagerAndVerifyExpectations() { - EXPECT_CALL(*mock_store_, Load()); - if (mock_external_data_manager_) { - EXPECT_CALL(*mock_external_data_manager_, + EXPECT_CALL(*mock_store(), Load()); + if (mock_external_data_manager()) { + EXPECT_CALL(*mock_external_data_manager(), Connect(scoped_refptr<net::URLRequestContextGetter>())); } policy_manager_->Init(&schema_registry_); - testing::Mock::VerifyAndClearExpectations(mock_store_); - if (mock_external_data_manager_) - testing::Mock::VerifyAndClearExpectations(mock_external_data_manager_); + testing::Mock::VerifyAndClearExpectations(mock_store()); + if (mock_external_data_manager()) + testing::Mock::VerifyAndClearExpectations(mock_external_data_manager()); + } + + // Owned by DBusThreadManager. + TestAuthPolicyClient* mock_client_ = nullptr; + + // Initialized by the individual tests but owned by the test class so that it + // can be shut down automatically after the test has run. + std::unique_ptr<ActiveDirectoryPolicyManager> policy_manager_; + + SchemaRegistry schema_registry_; + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; + DISALLOW_COPY_AND_ASSIGN(ActiveDirectoryPolicyManagerTest); +}; + +class UserActiveDirectoryPolicyManagerTest + : public ActiveDirectoryPolicyManagerTest { + public: + ~UserActiveDirectoryPolicyManagerTest() override { + EXPECT_EQ(session_exit_expected_, session_exited_); + } + + protected: + UserActiveDirectoryPolicyManager* user_policy_manager() const { + return static_cast<UserActiveDirectoryPolicyManager*>( + policy_manager_.get()); + } + + // Creates |policy_manager_| with fake AD account id and + // |initial_policy_fetch_timeout| as timeout. + void CreatePolicyManager(base::TimeDelta initial_policy_fetch_timeout) { + auto account_id = AccountId::AdFromUserEmailObjGuid("bla", "ble"); + + base::OnceClosure exit_session = + base::BindOnce(&UserActiveDirectoryPolicyManagerTest::ExitSession, + base::Unretained(this)); + + policy_manager_ = std::make_unique<UserActiveDirectoryPolicyManager>( + account_id, initial_policy_fetch_timeout, std::move(exit_session), + std::make_unique<MockCloudPolicyStore>(), + std::make_unique<MockCloudExternalDataManager>()); + + EXPECT_FALSE( + policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); } // Expect that session exit will be called below. (Must only be called once.) @@ -175,26 +197,10 @@ bool session_exited_ = false; bool session_exit_expected_ = false; - - // Created by CreateUserPolicyManager(). - MockCloudPolicyStore* mock_store_ = nullptr; - MockCloudExternalDataManager* mock_external_data_manager_ = nullptr; - - // Owned by DBusThreadManager. - TestAuthPolicyClient* mock_client_ = nullptr; - - SchemaRegistry schema_registry_; - - // Initialized by the individual tests but owned by the test class so that it - // can be shut down automatically after the test has run. - std::unique_ptr<ActiveDirectoryPolicyManager> policy_manager_; - - private: - base::test::ScopedTaskEnvironment scoped_task_environment_; }; -TEST_F(ActiveDirectoryPolicyManagerTest, UserManager_DontWait) { - CreateUserPolicyManager(base::TimeDelta()); +TEST_F(UserActiveDirectoryPolicyManagerTest, DontWait) { + CreatePolicyManager(base::TimeDelta()); // Configure mock policy fetch to fail. mock_client_->SetRefreshUserPolicyCallbackError(authpolicy::ERROR_UNKNOWN); @@ -205,24 +211,24 @@ // Simulate failed store load. Initialization is reported complete at this // point. - mock_store_->NotifyStoreError(); + mock_store()->NotifyStoreError(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Process reply for mock policy fetch. - EXPECT_CALL(*mock_store_, Load()); + EXPECT_CALL(*mock_store(), Load()); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Simulate failed store load. - mock_store_->NotifyStoreError(); + mock_store()->NotifyStoreError(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); } // If the initial fetch timeout is infinite, initialization is only complete // after policy has been fetched and after that has been loaded. -TEST_F(ActiveDirectoryPolicyManagerTest, - UserManager_WaitInfinite_LoadSuccess_FetchSuccess) { - CreateUserPolicyManager(base::TimeDelta::Max()); +TEST_F(UserActiveDirectoryPolicyManagerTest, + WaitInfinite_LoadSuccess_FetchSuccess) { + CreatePolicyManager(base::TimeDelta::Max()); // Configure mock policy fetch to succeed. mock_client_->SetRefreshUserPolicyCallbackError(authpolicy::ERROR_NONE); @@ -231,25 +237,25 @@ InitPolicyManagerAndVerifyExpectations(); // Simulate successful store load. - mock_store_->policy_ = std::make_unique<enterprise_management::PolicyData>(); - mock_store_->NotifyStoreLoaded(); + mock_store()->policy_ = std::make_unique<enterprise_management::PolicyData>(); + mock_store()->NotifyStoreLoaded(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Process reply for mock policy fetch. - EXPECT_CALL(*mock_store_, Load()); + EXPECT_CALL(*mock_store(), Load()); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Simulate successful store load. At this point initialization is complete. - mock_store_->NotifyStoreLoaded(); + mock_store()->NotifyStoreLoaded(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); } // If the initial fetch timeout is infinite, initialization does not complete if // load after fetch fails. -TEST_F(ActiveDirectoryPolicyManagerTest, - UserManager_WaitInfinite_LoadSuccess_FetchSuccess_LoadFail) { - CreateUserPolicyManager(base::TimeDelta::Max()); +TEST_F(UserActiveDirectoryPolicyManagerTest, + WaitInfinite_LoadSuccess_FetchSuccess_LoadFail) { + CreatePolicyManager(base::TimeDelta::Max()); // Configure mock policy fetch to succeed. mock_client_->SetRefreshUserPolicyCallbackError(authpolicy::ERROR_NONE); @@ -258,33 +264,33 @@ InitPolicyManagerAndVerifyExpectations(); // Simulate successful store load. - mock_store_->policy_ = std::make_unique<enterprise_management::PolicyData>(); - mock_store_->NotifyStoreLoaded(); + mock_store()->policy_ = std::make_unique<enterprise_management::PolicyData>(); + mock_store()->NotifyStoreLoaded(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Process reply for mock policy fetch. - EXPECT_CALL(*mock_store_, Load()); + EXPECT_CALL(*mock_store(), Load()); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); ExpectSessionExit(); // Simulate failed store load. - mock_store_->NotifyStoreError(); + mock_store()->NotifyStoreError(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); ExpectSessionExited(); // Simulate successful store load. - mock_store_->NotifyStoreLoaded(); + mock_store()->NotifyStoreLoaded(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); } // If the initial fetch timeout is infinite, failure in policy fetch prevents // initialization from finishing, ever. -TEST_F(ActiveDirectoryPolicyManagerTest, - UserManager_WaitInfinite_LoadSuccess_FetchFail) { - CreateUserPolicyManager(base::TimeDelta::Max()); +TEST_F(UserActiveDirectoryPolicyManagerTest, + WaitInfinite_LoadSuccess_FetchFail) { + CreatePolicyManager(base::TimeDelta::Max()); // Configure mock policy fetch to fail. mock_client_->SetRefreshUserPolicyCallbackError(authpolicy::ERROR_UNKNOWN); @@ -293,30 +299,29 @@ InitPolicyManagerAndVerifyExpectations(); // Simulate successful store load. - mock_store_->policy_ = std::make_unique<enterprise_management::PolicyData>(); - mock_store_->NotifyStoreLoaded(); + mock_store()->policy_ = std::make_unique<enterprise_management::PolicyData>(); + mock_store()->NotifyStoreLoaded(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); ExpectSessionExit(); // Process reply for mock policy fetch. - EXPECT_CALL(*mock_store_, Load()); + EXPECT_CALL(*mock_store(), Load()); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); ExpectSessionExited(); // Simulate successful store load. - mock_store_->NotifyStoreLoaded(); + mock_store()->NotifyStoreLoaded(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); } // If the initial fetch timeout is not infinite, we're in best-effort mode but // still require the policy load to succeed so that there's *some* policy // present (though possibly outdated). -TEST_F(ActiveDirectoryPolicyManagerTest, - UserManager_WaitFinite_LoadSuccess_FetchFail) { - CreateUserPolicyManager(base::TimeDelta::FromDays(365)); +TEST_F(UserActiveDirectoryPolicyManagerTest, WaitFinite_LoadSuccess_FetchFail) { + CreatePolicyManager(base::TimeDelta::FromDays(365)); // Configure mock policy fetch to fail. mock_client_->SetRefreshUserPolicyCallbackError(authpolicy::ERROR_UNKNOWN); @@ -325,19 +330,19 @@ InitPolicyManagerAndVerifyExpectations(); // Simulate successful store load. - mock_store_->policy_ = std::make_unique<enterprise_management::PolicyData>(); - mock_store_->NotifyStoreLoaded(); + mock_store()->policy_ = std::make_unique<enterprise_management::PolicyData>(); + mock_store()->NotifyStoreLoaded(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Process reply for mock policy fetch. At this point initialization is // complete (we have waited for the fetch but now that we know it has failed // we continue). - EXPECT_CALL(*mock_store_, Load()); + EXPECT_CALL(*mock_store(), Load()); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Simulate successful store load. - mock_store_->NotifyStoreLoaded(); + mock_store()->NotifyStoreLoaded(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); } @@ -345,9 +350,8 @@ // still require the policy load to succeed so that there's *some* policy // present (though possibly outdated). Here the sequence is inverted: Fetch // returns before load. -TEST_F(ActiveDirectoryPolicyManagerTest, - UserManager_WaitFinite_FetchFail_LoadSuccess) { - CreateUserPolicyManager(base::TimeDelta::FromDays(365)); +TEST_F(UserActiveDirectoryPolicyManagerTest, WaitFinite_FetchFail_LoadSuccess) { + CreatePolicyManager(base::TimeDelta::FromDays(365)); // Configure mock policy fetch to fail. mock_client_->SetRefreshUserPolicyCallbackError(authpolicy::ERROR_UNKNOWN); @@ -356,21 +360,20 @@ InitPolicyManagerAndVerifyExpectations(); // Process reply for mock policy fetch. - EXPECT_CALL(*mock_store_, Load()); + EXPECT_CALL(*mock_store(), Load()); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Simulate successful store load. - mock_store_->policy_ = std::make_unique<enterprise_management::PolicyData>(); - mock_store_->NotifyStoreLoaded(); + mock_store()->policy_ = std::make_unique<enterprise_management::PolicyData>(); + mock_store()->NotifyStoreLoaded(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); } // If the initial fetch timeout is not infinite, we're in best-effort mode but // if we can't load existing policy from disk we have to give up. -TEST_F(ActiveDirectoryPolicyManagerTest, - UserManager_WaitFinite_LoadFail_FetchFail) { - CreateUserPolicyManager(base::TimeDelta::FromDays(365)); +TEST_F(UserActiveDirectoryPolicyManagerTest, WaitFinite_LoadFail_FetchFail) { + CreatePolicyManager(base::TimeDelta::FromDays(365)); // Configure mock policy fetch to fail. mock_client_->SetRefreshUserPolicyCallbackError(authpolicy::ERROR_UNKNOWN); @@ -379,30 +382,30 @@ InitPolicyManagerAndVerifyExpectations(); // Simulate failed store load. - mock_store_->NotifyStoreError(); + mock_store()->NotifyStoreError(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); ExpectSessionExit(); // Process reply for mock policy fetch. - EXPECT_CALL(*mock_store_, Load()); + EXPECT_CALL(*mock_store(), Load()); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); ExpectSessionExited(); // Simulate successful store load. - mock_store_->policy_ = std::make_unique<enterprise_management::PolicyData>(); - mock_store_->NotifyStoreLoaded(); + mock_store()->policy_ = std::make_unique<enterprise_management::PolicyData>(); + mock_store()->NotifyStoreLoaded(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); } // If the initial fetch timeout is not infinite, we're in best-effort mode and // upon timeout initialization is complete if any policy could be loaded from // disk. -TEST_F(ActiveDirectoryPolicyManagerTest, - UserManager_WaitFinite_LoadSuccess_FetchTimeout) { - CreateUserPolicyManager(base::TimeDelta::FromDays(365)); +TEST_F(UserActiveDirectoryPolicyManagerTest, + WaitFinite_LoadSuccess_FetchTimeout) { + CreatePolicyManager(base::TimeDelta::FromDays(365)); // Configure mock policy fetch to fail. mock_client_->SetRefreshUserPolicyCallbackError(authpolicy::ERROR_UNKNOWN); @@ -411,29 +414,29 @@ InitPolicyManagerAndVerifyExpectations(); // Simulate successful store load. - mock_store_->policy_ = std::make_unique<enterprise_management::PolicyData>(); - mock_store_->NotifyStoreLoaded(); + mock_store()->policy_ = std::make_unique<enterprise_management::PolicyData>(); + mock_store()->NotifyStoreLoaded(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Simulate policy fetch timeout. - policy_manager_->ForceTimeoutForTest(); + user_policy_manager()->ForceTimeoutForTesting(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Process reply for mock policy fetch. - EXPECT_CALL(*mock_store_, Load()); + EXPECT_CALL(*mock_store(), Load()); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Simulate failed store load. - mock_store_->NotifyStoreError(); + mock_store()->NotifyStoreError(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); } // If the initial fetch timeout is not infinite, we're in best-effort mode but // without a successful policy load we still can't continue. -TEST_F(ActiveDirectoryPolicyManagerTest, - UserManager_WaitFinite_LoadTimeout_FetchTimeout) { - CreateUserPolicyManager(base::TimeDelta::FromDays(365)); +TEST_F(UserActiveDirectoryPolicyManagerTest, + WaitFinite_LoadTimeout_FetchTimeout) { + CreatePolicyManager(base::TimeDelta::FromDays(365)); // Configure mock policy fetch to fail. mock_client_->SetRefreshUserPolicyCallbackError(authpolicy::ERROR_UNKNOWN); @@ -444,24 +447,37 @@ ExpectSessionExit(); // Simulate policy fetch timeout. - policy_manager_->ForceTimeoutForTest(); + user_policy_manager()->ForceTimeoutForTesting(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); ExpectSessionExited(); // Process reply for mock policy fetch. - EXPECT_CALL(*mock_store_, Load()); + EXPECT_CALL(*mock_store(), Load()); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); // Simulate successful store load. - mock_store_->policy_ = std::make_unique<enterprise_management::PolicyData>(); - mock_store_->NotifyStoreLoaded(); + mock_store()->policy_ = std::make_unique<enterprise_management::PolicyData>(); + mock_store()->NotifyStoreLoaded(); EXPECT_TRUE(policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); } -TEST_F(ActiveDirectoryPolicyManagerTest, DeviceManager_Initialization) { - CreateDevicePolicyManager(); +class DeviceActiveDirectoryPolicyManagerTest + : public ActiveDirectoryPolicyManagerTest { + protected: + // Creates |mock_store()| and |policy_manager_|. + void CreatePolicyManager() { + policy_manager_ = std::make_unique<DeviceActiveDirectoryPolicyManager>( + std::make_unique<MockCloudPolicyStore>()); + + EXPECT_FALSE( + policy_manager_->IsInitializationComplete(POLICY_DOMAIN_CHROME)); + } +}; + +TEST_F(DeviceActiveDirectoryPolicyManagerTest, Initialization) { + CreatePolicyManager(); InitPolicyManagerAndVerifyExpectations(); }
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc index 82419315..a7ac918a 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -120,9 +120,8 @@ ->StartAuthPolicyService(); device_active_directory_policy_manager_ = - ActiveDirectoryPolicyManager::CreateForDevicePolicy( - std::move(device_cloud_policy_store)) - .release(); + new DeviceActiveDirectoryPolicyManager( + std::move(device_cloud_policy_store)); providers_for_init_.push_back( base::WrapUnique<ConfigurationPolicyProvider>( device_active_directory_policy_manager_));
diff --git a/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc b/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc index 5888138c..27ad44e8 100644 --- a/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc +++ b/chrome/browser/chromeos/policy/user_policy_manager_factory_chromeos.cc
@@ -356,11 +356,10 @@ store->LoadImmediately(); if (is_active_directory) { - std::unique_ptr<ActiveDirectoryPolicyManager> manager = - ActiveDirectoryPolicyManager::CreateForUserPolicy( - account_id, policy_refresh_timeout, - base::BindOnce(&chrome::AttemptUserExit), std::move(store), - std::move(external_data_manager)); + auto manager = std::make_unique<UserActiveDirectoryPolicyManager>( + account_id, policy_refresh_timeout, + base::BindOnce(&chrome::AttemptUserExit), std::move(store), + std::move(external_data_manager)); manager->Init( SchemaRegistryServiceFactory::GetForContext(profile)->registry());
diff --git a/chrome/browser/component_updater/cros_component_installer.cc b/chrome/browser/component_updater/cros_component_installer.cc index adb838a..3da68e16 100644 --- a/chrome/browser/component_updater/cros_component_installer.cc +++ b/chrome/browser/component_updater/cros_component_installer.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/files/file_util.h" +#include "base/metrics/histogram_macros.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/task_scheduler/post_task.h" @@ -86,6 +87,13 @@ return configs; } +// Report Error code. +CrOSComponentManager::Error ReportError(CrOSComponentManager::Error error) { + UMA_HISTOGRAM_ENUMERATION("ComponentUpdater.ChromeOS.InstallResult", error, + CrOSComponentManager::Error::ERROR_MAX); + return error; +} + } // namespace CrOSComponentInstallerPolicy::CrOSComponentInstallerPolicy( @@ -202,8 +210,9 @@ LoadInternal(name, std::move(load_callback)); } else { // A compatible component is installed, do not load it. - base::PostTask(FROM_HERE, base::BindOnce(std::move(load_callback), - Error::NONE, base::FilePath())); + base::PostTask(FROM_HERE, + base::BindOnce(std::move(load_callback), + ReportError(Error::NONE), base::FilePath())); } } @@ -259,7 +268,8 @@ if (!config) { base::PostTask(FROM_HERE, base::BindOnce(std::move(load_callback), - Error::UNKNOWN_COMPONENT, base::FilePath())); + ReportError(Error::UNKNOWN_COMPONENT), + base::FilePath())); return; } Register( @@ -283,14 +293,16 @@ LoadCallback load_callback, update_client::Error error) { if (error != update_client::Error::NONE) { - base::PostTask(FROM_HERE, - base::BindOnce(std::move(load_callback), - Error::INSTALL_FAILURE, base::FilePath())); + base::PostTask( + FROM_HERE, + base::BindOnce(std::move(load_callback), + ReportError(Error::INSTALL_FAILURE), base::FilePath())); } else if (mount_policy == MountPolicy::kMount) { LoadInternal(name, std::move(load_callback)); } else { - base::PostTask(FROM_HERE, base::BindOnce(std::move(load_callback), - Error::NONE, base::FilePath())); + base::PostTask(FROM_HERE, + base::BindOnce(std::move(load_callback), + ReportError(Error::NONE), base::FilePath())); } } @@ -305,23 +317,31 @@ ->LoadComponentAtPath( name, path, base::BindOnce(&CrOSComponentManager::FinishLoad, - base::Unretained(this), std::move(load_callback))); + base::Unretained(this), std::move(load_callback), + base::TimeTicks::Now())); } else { - base::PostTask(FROM_HERE, base::BindOnce(std::move(load_callback), - Error::COMPATIBILITY_CHECK_FAILED, - base::FilePath())); + base::PostTask( + FROM_HERE, + base::BindOnce(std::move(load_callback), + ReportError(Error::COMPATIBILITY_CHECK_FAILED), + base::FilePath())); } } void CrOSComponentManager::FinishLoad(LoadCallback load_callback, + const base::TimeTicks start_time, base::Optional<base::FilePath> result) { + // Report component image mount time. + UMA_HISTOGRAM_LONG_TIMES("ComponentUpdater.ChromeOS.MountTime", + base::TimeTicks::Now() - start_time); if (!result.has_value()) { + base::PostTask(FROM_HERE, base::BindOnce(std::move(load_callback), + ReportError(Error::MOUNT_FAILURE), + base::FilePath())); + } else { base::PostTask(FROM_HERE, base::BindOnce(std::move(load_callback), - Error::MOUNT_FAILURE, base::FilePath())); - } else { - base::PostTask(FROM_HERE, base::BindOnce(std::move(load_callback), - Error::NONE, result.value())); + ReportError(Error::NONE), result.value())); } }
diff --git a/chrome/browser/component_updater/cros_component_installer.h b/chrome/browser/component_updater/cros_component_installer.h index 4c85b9c..c1ae1e1 100644 --- a/chrome/browser/component_updater/cros_component_installer.h +++ b/chrome/browser/component_updater/cros_component_installer.h
@@ -68,12 +68,15 @@ // This class contains functions used to register and install a component. class CrOSComponentManager { public: + // Error needs to be consistent with CrosComponentManagerError in + // src/tools/metrics/histograms/enums.xml. enum class Error { NONE = 0, UNKNOWN_COMPONENT = 1, // Component requested does not exist. INSTALL_FAILURE = 2, // update_client fails to install component. MOUNT_FAILURE = 3, // Component can not be mounted. COMPATIBILITY_CHECK_FAILED = 4, // Compatibility check failed. + ERROR_MAX }; using LoadCallback = base::OnceCallback<void(Error error, const base::FilePath&)>; @@ -146,6 +149,7 @@ // Calls load_callback and pass in the parameter |result| (component mount // point). void FinishLoad(LoadCallback load_callback, + const base::TimeTicks start_time, base::Optional<base::FilePath> result); // Registers component |configs| to be updated.
diff --git a/chrome/browser/conflicts/problematic_programs_updater_win.cc b/chrome/browser/conflicts/problematic_programs_updater_win.cc index 1d43888..81a76a24 100644 --- a/chrome/browser/conflicts/problematic_programs_updater_win.cc +++ b/chrome/browser/conflicts/problematic_programs_updater_win.cc
@@ -251,10 +251,14 @@ const ModuleInfoData& module_data) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // Only consider loaded modules. - // TODO(pmonette): Also consider blocked modules when that becomes possible. - if ((module_data.module_types & ModuleInfoData::kTypeLoadedModule) == 0) + // Only consider loaded modules that are not shell extensions or IMEs. + static constexpr uint32_t kModuleTypesBitmask = + ModuleInfoData::kTypeLoadedModule | ModuleInfoData::kTypeShellExtension | + ModuleInfoData::kTypeIme; + if ((module_data.module_types & kModuleTypesBitmask) != + ModuleInfoData::kTypeLoadedModule) { return; + } // Explicitly whitelist modules whose signing cert's Subject field matches the // one in the current executable. No attempt is made to check the validity of
diff --git a/chrome/browser/conflicts/problematic_programs_updater_win_unittest.cc b/chrome/browser/conflicts/problematic_programs_updater_win_unittest.cc index afdb372..9025068 100644 --- a/chrome/browser/conflicts/problematic_programs_updater_win_unittest.cc +++ b/chrome/browser/conflicts/problematic_programs_updater_win_unittest.cc
@@ -306,3 +306,31 @@ auto program_names = ProblematicProgramsUpdater::GetCachedPrograms(); ASSERT_EQ(0u, program_names.size()); } + +// Registered modules are defined as either a shell extension or an IME. +TEST_F(ProblematicProgramsUpdaterTest, IgnoreRegisteredModules) { + AddProblematicProgram(dll1_, L"Shell Extension", Option::ADD_REGISTRY_ENTRY); + AddProblematicProgram(dll2_, L"Input Method Editor", + Option::ADD_REGISTRY_ENTRY); + + auto problematic_programs_updater = + std::make_unique<ProblematicProgramsUpdater>( + exe_certificate_info(), module_list_filter(), installed_programs()); + + // Set the respective bit for registered modules. + auto module_data1 = CreateLoadedModuleInfoData(); + module_data1.module_types |= ModuleInfoData::kTypeShellExtension; + auto module_data2 = CreateLoadedModuleInfoData(); + module_data2.module_types |= ModuleInfoData::kTypeIme; + + // Simulate the modules loading into the process. + problematic_programs_updater->OnNewModuleFound(ModuleInfoKey(dll1_, 0, 0, 0), + module_data1); + problematic_programs_updater->OnNewModuleFound(ModuleInfoKey(dll2_, 0, 0, 0), + module_data2); + problematic_programs_updater->OnModuleDatabaseIdle(); + + EXPECT_FALSE(ProblematicProgramsUpdater::HasCachedPrograms()); + auto program_names = ProblematicProgramsUpdater::GetCachedPrograms(); + ASSERT_EQ(0u, program_names.size()); +}
diff --git a/chrome/browser/data_usage/tab_id_annotator.cc b/chrome/browser/data_usage/tab_id_annotator.cc index 30c534d..a30ff66 100644 --- a/chrome/browser/data_usage/tab_id_annotator.cc +++ b/chrome/browser/data_usage/tab_id_annotator.cc
@@ -32,9 +32,9 @@ // Attempts to get the associated tab info for render frame identified by // |render_process_id| and |render_frame_id|. |global_request_id| is also // populated in the tab info. -int32_t GetTabInfoForRequest(int render_process_id, - int render_frame_id, - content::GlobalRequestID global_request_id) { +SessionID GetTabInfoForRequest(int render_process_id, + int render_frame_id, + content::GlobalRequestID global_request_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // TODO(sclittle): For prerendering tabs, investigate if it's possible to find // the original tab that initiated the prerender. @@ -51,7 +51,7 @@ void AnnotateDataUse( std::unique_ptr<DataUse> data_use, const data_usage::DataUseAnnotator::DataUseConsumerCallback& callback, - int32_t tab_info) { + SessionID tab_info) { DCHECK(data_use); data_use->tab_id = tab_info; @@ -86,7 +86,8 @@ request, &render_process_id, &render_frame_id)) { // Run the callback immediately with a tab ID of -1 if the request has no // render frame. - AnnotateDataUse(std::move(data_use), callback, -1 /* tab_id */); + AnnotateDataUse(std::move(data_use), callback, + /*tab_id=*/SessionID::InvalidValue()); return; }
diff --git a/chrome/browser/data_usage/tab_id_annotator_unittest.cc b/chrome/browser/data_usage/tab_id_annotator_unittest.cc index 5ce30cde..ba51436 100644 --- a/chrome/browser/data_usage/tab_id_annotator_unittest.cc +++ b/chrome/browser/data_usage/tab_id_annotator_unittest.cc
@@ -53,7 +53,8 @@ }; // Synthesizes a DataUse object with the given |tab_id|. -std::unique_ptr<DataUse> CreateDataUse(int32_t tab_id, int render_process_id) { +std::unique_ptr<DataUse> CreateDataUse(SessionID tab_id, + int render_process_id) { auto data_use = std::unique_ptr<DataUse>(new DataUse( GURL("http://foo.com"), base::TimeTicks(), GURL(), tab_id, net::NetworkChangeNotifier::CONNECTION_UNKNOWN, std::string(), 100, 100)); @@ -92,7 +93,7 @@ void TestAnnotateOnIOThread(base::RunLoop* ui_run_loop, int render_process_id, int render_frame_id, - int32_t expected_tab_id) { + SessionID expected_tab_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(ui_run_loop); @@ -113,9 +114,10 @@ content::PREVIEWS_OFF, nullptr); } - // An invalid tab ID to check that the annotator always sets the tab ID. -2 is - // used because a tab ID of -1 is a valid value that means "no tab was found". - const int32_t kInvalidTabId = -2; + // An invalid tab ID to check that the annotator always sets the tab ID. An + // arbitrary number is used because SessionID::InvalidValue() means "no tab + // was found". + const SessionID kInvalidTabId = SessionID::FromSerializedValue(123456); // Annotate two separate DataUse objects to ensure that repeated annotations // for the same URLRequest work properly. @@ -140,21 +142,21 @@ BrowserThread::IO, FROM_HERE, base::BindOnce(&TestAnnotateOnIOThread, &ui_run_loop, -1 /* render_process_id */, -1 /* render_frame_id */, - -1 /* expected_tab_id */)); + SessionID::InvalidValue() /* expected_tab_id */)); ui_run_loop.Run(); } TEST_F(TabIdAnnotatorTest, AnnotateWithRenderFrameAndNoTab) { base::RunLoop ui_run_loop; // |web_contents()| isn't a tab, so it shouldn't have a tab ID. - EXPECT_EQ(-1, SessionTabHelper::IdForTab(web_contents())); + EXPECT_FALSE(SessionTabHelper::IdForTab(web_contents()).is_valid()); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::BindOnce(&TestAnnotateOnIOThread, &ui_run_loop, web_contents()->GetMainFrame()->GetProcess()->GetID(), web_contents()->GetMainFrame()->GetRoutingID(), - -1 /* expected_tab_id */)); + SessionID::InvalidValue() /* expected_tab_id */)); ui_run_loop.Run(); } @@ -162,9 +164,9 @@ base::RunLoop ui_run_loop; // Make |web_contents()| into a tab. SessionTabHelper::CreateForWebContents(web_contents()); - int32_t expected_tab_id = SessionTabHelper::IdForTab(web_contents()); + SessionID expected_tab_id = SessionTabHelper::IdForTab(web_contents()); // |web_contents()| is a tab, so it should have a tab ID. - EXPECT_NE(-1, expected_tab_id); + EXPECT_TRUE(expected_tab_id.is_valid()); BrowserThread::PostTask( BrowserThread::IO, FROM_HERE,
diff --git a/chrome/browser/data_usage/tab_id_provider.cc b/chrome/browser/data_usage/tab_id_provider.cc index d190720..ccd7eb9 100644 --- a/chrome/browser/data_usage/tab_id_provider.cc +++ b/chrome/browser/data_usage/tab_id_provider.cc
@@ -21,8 +21,8 @@ namespace { // Convenience typedefs for clarity. -typedef base::OnceCallback<int32_t(void)> TabIdGetter; -typedef base::OnceCallback<void(int32_t)> TabIdCallback; +typedef base::OnceCallback<SessionID(void)> TabIdGetter; +typedef base::OnceCallback<void(SessionID)> TabIdCallback; } // namespace @@ -44,7 +44,7 @@ // Runs all the callbacks in the order that they were added. This method must // not be called more than once. - void RunAll(int32_t tab_info) { + void RunAll(SessionID tab_info) { DCHECK(thread_checker_.CalledOnValidThread()); DCHECK(!is_done_); is_done_ = true; @@ -73,7 +73,7 @@ TabIdProvider::TabIdProvider(base::TaskRunner* task_runner, const base::Location& from_here, TabIdGetter tab_id_getter) - : is_tab_info_ready_(false), tab_info_(-1), weak_ptr_factory_(this) { + : weak_ptr_factory_(this) { std::unique_ptr<CallbackRunner> callback_runner(new CallbackRunner()); weak_callback_runner_ = callback_runner->GetWeakPtr(); callback_runner->AddCallback( @@ -93,8 +93,8 @@ void TabIdProvider::ProvideTabId(TabIdCallback callback) { DCHECK(thread_checker_.CalledOnValidThread()); - if (is_tab_info_ready_) { - std::move(callback).Run(tab_info_); + if (tab_info_.has_value()) { + std::move(callback).Run(*tab_info_); return; } if (weak_callback_runner_) { @@ -102,9 +102,9 @@ return; } // If no cached tab ID is available and |weak_callback_runner_| has been - // destroyed, pass a tab ID of -1 to the callback indicating that no tab was - // found. - std::move(callback).Run(-1); + // destroyed, pass an invalid tab ID to the callback indicating that no tab + // was found. + std::move(callback).Run(SessionID::InvalidValue()); } base::WeakPtr<TabIdProvider> TabIdProvider::GetWeakPtr() { @@ -116,12 +116,11 @@ const void* const TabIdProvider::kTabIdProviderUserDataKey = "TabIdProviderUserDataKey"; -void TabIdProvider::OnTabIdReady(int32_t tab_info) { +void TabIdProvider::OnTabIdReady(SessionID tab_info) { DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!is_tab_info_ready_); + DCHECK(!tab_info_.has_value()); tab_info_ = tab_info; - is_tab_info_ready_ = true; } } // namespace chrome_browser_data_usage
diff --git a/chrome/browser/data_usage/tab_id_provider.h b/chrome/browser/data_usage/tab_id_provider.h index eca8987..3c17f839 100644 --- a/chrome/browser/data_usage/tab_id_provider.h +++ b/chrome/browser/data_usage/tab_id_provider.h
@@ -10,8 +10,10 @@ #include "base/callback.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/supports_user_data.h" #include "base/threading/thread_checker.h" +#include "components/sessions/core/session_id.h" #include "content/public/browser/global_request_id.h" namespace base { @@ -29,18 +31,18 @@ public: struct URLRequestTabInfo { URLRequestTabInfo() - : tab_id(-1), + : tab_id(SessionID::InvalidValue()), main_frame_global_request_id(content::GlobalRequestID()) {} URLRequestTabInfo( - int32_t tab_id, + SessionID tab_id, const content::GlobalRequestID& main_frame_global_request_id) : tab_id(tab_id), main_frame_global_request_id(main_frame_global_request_id) {} // ID of the Tab for which this request happens. See comments of the same // field in data_usage::DataUse for when this is field is populated. - int32_t tab_id; + SessionID tab_id; // GlobalRequestID of the mainframe request. See comments of the same field // in data_usage::DataUse for when this is field is populated. @@ -51,13 +53,13 @@ // |task_runner|. TabIdProvider(base::TaskRunner* task_runner, const base::Location& from_here, - base::OnceCallback<int32_t(void)> tab_id_getter); + base::OnceCallback<SessionID(void)> tab_id_getter); ~TabIdProvider() override; // Calls |callback| with the tab ID, either immediately if it's already // available, or later once it becomes available. - void ProvideTabId(base::OnceCallback<void(int32_t)> callback); + void ProvideTabId(base::OnceCallback<void(SessionID)> callback); base::WeakPtr<TabIdProvider> GetWeakPtr(); @@ -67,11 +69,10 @@ class CallbackRunner; // Called when the |tab_info| is ready. - void OnTabIdReady(int32_t tab_info); + void OnTabIdReady(SessionID tab_info); base::ThreadChecker thread_checker_; - bool is_tab_info_ready_; - int32_t tab_info_; + base::Optional<SessionID> tab_info_; base::WeakPtr<CallbackRunner> weak_callback_runner_; base::WeakPtrFactory<TabIdProvider> weak_ptr_factory_;
diff --git a/chrome/browser/data_usage/tab_id_provider_unittest.cc b/chrome/browser/data_usage/tab_id_provider_unittest.cc index b915559..8c64885 100644 --- a/chrome/browser/data_usage/tab_id_provider_unittest.cc +++ b/chrome/browser/data_usage/tab_id_provider_unittest.cc
@@ -24,7 +24,7 @@ namespace { -const int32_t kTabId = 10; +const SessionID kTabId = SessionID::FromSerializedValue(10); class TabIdProviderTest : public testing::Test { public: @@ -34,7 +34,7 @@ ~TabIdProviderTest() override {} - base::OnceCallback<int32_t(void)> TabIdGetterCallback() { + base::OnceCallback<SessionID(void)> TabIdGetterCallback() { return base::BindOnce(&TabIdProviderTest::GetTabInfo, base::Unretained(this)); } @@ -44,7 +44,7 @@ int tab_id_getter_call_count() const { return tab_id_getter_call_count_; } private: - int32_t GetTabInfo() { + SessionID GetTabInfo() { ++tab_id_getter_call_count_; return kTabId; } @@ -58,14 +58,14 @@ }; // Copies |tab_id| into |capture|. -void CaptureTabId(int32_t* capture, int32_t tab_info) { +void CaptureTabId(SessionID* capture, SessionID tab_info) { *capture = tab_info; } TEST_F(TabIdProviderTest, ProvideTabId) { TabIdProvider provider(task_runner(), FROM_HERE, TabIdGetterCallback()); - int32_t tab_id = -1; + SessionID tab_id = SessionID::InvalidValue(); provider.ProvideTabId(base::BindOnce(&CaptureTabId, &tab_id)); run_loop()->RunUntilIdle(); @@ -77,13 +77,13 @@ TabIdProvider provider(task_runner(), FROM_HERE, TabIdGetterCallback()); // First, ask for the first tab ID to kick things off. - int32_t first_tab_id = -1; + SessionID first_tab_id = SessionID::InvalidValue(); provider.ProvideTabId(base::BindOnce(&CaptureTabId, &first_tab_id)); // The first tab ID callback should still be pending, with the tab ID not // available yet, so this second callback should piggyback off of the first // callback. - int32_t piggyback_tab_id = -1; + SessionID piggyback_tab_id = SessionID::InvalidValue(); provider.ProvideTabId(base::BindOnce(&CaptureTabId, &piggyback_tab_id)); run_loop()->RunUntilIdle(); @@ -98,7 +98,7 @@ TabIdProvider provider(task_runner(), FROM_HERE, TabIdGetterCallback()); // First, ask for the first tab ID to kick things off. - int32_t first_tab_id = -1; + SessionID first_tab_id = SessionID::InvalidValue(); provider.ProvideTabId(base::BindOnce(&CaptureTabId, &first_tab_id)); // Wait for the first tab ID callback to finish. @@ -109,7 +109,7 @@ // Ask for another tab ID, which should be satisfied by the cached tab ID from // the first callback. - int32_t cache_hit_tab_id = -1; + SessionID cache_hit_tab_id = SessionID::InvalidValue(); provider.ProvideTabId(base::BindOnce(&CaptureTabId, &cache_hit_tab_id)); // This cache hit callback should run synchronously, without causing the tab @@ -123,7 +123,8 @@ new TabIdProvider(task_runner(), FROM_HERE, TabIdGetterCallback())); // Ask for two tab IDs. - int32_t first_tab_id = -1, second_tab_id = -1; + SessionID first_tab_id = SessionID::InvalidValue(), + second_tab_id = SessionID::InvalidValue(); provider->ProvideTabId(base::BindOnce(&CaptureTabId, &first_tab_id)); provider->ProvideTabId(base::BindOnce(&CaptureTabId, &second_tab_id));
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index aef2bea..2683893a 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -2600,12 +2600,12 @@ // the headers are successfully received. "download-anchor-attrib-404.html", "there_IS_no_spoon.zip", DOWNLOAD_NAVIGATE, - download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT, false, false}, + download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT, true, false}, {// Similar to the above, but the resulting response contains a status // code of 400. "download-anchor-attrib-400.html", "zip_file_not_found.zip", DOWNLOAD_NAVIGATE, download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED, - false, false}, + true, false}, {// Direct download of a URL where the hostname doesn't resolve. "http://doesnotexist/shouldnotdownloadsuccessfully", "http://doesnotexist/shouldnotdownloadsuccessfully", DOWNLOAD_DIRECT,
diff --git a/chrome/browser/extensions/active_tab_unittest.cc b/chrome/browser/extensions/active_tab_unittest.cc index 3970ab9f..65273566 100644 --- a/chrome/browser/extensions/active_tab_unittest.cc +++ b/chrome/browser/extensions/active_tab_unittest.cc
@@ -125,9 +125,7 @@ TabHelper::CreateForWebContents(web_contents()); } - int tab_id() { - return SessionTabHelper::IdForTab(web_contents()); - } + int tab_id() { return SessionTabHelper::IdForTab(web_contents()).id(); } ActiveTabPermissionGranter* active_tab_permission_granter() { return extensions::TabHelper::FromWebContents(web_contents())-> @@ -194,7 +192,7 @@ bool IsGrantedForTab(const Extension* extension, const content::WebContents* web_contents) { return extension->permissions_data()->HasAPIPermissionForTab( - SessionTabHelper::IdForTab(web_contents), APIPermission::kTab); + SessionTabHelper::IdForTab(web_contents).id(), APIPermission::kTab); } // TODO(justinlin): Remove when tabCapture is moved to stable.
diff --git a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc index 3c912638..519623a 100644 --- a/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc +++ b/chrome/browser/extensions/api/cryptotoken_private/cryptotoken_private_api_unittest.cc
@@ -175,7 +175,7 @@ content::WebContents* web_contents = browser()->tab_strip_model()->GetWebContentsAt(0); - tab_id_ = SessionTabHelper::IdForTab(web_contents); + tab_id_ = SessionTabHelper::IdForTab(web_contents).id(); PermissionRequestManager::CreateForWebContents(web_contents); prompt_factory_ = std::make_unique<MockPermissionPromptFactory>( PermissionRequestManager::FromWebContents(web_contents));
diff --git a/chrome/browser/extensions/api/debugger/debugger_apitest.cc b/chrome/browser/extensions/api/debugger/debugger_apitest.cc index 92fae33..28f88e20 100644 --- a/chrome/browser/extensions/api/debugger/debugger_apitest.cc +++ b/chrome/browser/extensions/api/debugger/debugger_apitest.cc
@@ -86,7 +86,7 @@ browser()->tab_strip_model()->GetActiveWebContents(); // Attach by tabId. - int tab_id = SessionTabHelper::IdForTab(web_contents); + int tab_id = SessionTabHelper::IdForTab(web_contents).id(); std::string debugee_by_tab = base::StringPrintf("{\"tabId\": %d}", tab_id); testing::AssertionResult result = RunAttachFunctionOnTarget(debugee_by_tab, expected_error); @@ -191,7 +191,8 @@ IN_PROC_BROWSER_TEST_F(DebuggerApiTest, InfoBar) { int tab_id = SessionTabHelper::IdForTab( - browser()->tab_strip_model()->GetActiveWebContents()); + browser()->tab_strip_model()->GetActiveWebContents()) + .id(); scoped_refptr<DebuggerAttachFunction> attach_function; scoped_refptr<DebuggerDetachFunction> detach_function; @@ -200,7 +201,8 @@ AddBlankTabAndShow(another_browser); AddBlankTabAndShow(another_browser); int tab_id2 = SessionTabHelper::IdForTab( - another_browser->tab_strip_model()->GetActiveWebContents()); + another_browser->tab_strip_model()->GetActiveWebContents()) + .id(); InfoBarService* service1 = InfoBarService::FromWebContents( browser()->tab_strip_model()->GetActiveWebContents());
diff --git a/chrome/browser/extensions/api/declarative_content/content_action.cc b/chrome/browser/extensions/api/declarative_content/content_action.cc index fa344ec..cbda955 100644 --- a/chrome/browser/extensions/api/declarative_content/content_action.cc +++ b/chrome/browser/extensions/api/declarative_content/content_action.cc
@@ -381,9 +381,7 @@ content::RenderFrameHost* render_frame_host = contents->GetMainFrame(); render_frame_host->Send(new ExtensionMsg_ExecuteDeclarativeScript( render_frame_host->GetRoutingID(), - SessionTabHelper::IdForTab(contents), - extension->id(), - script_.id(), + SessionTabHelper::IdForTab(contents).id(), extension->id(), script_.id(), contents->GetLastCommittedURL())); }
diff --git a/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc b/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc index 51be4bb..37063408 100644 --- a/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc +++ b/chrome/browser/extensions/api/extension_action/browser_action_interactive_test.cc
@@ -345,13 +345,13 @@ OpenPopupViaAPI(false); ExtensionService* service = extensions::ExtensionSystem::Get( browser()->profile())->extension_service(); - ASSERT_FALSE( - service->GetExtensionById(last_loaded_extension_id(), false) - ->permissions_data() - ->HasAPIPermissionForTab( - SessionTabHelper::IdForTab( - browser()->tab_strip_model()->GetActiveWebContents()), - APIPermission::kTab)); + ASSERT_FALSE(service->GetExtensionById(last_loaded_extension_id(), false) + ->permissions_data() + ->HasAPIPermissionForTab( + SessionTabHelper::IdForTab( + browser()->tab_strip_model()->GetActiveWebContents()) + .id(), + APIPermission::kTab)); ClosePopup(); }
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_api.cc b/chrome/browser/extensions/api/extension_action/extension_action_api.cc index 6466d63..3d48f3a 100644 --- a/chrome/browser/extensions/api/extension_action/extension_action_api.cc +++ b/chrome/browser/extensions/api/extension_action/extension_action_api.cc
@@ -239,7 +239,7 @@ void ExtensionActionAPI::ClearAllValuesForTab( content::WebContents* web_contents) { DCHECK(web_contents); - int tab_id = SessionTabHelper::IdForTab(web_contents); + const SessionID tab_id = SessionTabHelper::IdForTab(web_contents); content::BrowserContext* browser_context = web_contents->GetBrowserContext(); const ExtensionSet& enabled_extensions = ExtensionRegistry::Get(browser_context_)->enabled_extensions(); @@ -251,7 +251,7 @@ ExtensionAction* extension_action = action_manager->GetExtensionAction(**iter); if (extension_action) { - extension_action->ClearAllValuesForTab(tab_id); + extension_action->ClearAllValuesForTab(tab_id.id()); NotifyChange(extension_action, web_contents, browser_context); } }
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc index 1ad1768..fb57664c 100644 --- a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc +++ b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc
@@ -119,7 +119,7 @@ domAutomationController.send('pass');)"; content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - int tab_id = SessionTabHelper::IdForTab(web_contents); + SessionID tab_id = SessionTabHelper::IdForTab(web_contents); constexpr char kBrowserActionKey[] = "browser_action"; TestStateStoreObserver test_state_store_observer(profile(), extension->id()); @@ -128,7 +128,7 @@ extension->id()); // First, update a specific tab. std::string update_options = - base::StringPrintf("{text: 'New Text', tabId: %d}", tab_id); + base::StringPrintf("{text: 'New Text', tabId: %d}", tab_id.id()); EXPECT_EQ("pass", browsertest_util::ExecuteScriptInBackgroundPage( profile(), extension->id(), base::StringPrintf(kUpdate, update_options.c_str())));
diff --git a/chrome/browser/extensions/api/processes/processes_api.cc b/chrome/browser/extensions/api/processes/processes_api.cc index 276159c9..9f8179e 100644 --- a/chrome/browser/extensions/api/processes/processes_api.cc +++ b/chrome/browser/extensions/api/processes/processes_api.cc
@@ -131,9 +131,9 @@ for (const auto& task_id : tasks_on_process) { api::processes::TaskInfo task_info; task_info.title = base::UTF16ToUTF8(task_manager->GetTitle(task_id)); - const int tab_id = task_manager->GetTabId(task_id); - if (tab_id != -1) - task_info.tab_id.reset(new int(tab_id)); + const SessionID tab_id = task_manager->GetTabId(task_id); + if (tab_id.is_valid()) + task_info.tab_id.reset(new int(tab_id.id())); out_process->tasks.push_back(std::move(task_info)); }
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc index 09a7f1b2..2978c2b 100644 --- a/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc +++ b/chrome/browser/extensions/api/tab_capture/tab_capture_api.cc
@@ -204,7 +204,7 @@ // Make sure either we have been granted permission to capture through an // extension icon click or our extension is whitelisted. if (!extension()->permissions_data()->HasAPIPermissionForTab( - SessionTabHelper::IdForTab(target_contents), + SessionTabHelper::IdForTab(target_contents).id(), APIPermission::kTabCaptureForTab) && base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kWhitelistedExtensionID) != extension_id &&
diff --git a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc index 6cd5062..c8a4493 100644 --- a/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc +++ b/chrome/browser/extensions/api/tab_capture/tab_capture_registry.cc
@@ -192,7 +192,7 @@ } void GetCaptureInfo(tab_capture::CaptureInfo* info) const { - info->tab_id = SessionTabHelper::IdForTab(web_contents()); + info->tab_id = SessionTabHelper::IdForTab(web_contents()).id(); info->status = capture_state_; info->fullscreen = is_fullscreened_; }
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index b8604ff..b83c1da 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -36,6 +36,7 @@ #include "chrome/browser/extensions/window_controller_list.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" #include "chrome/browser/resource_coordinator/tab_manager.h" #include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/translate/chrome_translate_client.h" @@ -986,8 +987,6 @@ TabStripModel* tab_strip = browser->tab_strip_model(); for (int i = 0; i < tab_strip->count(); ++i) { WebContents* web_contents = tab_strip->GetWebContentsAt(i); - resource_coordinator::TabManager* tab_manager = - g_browser_process->GetTabManager(); if (index > -1 && i != index) continue; @@ -1016,13 +1015,17 @@ continue; } + auto* tab_lifecycle_unit_external = + resource_coordinator::TabLifecycleUnitExternal::FromWebContents( + web_contents); + if (!MatchesBool(params->query_info.discarded.get(), - tab_manager->IsTabDiscarded(web_contents))) { + tab_lifecycle_unit_external->IsDiscarded())) { continue; } if (!MatchesBool(params->query_info.auto_discardable.get(), - tab_manager->IsTabAutoDiscardable(web_contents))) { + tab_lifecycle_unit_external->IsAutoDiscardable())) { continue; } @@ -1252,7 +1255,7 @@ error_ = keys::kNoSelectedTabError; return false; } - tab_id = SessionTabHelper::IdForTab(contents); + tab_id = SessionTabHelper::IdForTab(contents).id(); } else { tab_id = *params->tab_id; } @@ -1734,7 +1737,7 @@ } if (!extension()->permissions_data()->CanCaptureVisiblePage( - SessionTabHelper::IdForTab(contents), &error_)) { + SessionTabHelper::IdForTab(contents).id(), &error_)) { return NULL; } return contents;
diff --git a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc index bd67c2e..89c2d712 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api_unittest.cc
@@ -20,27 +20,15 @@ #include "extensions/browser/api_test_utils.h" #include "extensions/common/constants.h" #include "extensions/common/extension_builder.h" +#include "ui/display/test/scoped_screen_override.h" #include "ui/display/test/test_screen.h" namespace extensions { +using display::test::ScopedScreenOverride; + namespace { -class ScopedScreenOverride { - public: - ~ScopedScreenOverride() { - display::Screen::SetScreenInstance(original_screen_); - } - - void SetScreenInstance(display::Screen* instance) { - original_screen_ = display::Screen::GetScreen(); - display::Screen::SetScreenInstance(instance); - } - - private: - display::Screen* original_screen_ = nullptr; -}; - std::unique_ptr<base::ListValue> RunTabsQueryFunction( Browser* browser, const Extension* extension, @@ -88,14 +76,13 @@ params.type = Browser::TYPE_TABBED; params.window = browser_window_.get(); browser_.reset(new Browser(params)); - scoped_screen_override_.reset(new ScopedScreenOverride); - scoped_screen_override_->SetScreenInstance(&test_screen_); + scoped_screen_override_ = + std::make_unique<ScopedScreenOverride>(&test_screen_); } void TabsApiUnitTest::TearDown() { browser_.reset(); browser_window_.reset(); - scoped_screen_override_.reset(); content::BrowserSideNavigationTearDown(); ExtensionServiceTestBase::TearDown(); } @@ -266,7 +253,7 @@ EXPECT_EQ(kGoogle, web_contents->GetVisibleURL()); SessionTabHelper::CreateForWebContents(web_contents); - int tab_id = SessionTabHelper::IdForTab(web_contents); + int tab_id = SessionTabHelper::IdForTab(web_contents).id(); browser()->tab_strip_model()->AppendWebContents(web_contents, true); scoped_refptr<TabsUpdateFunction> function = new TabsUpdateFunction();
diff --git a/chrome/browser/extensions/api/tabs/tabs_test.cc b/chrome/browser/extensions/api/tabs/tabs_test.cc index abb1c3a..aa7aea4 100644 --- a/chrome/browser/extensions/api/tabs/tabs_test.cc +++ b/chrome/browser/extensions/api/tabs/tabs_test.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/extensions/window_controller.h" #include "chrome/browser/prefs/incognito_mode_prefs.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" #include "chrome/browser/resource_coordinator/tab_manager.h" #include "chrome/browser/resource_coordinator/time.h" #include "chrome/browser/ui/browser.h" @@ -1460,10 +1461,10 @@ discard.get(), base::StringPrintf("[%u]", tab_id), browser()))); // Confirms that TabManager sees the tab as discarded. - resource_coordinator::TabManager* tab_manager = - g_browser_process->GetTabManager(); web_contents = browser()->tab_strip_model()->GetWebContentsAt(1); - EXPECT_TRUE(tab_manager->IsTabDiscarded(web_contents)); + EXPECT_TRUE(resource_coordinator::TabLifecycleUnitExternal::FromWebContents( + web_contents) + ->IsDiscarded()); // Make sure the returned tab is the one discarded and its discarded state is // correct. @@ -1507,8 +1508,9 @@ discard.get(), base::StringPrintf("[%u]", tab_invalid_id), browser()); // Discarded state should still be false as no tab was discarded. - EXPECT_FALSE(g_browser_process->GetTabManager()->IsTabDiscarded( - browser()->tab_strip_model()->GetWebContentsAt(1))); + EXPECT_FALSE(resource_coordinator::TabLifecycleUnitExternal::FromWebContents( + browser()->tab_strip_model()->GetWebContentsAt(1)) + ->IsDiscarded()); // Check error message. EXPECT_TRUE(base::MatchPattern(error, keys::kTabNotFoundError)); @@ -1537,7 +1539,9 @@ // Confirms that TabManager sees the tab as discarded. web_contents = browser()->tab_strip_model()->GetWebContentsAt(1); - EXPECT_TRUE(g_browser_process->GetTabManager()->IsTabDiscarded(web_contents)); + EXPECT_TRUE(resource_coordinator::TabLifecycleUnitExternal::FromWebContents( + web_contents) + ->IsDiscarded()); // Make sure the returned tab is the one discarded and its discarded state is // correct. @@ -1567,10 +1571,12 @@ utils::RunFunctionAndReturnError(discard.get(), "[]", browser()); // Discarded state should be false for both tabs as no tab was discarded. - EXPECT_FALSE(g_browser_process->GetTabManager()->IsTabDiscarded( - browser()->tab_strip_model()->GetWebContentsAt(1))); - EXPECT_FALSE(g_browser_process->GetTabManager()->IsTabDiscarded( - browser()->tab_strip_model()->GetWebContentsAt(0))); + EXPECT_FALSE(resource_coordinator::TabLifecycleUnitExternal::FromWebContents( + browser()->tab_strip_model()->GetWebContentsAt(1)) + ->IsDiscarded()); + EXPECT_FALSE(resource_coordinator::TabLifecycleUnitExternal::FromWebContents( + browser()->tab_strip_model()->GetWebContentsAt(0)) + ->IsDiscarded()); // Check error message. EXPECT_TRUE(base::MatchPattern(error, keys::kCannotFindTabToDiscard));
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index 1446ca5..8f3d556 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -45,11 +45,9 @@ #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" -#include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" #include "content/public/common/page_type.h" #include "content/public/test/browser_test_utils.h" -#include "content/public/test/simple_url_loader_test_helper.h" #include "content/public/test/url_loader_interceptor.h" #include "extensions/browser/api/web_request/web_request_api.h" #include "extensions/browser/blocked_action_type.h" @@ -74,8 +72,6 @@ #include "net/url_request/url_request_filter.h" #include "net/url_request/url_request_interceptor.h" #include "services/network/public/cpp/features.h" -#include "services/network/public/cpp/resource_request.h" -#include "services/network/public/cpp/simple_url_loader.h" #include "third_party/WebKit/public/platform/WebInputEvent.h" #if defined(OS_CHROMEOS) @@ -912,11 +908,12 @@ } // Verify that requests to clientsX.google.com are protected properly. -// First test requests from a standard renderer and then a request from the -// browser process. +// First test requests from a standard renderer and a webui renderer. +// Then test a request from the browser process. IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestClientsGoogleComProtection) { ASSERT_TRUE(embedded_test_server()->Start()); + int port = embedded_test_server()->port(); // Load an extension that registers a listener for webRequest events, and // wait until it's initialized. @@ -926,60 +923,96 @@ ASSERT_TRUE(extension) << message_; EXPECT_TRUE(listener.WaitUntilSatisfied()); - EXPECT_EQ(0, GetWebRequestCountFromBackgroundPage(extension, profile())); + // Perform requests to https://client1.google.com from renderer processes. - GURL main_frame_url = - embedded_test_server()->GetURL("www.example.com", "/simple.html"); - NavigateParams params(browser(), main_frame_url, ui::PAGE_TRANSITION_TYPED); - ui_test_utils::NavigateToURL(¶ms); + struct TestCase { + const char* main_frame_url; + bool request_to_clients1_google_com_visible; + } testcases[] = { + {"http://www.example.com", true}, {"chrome://settings", false}, + }; - EXPECT_EQ(0, GetWebRequestCountFromBackgroundPage(extension, profile())); + // Expected number of requests to clients1.google.com observed so far. + int expected_requests_observed = 0; + EXPECT_EQ(expected_requests_observed, + GetWebRequestCountFromBackgroundPage(extension, profile())); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_TRUE(web_contents); + for (const auto& testcase : testcases) { + SCOPED_TRACE(testcase.main_frame_url); - // Attempt to issue a request to clients1.google.com from the renderer. This - // will fail, but should still be visible to the WebRequest API. - const char kRequest[] = R"( - var xhr = new XMLHttpRequest(); - xhr.open('GET', 'http://clients1.google.com'); - xhr.onload = () => {window.domAutomationController.send(true);}; - xhr.onerror = () => {window.domAutomationController.send(false);}; - xhr.send();)"; - bool success = false; - EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetMainFrame(), - kRequest, &success)); - // Requests always fail due to cross origin nature. - EXPECT_FALSE(success); + GURL url; + if (base::StartsWith(testcase.main_frame_url, "chrome://", + base::CompareCase::INSENSITIVE_ASCII)) { + url = GURL(testcase.main_frame_url); + } else { + url = GURL(base::StringPrintf("%s:%d/simple.html", + testcase.main_frame_url, port)); + } - EXPECT_EQ(1, GetWebRequestCountFromBackgroundPage(extension, profile())); + NavigateParams params(browser(), url, ui::PAGE_TRANSITION_TYPED); + ui_test_utils::NavigateToURL(¶ms); - // Now perform a request to client1.google.com from the browser process. This - // should *not* be visible to the WebRequest API. + EXPECT_EQ(expected_requests_observed, + GetWebRequestCountFromBackgroundPage(extension, profile())); - auto request = std::make_unique<network::ResourceRequest>(); - request->url = - embedded_test_server()->GetURL("clients1.google.com", "/simple.html"); + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + ASSERT_TRUE(web_contents); - auto* url_loader_factory = - content::BrowserContext::GetDefaultStoragePartition(profile()) - ->GetURLLoaderFactoryForBrowserProcess() - .get(); - content::SimpleURLLoaderTestHelper loader_helper; - auto loader = network::SimpleURLLoader::Create(std::move(request), - TRAFFIC_ANNOTATION_FOR_TESTS); - loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( - url_loader_factory, loader_helper.GetCallback()); + const char kRequest[] = + "var xhr = new XMLHttpRequest();\n" + "xhr.open('GET', 'https://clients1.google.com');\n" + "xhr.onload = () => {window.domAutomationController.send(true);};\n" + "xhr.onerror = () => {window.domAutomationController.send(false);};\n" + "xhr.send();\n"; - // Wait for the response to complete. - loader_helper.WaitForCallback(); - EXPECT_TRUE(loader_helper.response_body()); - EXPECT_EQ(200, loader->ResponseInfo()->headers->response_code()); + bool success = false; + EXPECT_TRUE(ExecuteScriptAndExtractBool(web_contents->GetMainFrame(), + kRequest, &success)); + // Requests always fail due to cross origin nature. + EXPECT_FALSE(success); - // We should still have only seen the single render-initiated request from the - // first half of the test. - EXPECT_EQ(1, GetWebRequestCountFromBackgroundPage(extension, profile())); + if (testcase.request_to_clients1_google_com_visible) + ++expected_requests_observed; + + EXPECT_EQ(expected_requests_observed, + GetWebRequestCountFromBackgroundPage(extension, profile())); + } + + // Perform request to https://client1.google.com from browser process. + + class TestURLFetcherDelegate : public net::URLFetcherDelegate { + public: + explicit TestURLFetcherDelegate(const base::Closure& quit_loop_func) + : quit_loop_func_(quit_loop_func) {} + ~TestURLFetcherDelegate() override {} + + void OnURLFetchComplete(const net::URLFetcher* source) override { + EXPECT_EQ(net::HTTP_OK, source->GetResponseCode()); + quit_loop_func_.Run(); + } + + private: + base::Closure quit_loop_func_; + }; + base::RunLoop run_loop; + TestURLFetcherDelegate delegate(run_loop.QuitClosure()); + + net::URLFetcherImplFactory url_fetcher_impl_factory; + net::FakeURLFetcherFactory url_fetcher_factory(&url_fetcher_impl_factory); + url_fetcher_factory.SetFakeResponse(GURL("https://client1.google.com"), + "hello my friend", net::HTTP_OK, + net::URLRequestStatus::SUCCESS); + std::unique_ptr<net::URLFetcher> fetcher = + url_fetcher_factory.CreateURLFetcher( + 1, GURL("https://client1.google.com"), net::URLFetcher::GET, + &delegate, TRAFFIC_ANNOTATION_FOR_TESTS); + fetcher->Start(); + run_loop.Run(); + + // This request should not be observed by the extension. + EXPECT_EQ(expected_requests_observed, + GetWebRequestCountFromBackgroundPage(extension, profile())); } // Verify that requests for PAC scripts are protected properly.
diff --git a/chrome/browser/extensions/extension_action_runner.cc b/chrome/browser/extensions/extension_action_runner.cc index c97dac8..dbf216e 100644 --- a/chrome/browser/extensions/extension_action_runner.cc +++ b/chrome/browser/extensions/extension_action_runner.cc
@@ -111,7 +111,7 @@ // Anything that gets here should have a page or browser action. DCHECK(extension_action); - int tab_id = SessionTabHelper::IdForTab(web_contents()); + int tab_id = SessionTabHelper::IdForTab(web_contents()).id(); if (!extension_action->GetIsVisible(tab_id)) return ExtensionAction::ACTION_NONE; @@ -204,7 +204,7 @@ return PermissionsData::ACCESS_ALLOWED; GURL url = web_contents()->GetVisibleURL(); - int tab_id = SessionTabHelper::IdForTab(web_contents()); + int tab_id = SessionTabHelper::IdForTab(web_contents()).id(); switch (type) { case UserScript::CONTENT_SCRIPT: return extension->permissions_data()->GetContentScriptAccess(
diff --git a/chrome/browser/extensions/extension_action_test_util.cc b/chrome/browser/extensions/extension_action_test_util.cc index 5314e6b..b4ff1103 100644 --- a/chrome/browser/extensions/extension_action_test_util.cc +++ b/chrome/browser/extensions/extension_action_test_util.cc
@@ -28,7 +28,7 @@ bool only_count_visible) { DCHECK(web_contents); size_t count = 0u; - int tab_id = SessionTabHelper::IdForTab(web_contents); + SessionID tab_id = SessionTabHelper::IdForTab(web_contents); Profile* profile = Profile::FromBrowserContext(web_contents->GetBrowserContext()); ToolbarActionsModel* toolbar_model = ToolbarActionsModel::Get(profile); @@ -44,7 +44,7 @@ ExtensionAction* extension_action = action_manager->GetPageAction(*extension); if (extension_action && - (!only_count_visible || extension_action->GetIsVisible(tab_id))) + (!only_count_visible || extension_action->GetIsVisible(tab_id.id()))) ++count; } }
diff --git a/chrome/browser/extensions/extension_context_menu_model.cc b/chrome/browser/extensions/extension_context_menu_model.cc index dc2099a..6c601b4 100644 --- a/chrome/browser/extensions/extension_context_menu_model.cc +++ b/chrome/browser/extensions/extension_context_menu_model.cc
@@ -209,7 +209,7 @@ content::WebContents* web_contents = GetActiveWebContents(); return web_contents && extension_action_ && extension_action_->HasPopup( - SessionTabHelper::IdForTab(web_contents)); + SessionTabHelper::IdForTab(web_contents).id()); } case UNINSTALL: return !IsExtensionRequiredByPolicy(extension, profile_);
diff --git a/chrome/browser/extensions/extension_context_menu_model_unittest.cc b/chrome/browser/extensions/extension_context_menu_model_unittest.cc index 15faf18..e2f01a5 100644 --- a/chrome/browser/extensions/extension_context_menu_model_unittest.cc +++ b/chrome/browser/extensions/extension_context_menu_model_unittest.cc
@@ -43,11 +43,14 @@ #include "extensions/common/value_builder.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/display/test/scoped_screen_override.h" #include "ui/display/test/test_screen.h" #include "ui/gfx/image/image.h" namespace extensions { +using display::test::ScopedScreenOverride; + namespace { void Increment(int* i) { @@ -191,6 +194,7 @@ std::unique_ptr<TestBrowserWindow> test_window_; std::unique_ptr<Browser> browser_; display::test::TestScreen test_screen_; + std::unique_ptr<ScopedScreenOverride> scoped_screen_override_; DISALLOW_COPY_AND_ASSIGN(ExtensionContextMenuModelTest); }; @@ -243,7 +247,8 @@ void ExtensionContextMenuModelTest::SetUp() { ExtensionServiceTestBase::SetUp(); content::BrowserSideNavigationSetUp(); - display::Screen::SetScreenInstance(&test_screen_); + scoped_screen_override_ = + std::make_unique<ScopedScreenOverride>(&test_screen_); } void ExtensionContextMenuModelTest::TearDown() {
diff --git a/chrome/browser/extensions/extension_keybinding_apitest.cc b/chrome/browser/extensions/extension_keybinding_apitest.cc index ee4fdc5..429ca97c 100644 --- a/chrome/browser/extensions/extension_keybinding_apitest.cc +++ b/chrome/browser/extensions/extension_keybinding_apitest.cc
@@ -140,7 +140,7 @@ bool IsGrantedForTab(const Extension* extension, const content::WebContents* web_contents) { return extension->permissions_data()->HasAPIPermissionForTab( - SessionTabHelper::IdForTab(web_contents), APIPermission::kTab); + SessionTabHelper::IdForTab(web_contents).id(), APIPermission::kTab); } #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc index bc0755e..fae948e 100644 --- a/chrome/browser/extensions/extension_tab_util.cc +++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -17,7 +17,7 @@ #include "chrome/browser/extensions/chrome_extension_function_details.h" #include "chrome/browser/extensions/tab_helper.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/resource_coordinator/tab_manager.h" +#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" #include "chrome/browser/sessions/session_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -101,7 +101,7 @@ Browser* browser = chrome::FindBrowserWithWebContents(web_contents); if (browser && !ExtensionTabUtil::BrowserSupportsTabs(browser)) return -1; - return SessionTabHelper::IdForTab(web_contents); + return SessionTabHelper::IdForTab(web_contents).id(); } ExtensionTabUtil::Delegate* g_extension_tab_util_delegate = nullptr; @@ -305,7 +305,7 @@ } int ExtensionTabUtil::GetTabId(const WebContents* web_contents) { - return SessionTabHelper::IdForTab(web_contents); + return SessionTabHelper::IdForTab(web_contents).id(); } std::string ExtensionTabUtil::GetTabStatusText(bool is_loading) { @@ -313,7 +313,7 @@ } int ExtensionTabUtil::GetWindowIdOfTab(const WebContents* web_contents) { - return SessionTabHelper::IdForWindowContainingTab(web_contents); + return SessionTabHelper::IdForWindowContainingTab(web_contents).id(); } // static @@ -352,10 +352,13 @@ tab_object->highlighted = tab_strip && tab_strip->IsTabSelected(tab_index); tab_object->pinned = tab_strip && tab_strip->IsTabPinned(tab_index); tab_object->audible = std::make_unique<bool>(contents->WasRecentlyAudible()); + auto* tab_lifeycle_unit_external = + resource_coordinator::TabLifecycleUnitExternal::FromWebContents(contents); tab_object->discarded = - g_browser_process->GetTabManager()->IsTabDiscarded(contents); + tab_lifeycle_unit_external && tab_lifeycle_unit_external->IsDiscarded(); tab_object->auto_discardable = - g_browser_process->GetTabManager()->IsTabAutoDiscardable(contents); + !tab_lifeycle_unit_external || + tab_lifeycle_unit_external->IsAutoDiscardable(); tab_object->muted_info = CreateMutedInfo(contents); tab_object->incognito = contents->GetBrowserContext()->IsOffTheRecord(); gfx::Size contents_size = contents->GetContainerBounds().size(); @@ -568,7 +571,7 @@ TabStripModel* target_tab_strip = target_browser->tab_strip_model(); for (int i = 0; i < target_tab_strip->count(); ++i) { WebContents* target_contents = target_tab_strip->GetWebContentsAt(i); - if (SessionTabHelper::IdForTab(target_contents) == tab_id) { + if (SessionTabHelper::IdForTab(target_contents).id() == tab_id) { if (browser) *browser = target_browser; if (tab_strip)
diff --git a/chrome/browser/extensions/native_bindings_apitest.cc b/chrome/browser/extensions/native_bindings_apitest.cc index 2a826f7..b37a4de 100644 --- a/chrome/browser/extensions/native_bindings_apitest.cc +++ b/chrome/browser/extensions/native_bindings_apitest.cc
@@ -102,7 +102,7 @@ ExtensionActionManager::Get(profile())->GetPageAction(*extension); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - int tab_id = SessionTabHelper::IdForTab(web_contents); + int tab_id = SessionTabHelper::IdForTab(web_contents).id(); EXPECT_FALSE(page_action->GetIsVisible(tab_id)); EXPECT_TRUE(page_action->GetDeclarativeIcon(tab_id).IsEmpty());
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc index 23ef319a..32a5003 100644 --- a/chrome/browser/extensions/tab_helper.cc +++ b/chrome/browser/extensions/tab_helper.cc
@@ -171,9 +171,7 @@ web_contents->ForEachFrame( base::BindRepeating(&TabHelper::SetTabId, base::Unretained(this))); active_tab_permission_granter_.reset(new ActiveTabPermissionGranter( - web_contents, - SessionTabHelper::IdForTab(web_contents), - profile_)); + web_contents, SessionTabHelper::IdForTab(web_contents).id(), profile_)); AddScriptExecutionObserver(ActivityLog::GetInstance(profile_)); @@ -612,9 +610,9 @@ } void TabHelper::SetTabId(content::RenderFrameHost* render_frame_host) { - render_frame_host->Send( - new ExtensionMsg_SetTabId(render_frame_host->GetRoutingID(), - SessionTabHelper::IdForTab(web_contents()))); + render_frame_host->Send(new ExtensionMsg_SetTabId( + render_frame_host->GetRoutingID(), + SessionTabHelper::IdForTab(web_contents()).id())); } } // namespace extensions
diff --git a/chrome/browser/feedback/feedback_dialog_utils.cc b/chrome/browser/feedback/feedback_dialog_utils.cc index 7946c42b..3c4a96f 100644 --- a/chrome/browser/feedback/feedback_dialog_utils.cc +++ b/chrome/browser/feedback/feedback_dialog_utils.cc
@@ -21,7 +21,7 @@ namespace chrome { -GURL GetTargetTabUrl(int session_id, int index) { +GURL GetTargetTabUrl(SessionID session_id, int index) { Browser* browser = chrome::FindBrowserWithID(session_id); // Sanity checks. if (!browser || index >= browser->tab_strip_model()->count())
diff --git a/chrome/browser/feedback/feedback_dialog_utils.h b/chrome/browser/feedback/feedback_dialog_utils.h index fa7f0f6..ff049e6 100644 --- a/chrome/browser/feedback/feedback_dialog_utils.h +++ b/chrome/browser/feedback/feedback_dialog_utils.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_FEEDBACK_FEEDBACK_DIALOG_UTILS_H_ #define CHROME_BROWSER_FEEDBACK_FEEDBACK_DIALOG_UTILS_H_ +#include "components/sessions/core/session_id.h" + class Browser; class GURL; class Profile; @@ -14,7 +16,7 @@ // Get the GURL of the active tab when the feedback dialog was invoked, if // any. -GURL GetTargetTabUrl(int session_id, int index); +GURL GetTargetTabUrl(SessionID session_id, int index); // Get the profile that should be used to open the feedback dialog. Profile* GetFeedbackProfile(Browser* browser);
diff --git a/chrome/browser/feedback/show_feedback_page.cc b/chrome/browser/feedback/show_feedback_page.cc index 31047965e..4c24fdf 100644 --- a/chrome/browser/feedback/show_feedback_page.cc +++ b/chrome/browser/feedback/show_feedback_page.cc
@@ -25,7 +25,7 @@ const std::string& extra_diagnostics) { GURL page_url; if (browser) { - page_url = GetTargetTabUrl(browser->session_id().id(), + page_url = GetTargetTabUrl(browser->session_id(), browser->tab_strip_model()->active_index()); }
diff --git a/chrome/browser/media/cast_remoting_connector.cc b/chrome/browser/media/cast_remoting_connector.cc index 4bddaf91..a298d9e2 100644 --- a/chrome/browser/media/cast_remoting_connector.cc +++ b/chrome/browser/media/cast_remoting_connector.cc
@@ -129,8 +129,8 @@ if (!connector) { // TODO(xjz): Use TabAndroid::GetAndroidId() to get the tab ID when support // remoting on Android. - const SessionID::id_type tab_id = SessionTabHelper::IdForTab(contents); - if (tab_id == -1) + const SessionID tab_id = SessionTabHelper::IdForTab(contents); + if (!tab_id.is_valid()) return nullptr; connector = new CastRemotingConnector( media_router::MediaRouterFactory::GetApiForBrowserContext( @@ -157,7 +157,7 @@ } CastRemotingConnector::CastRemotingConnector(media_router::MediaRouter* router, - int32_t tab_id) + SessionID tab_id) : media_router_(router), tab_id_(tab_id), active_bridge_(nullptr),
diff --git a/chrome/browser/media/cast_remoting_connector.h b/chrome/browser/media/cast_remoting_connector.h index 1fe3f7c..6a53a34 100644 --- a/chrome/browser/media/cast_remoting_connector.h +++ b/chrome/browser/media/cast_remoting_connector.h
@@ -9,6 +9,7 @@ #include "base/memory/weak_ptr.h" #include "base/supports_user_data.h" +#include "components/sessions/core/session_id.h" #include "media/mojo/interfaces/mirror_service_remoting.mojom.h" #include "media/mojo/interfaces/remoting.mojom.h" #include "mojo/public/cpp/bindings/binding.h" @@ -107,7 +108,7 @@ // Main constructor. |tab_id| refers to any remoted content managed // by this instance (i.e., any remoted content from one tab/WebContents). - CastRemotingConnector(media_router::MediaRouter* router, int32_t tab_id); + CastRemotingConnector(media_router::MediaRouter* router, SessionID tab_id); // Creates a RemotingBridge that implements the requested Remoter service, and // binds it to the interface |request|. @@ -163,7 +164,7 @@ media_router::MediaRouter* const media_router_; - const int32_t tab_id_; + const SessionID tab_id_; // Describes the remoting sink's metadata and the enabled features. The sink's // metadata is updated by the mirror service calling OnSinkAvailable() and
diff --git a/chrome/browser/media/cast_remoting_connector_unittest.cc b/chrome/browser/media/cast_remoting_connector_unittest.cc index 668e80e..2e15e81 100644 --- a/chrome/browser/media/cast_remoting_connector_unittest.cc +++ b/chrome/browser/media/cast_remoting_connector_unittest.cc
@@ -42,7 +42,7 @@ namespace { -constexpr int32_t kRemotingTabId = 2; +constexpr SessionID kRemotingTabId = SessionID::FromSerializedValue(2); RemotingSinkMetadataPtr GetDefaultSinkMetadata() { RemotingSinkMetadataPtr metadata = RemotingSinkMetadata::New(); @@ -63,21 +63,21 @@ FakeMediaRouter() : weak_factory_(this) {} ~FakeMediaRouter() final {} - void RegisterRemotingSource(int32_t tab_id, + void RegisterRemotingSource(SessionID tab_id, CastRemotingConnector* remoting_source) final { - EXPECT_EQ(-1, tab_id_); + EXPECT_FALSE(tab_id_.is_valid()); tab_id_ = tab_id; connector_ = remoting_source; } - void UnregisterRemotingSource(int32_t tab_id) final { + void UnregisterRemotingSource(SessionID tab_id) final { EXPECT_EQ(tab_id, tab_id_); - tab_id_ = -1; + tab_id_ = SessionID::InvalidValue(); connector_ = nullptr; } void OnMediaRemoterCreated( - int32_t tab_id, + SessionID tab_id, MirrorServiceRemoterPtr remoter, MirrorServiceRemotingSourceRequest remoting_source) { if (tab_id != tab_id_) @@ -89,10 +89,10 @@ } // Get the registered tab ID. - int32_t tab_id() const { return tab_id_; } + SessionID tab_id() const { return tab_id_; } private: - int32_t tab_id_ = -1; + SessionID tab_id_ = SessionID::InvalidValue(); CastRemotingConnector* connector_ = nullptr; base::WeakPtrFactory<FakeMediaRouter> weak_factory_;
diff --git a/chrome/browser/media/router/media_router.h b/chrome/browser/media/router/media_router.h index 7413fd2a..85b9f720 100644 --- a/chrome/browser/media/router/media_router.h +++ b/chrome/browser/media/router/media_router.h
@@ -21,6 +21,7 @@ #include "chrome/common/media_router/media_sink.h" #include "chrome/common/media_router/media_source.h" #include "components/keyed_service/core/keyed_service.h" +#include "components/sessions/core/session_id.h" #include "content/public/browser/media_controller.h" #include "content/public/browser/presentation_service_delegate.h" @@ -205,9 +206,9 @@ // given |tab_id|, only one CastRemotingConnector can be registered. The // registered CastRemotingConnector should be removed before it is destroyed. virtual void RegisterRemotingSource( - int32_t tab_id, + SessionID tab_id, CastRemotingConnector* remoting_source) = 0; - virtual void UnregisterRemotingSource(int32_t tab_id) = 0; + virtual void UnregisterRemotingSource(SessionID tab_id) = 0; // Returns media router state as a JSON string represented by base::Vaule. // Used by media-router-internals page.
diff --git a/chrome/browser/media/router/media_router_base.cc b/chrome/browser/media/router/media_router_base.cc index 66554a0ef..ec72ea79 100644 --- a/chrome/browser/media/router/media_router_base.cc +++ b/chrome/browser/media/router/media_router_base.cc
@@ -174,7 +174,7 @@ #endif // !defined(OS_ANDROID) void MediaRouterBase::RegisterRemotingSource( - int32_t tab_id, + SessionID tab_id, CastRemotingConnector* remoting_source) { auto it = remoting_sources_.find(tab_id); if (it != remoting_sources_.end()) { @@ -184,7 +184,7 @@ remoting_sources_.emplace(tab_id, remoting_source); } -void MediaRouterBase::UnregisterRemotingSource(int32_t tab_id) { +void MediaRouterBase::UnregisterRemotingSource(SessionID tab_id) { auto it = remoting_sources_.find(tab_id); DCHECK(it != remoting_sources_.end()); remoting_sources_.erase(it);
diff --git a/chrome/browser/media/router/media_router_base.h b/chrome/browser/media/router/media_router_base.h index 9827a37..6859a2f 100644 --- a/chrome/browser/media/router/media_router_base.h +++ b/chrome/browser/media/router/media_router_base.h
@@ -40,9 +40,9 @@ scoped_refptr<MediaRouteController> GetRouteController( const MediaRoute::Id& route_id) override; #endif // !defined(OS_ANDROID) - void RegisterRemotingSource(int32_t tab_id, + void RegisterRemotingSource(SessionID tab_id, CastRemotingConnector* remoting_source) override; - void UnregisterRemotingSource(int32_t tab_id) override; + void UnregisterRemotingSource(SessionID tab_id) override; base::Value GetState() const override; protected: @@ -85,7 +85,8 @@ // Stores CastRemotingConnectors that can be connected to the MediaRemoter // for media remoting when MediaRemoter is started. The map uses the tab ID // as the key. - std::unordered_map<int32_t, CastRemotingConnector*> remoting_sources_; + std::unordered_map<SessionID, CastRemotingConnector*, SessionID::Hasher> + remoting_sources_; private: friend class MediaRouterBaseTest;
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc index 3432134..74f6187 100644 --- a/chrome/browser/media/router/mojo/media_router_mojo_impl.cc +++ b/chrome/browser/media/router/mojo/media_router_mojo_impl.cc
@@ -213,7 +213,7 @@ provider_id = MediaRouteProviderId::EXTENSION; } - int tab_id = SessionTabHelper::IdForTab(web_contents); + int tab_id = SessionTabHelper::IdForTab(web_contents).id(); std::string presentation_id = MediaRouterBase::CreatePresentationId(); auto callback = base::BindOnce( &MediaRouterMojoImpl::RouteResponseReceived, weak_factory_.GetWeakPtr(), @@ -246,7 +246,7 @@ return; } - int tab_id = SessionTabHelper::IdForTab(web_contents); + int tab_id = SessionTabHelper::IdForTab(web_contents).id(); auto callback = base::BindOnce( &MediaRouterMojoImpl::RouteResponseReceived, weak_factory_.GetWeakPtr(), presentation_id, *provider_id, incognito, std::move(callbacks), true); @@ -273,7 +273,7 @@ return; } - int tab_id = SessionTabHelper::IdForTab(web_contents); + int tab_id = SessionTabHelper::IdForTab(web_contents).id(); std::string presentation_id = MediaRouterBase::CreatePresentationId(); auto callback = base::BindOnce( &MediaRouterMojoImpl::RouteResponseReceived, weak_factory_.GetWeakPtr(), @@ -901,7 +901,7 @@ media::mojom::MirrorServiceRemotingSourceRequest source_request) { DVLOG_WITH_INSTANCE(1) << __func__ << ": tab_id = " << tab_id; - auto it = remoting_sources_.find(tab_id); + auto it = remoting_sources_.find(SessionID::FromSerializedValue(tab_id)); if (it == remoting_sources_.end()) { LOG(WARNING) << __func__ << ": No registered remoting source for tab_id = " << tab_id;
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc index da3c439..3d106b1 100644 --- a/chrome/browser/metrics/chrome_metrics_service_client.cc +++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -587,7 +587,11 @@ if (IsMetricsReportingForceEnabled() || base::FeatureList::IsEnabled(ukm::kUkmFeature)) { - ukm_service_.reset(new ukm::UkmService(local_state, this)); + // We only need to restrict to whitelisted Entries if metrics reporting + // is not forced. + bool restrict_to_whitelist_entries = !IsMetricsReportingForceEnabled(); + ukm_service_.reset( + new ukm::UkmService(local_state, this, restrict_to_whitelist_entries)); ukm_service_->SetIsWebstoreExtensionCallback( base::BindRepeating(&IsWebstoreExtension)); RegisterUKMProviders();
diff --git a/chrome/browser/net/trial_comparison_cert_verifier.h b/chrome/browser/net/trial_comparison_cert_verifier.h index f7a05a7..7d3f2f83 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier.h +++ b/chrome/browser/net/trial_comparison_cert_verifier.h
@@ -17,7 +17,7 @@ class CertVerifyProc; } -class NET_EXPORT TrialComparisonCertVerifier : public net::CertVerifier { +class TrialComparisonCertVerifier : public net::CertVerifier { public: // These values are persisted to logs. Entries should not be renumbered and // numeric values should never be reused.
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc b/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc index 6c80be0..da25185 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier_unittest.cc
@@ -181,22 +181,17 @@ net::X509Certificate::FORMAT_AUTO); ASSERT_TRUE(cert_chain_2_); - reporting_service_test_helper_.SetUpInterceptor(); + reporting_service_test_helper_ = + base::MakeRefCounted<CertificateReportingServiceTestHelper>(); CertificateReportingServiceFactory::GetInstance() ->SetReportEncryptionParamsForTesting( reporting_service_test_helper()->server_public_key(), reporting_service_test_helper()->server_public_key_version()); + CertificateReportingServiceFactory::GetInstance() + ->SetURLLoaderFactoryForTesting(reporting_service_test_helper_); reporting_service_test_helper()->SetFailureMode( certificate_reporting_test_utils::REPORTS_SUCCESSFUL); - url_request_context_getter_ = - base::MakeRefCounted<net::TestURLRequestContextGetter>( - (content::BrowserThread::GetTaskRunnerForThread( - content::BrowserThread::IO))); - - TestingBrowserProcess::GetGlobal()->SetSystemRequestContext( - url_request_context_getter_.get()); - sb_service_ = base::MakeRefCounted<safe_browsing::TestSafeBrowsingService>( // Doesn't matter, just need to choose one. safe_browsing::V4FeatureList::V4UsageStatus::V4_DISABLED); @@ -236,7 +231,7 @@ } CertificateReportingServiceTestHelper* reporting_service_test_helper() { - return &reporting_service_test_helper_; + return reporting_service_test_helper_.get(); } CertificateReportingService* service() const { @@ -252,12 +247,12 @@ private: content::TestBrowserThreadBundle thread_bundle_; - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; scoped_refptr<safe_browsing::SafeBrowsingService> sb_service_; std::unique_ptr<TestingProfileManager> profile_manager_; TestingProfile* profile_; - CertificateReportingServiceTestHelper reporting_service_test_helper_; + scoped_refptr<CertificateReportingServiceTestHelper> + reporting_service_test_helper_; }; TEST_F(TrialComparisonCertVerifierTest, NotOptedIn) {
diff --git a/chrome/browser/notifications/chrome_ash_message_center_client.cc b/chrome/browser/notifications/chrome_ash_message_center_client.cc index 9d77aa0..1fae3b1 100644 --- a/chrome/browser/notifications/chrome_ash_message_center_client.cc +++ b/chrome/browser/notifications/chrome_ash_message_center_client.cc
@@ -6,6 +6,7 @@ #include "ash/public/interfaces/constants.mojom.h" #include "base/i18n/string_compare.h" +#include "base/stl_util.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/notifications/arc_application_notifier_controller_chromeos.h" #include "chrome/browser/notifications/extension_notifier_controller.h" @@ -20,6 +21,9 @@ namespace { +// The singleton instance, which is tracked to allow access from tests. +ChromeAshMessageCenterClient* g_chrome_ash_message_center_client = nullptr; + // All notifier actions are performed on the notifiers for the currently active // profile, so this just returns the active profile. Profile* GetProfileForNotifiers() { @@ -51,6 +55,9 @@ ChromeAshMessageCenterClient::ChromeAshMessageCenterClient( NotificationPlatformBridgeDelegate* delegate) : delegate_(delegate), binding_(this) { + DCHECK(!g_chrome_ash_message_center_client); + g_chrome_ash_message_center_client = this; + // May be null in unit tests. auto* connection = content::ServiceManagerConnection::GetForProcess(); if (connection) { @@ -77,7 +84,10 @@ new arc::ArcApplicationNotifierControllerChromeOS(this)))); } -ChromeAshMessageCenterClient::~ChromeAshMessageCenterClient() {} +ChromeAshMessageCenterClient::~ChromeAshMessageCenterClient() { + DCHECK_EQ(this, g_chrome_ash_message_center_client); + g_chrome_ash_message_center_client = nullptr; +} // The unused variables here will not be a part of the future // NotificationPlatformBridge interface. @@ -86,7 +96,18 @@ Profile* /* profile */, const message_center::Notification& notification, std::unique_ptr<NotificationCommon::Metadata> metadata) { - controller_->ShowClientNotification(notification); + // Remove any previous mapping to |notification.id()| before inserting a new + // one. + base::EraseIf( + displayed_notifications_, + [notification]( + const std::pair<base::UnguessableToken, std::string>& pair) { + return pair.second == notification.id(); + }); + + base::UnguessableToken token = base::UnguessableToken::Create(); + displayed_notifications_[token] = notification.id(); + controller_->ShowClientNotification(notification, token); } // The unused variable here will not be a part of the future @@ -113,9 +134,13 @@ } void ChromeAshMessageCenterClient::HandleNotificationClosed( - const std::string& id, + const base::UnguessableToken& display_token, bool by_user) { - delegate_->HandleNotificationClosed(id, by_user); + auto entry = displayed_notifications_.find(display_token); + if (entry != displayed_notifications_.end()) { + delegate_->HandleNotificationClosed(entry->second, by_user); + displayed_notifications_.erase(entry); + } } void ChromeAshMessageCenterClient::HandleNotificationClicked( @@ -180,3 +205,8 @@ if (controller_) controller_->NotifierEnabledChanged(notifier_id, enabled); } + +// static +void ChromeAshMessageCenterClient::FlushForTesting() { + g_chrome_ash_message_center_client->binding_.FlushForTesting(); +}
diff --git a/chrome/browser/notifications/chrome_ash_message_center_client.h b/chrome/browser/notifications/chrome_ash_message_center_client.h index 96cadb7d..8e953179 100644 --- a/chrome/browser/notifications/chrome_ash_message_center_client.h +++ b/chrome/browser/notifications/chrome_ash_message_center_client.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_NOTIFICATIONS_CHROME_ASH_MESSAGE_CENTER_CLIENT_H_ #include "ash/public/interfaces/ash_message_center_controller.mojom.h" +#include "base/unguessable_token.h" #include "chrome/browser/notifications/notification_platform_bridge.h" #include "chrome/browser/notifications/notification_platform_bridge_chromeos.h" #include "chrome/browser/notifications/notifier_controller.h" @@ -37,7 +38,8 @@ void SetReadyCallback(NotificationBridgeReadyCallback callback) override; // ash::mojom::AshMessageCenterClient: - void HandleNotificationClosed(const std::string& id, bool by_user) override; + void HandleNotificationClosed(const base::UnguessableToken& display_token, + bool by_user) override; void HandleNotificationClicked(const std::string& id) override; void HandleNotificationButtonClicked( const std::string& id, @@ -55,9 +57,20 @@ void OnNotifierEnabledChanged(const message_center::NotifierId& notifier_id, bool enabled) override; + // Flushs |binding_|. + static void FlushForTesting(); + private: NotificationPlatformBridgeDelegate* delegate_; + // A mapping from display token to notification ID. The display token is + // generated each time a notification is shown (even if a notification is + // displayed more than once). This allows |this| to drop out-of-order + // HandleNotificationClosed() calls (i.e. those that arrive after the + // notification has already been re-displayed/updated and refer to an earlier + // notification). + std::map<base::UnguessableToken, std::string> displayed_notifications_; + // Notifier source for each notifier type. std::map<message_center::NotifierId::NotifierType, std::unique_ptr<NotifierController>>
diff --git a/chrome/browser/notifications/chrome_ash_message_center_client_browsertest.cc b/chrome/browser/notifications/chrome_ash_message_center_client_browsertest.cc new file mode 100644 index 0000000..cec2feb3f --- /dev/null +++ b/chrome/browser/notifications/chrome_ash_message_center_client_browsertest.cc
@@ -0,0 +1,89 @@ +// Copyright 2018 The Chromium Authors. 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/notifications/chrome_ash_message_center_client.h" + +#include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" +#include "chrome/browser/notifications/notification_display_service.h" +#include "chrome/browser/notifications/notification_test_util.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/common/chrome_features.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "ui/message_center/public/cpp/notification_delegate.h" + +namespace { + +class ChromeAshMessageCenterClientBrowserTest : public InProcessBrowserTest { + public: + ChromeAshMessageCenterClientBrowserTest() = default; + ~ChromeAshMessageCenterClientBrowserTest() override = default; + + // InProcessBrowserTest overrides. + void SetUpInProcessBrowserTestFixture() override { + scoped_feature_list_.InitWithFeatures({features::kNativeNotifications}, {}); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; + + DISALLOW_COPY_AND_ASSIGN(ChromeAshMessageCenterClientBrowserTest); +}; + +class TestNotificationDelegate : public message_center::NotificationDelegate { + public: + TestNotificationDelegate() {} + + void Wait() { run_loop_.Run(); } + + void Close(bool by_user) override { + close_count_++; + run_loop_.Quit(); + } + + int close_count() const { return close_count_; } + + private: + ~TestNotificationDelegate() override {} + + base::RunLoop run_loop_; + int close_count_ = 0; + + DISALLOW_COPY_AND_ASSIGN(TestNotificationDelegate); +}; + +// Regression test for https://crbug.com/825141 that verifies out-of-order +// Display/Close pairs are handled correctly. +IN_PROC_BROWSER_TEST_F(ChromeAshMessageCenterClientBrowserTest, + DisplayCloseOrdering) { + auto delegate = base::MakeRefCounted<TestNotificationDelegate>(); + const std::string id("notification_identifier"); + message_center::Notification notification( + message_center::NOTIFICATION_TYPE_SIMPLE, id, base::string16(), + base::string16(), gfx::Image(), base::ASCIIToUTF16("display_source"), + GURL(), + message_center::NotifierId(message_center::NotifierId::SYSTEM_COMPONENT, + "notifier_id"), + {}, delegate); + + auto* display_service = + NotificationDisplayService::GetForProfile(browser()->profile()); + display_service->Display(NotificationHandler::Type::TRANSIENT, notification); + display_service->Close(NotificationHandler::Type::TRANSIENT, + notification.id()); + // The Close callback should be fired asynchronously, so there is no close + // yet. + EXPECT_EQ(0, delegate->close_count()); + + display_service->Display(NotificationHandler::Type::TRANSIENT, notification); + display_service->Close(NotificationHandler::Type::TRANSIENT, + notification.id()); + ChromeAshMessageCenterClient::FlushForTesting(); + + // Only one close logged because Display was called again before the first + // close arrived. + EXPECT_EQ(1, delegate->close_count()); +} + +} // namespace
diff --git a/chrome/browser/notifications/notification_platform_bridge_chromeos.cc b/chrome/browser/notifications/notification_platform_bridge_chromeos.cc index d7418430..adc31c79 100644 --- a/chrome/browser/notifications/notification_platform_bridge_chromeos.cc +++ b/chrome/browser/notifications/notification_platform_bridge_chromeos.cc
@@ -48,7 +48,12 @@ void NotificationPlatformBridgeChromeOs::Close( Profile* profile, const std::string& notification_id) { - impl_->Close(profile, notification_id); + // TODO(estade): we need |is_incognito| here. + const std::string profile_notification_id = + ProfileNotification::GetProfileNotificationId( + notification_id, NotificationUIManager::GetProfileID(profile)); + + impl_->Close(nullptr, profile_notification_id); } void NotificationPlatformBridgeChromeOs::GetDisplayed(
diff --git a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc index 3e80ef3..6bb4818 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client_unittest.cc
@@ -88,7 +88,7 @@ MOCK_METHOD3(FillReferrerChain, void(const GURL&, - int, + SessionID, safe_browsing::LoginReputationClientRequest::Frame*)); MOCK_METHOD0(IsExtendedReporting, bool()); MOCK_METHOD0(IsIncognito, bool());
diff --git a/chrome/browser/predictors/loading_data_collector_unittest.cc b/chrome/browser/predictors/loading_data_collector_unittest.cc index de49e26..e8bc28b 100644 --- a/chrome/browser/predictors/loading_data_collector_unittest.cc +++ b/chrome/browser/predictors/loading_data_collector_unittest.cc
@@ -74,7 +74,7 @@ EXPECT_FALSE(summary.always_revalidate); // Navigation_id elements should be unset by default. - EXPECT_EQ(-1, summary.navigation_id.tab_id); + EXPECT_FALSE(summary.navigation_id.tab_id.is_valid()); EXPECT_EQ(GURL(), summary.navigation_id.main_frame_url); } @@ -358,51 +358,52 @@ // Single navigation that will be recorded. Will check for duplicate // resources and also for number of resources saved. TEST_F(LoadingDataCollectorTest, SimpleNavigation) { + const SessionID kTabId = SessionID::FromSerializedValue(1); URLRequestSummary main_frame = - CreateURLRequestSummary(1, "http://www.google.com"); + CreateURLRequestSummary(kTabId, "http://www.google.com"); collector_->RecordURLRequest(main_frame); collector_->RecordURLResponse(main_frame); EXPECT_EQ(1U, collector_->inflight_navigations_.size()); std::vector<URLRequestSummary> resources; resources.push_back(CreateURLRequestSummary( - 1, "http://www.google.com", "http://google.com/style1.css", + kTabId, "http://www.google.com", "http://google.com/style1.css", content::RESOURCE_TYPE_STYLESHEET)); collector_->RecordURLResponse(resources.back()); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/script1.js", content::RESOURCE_TYPE_SCRIPT)); collector_->RecordURLResponse(resources.back()); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/script2.js", content::RESOURCE_TYPE_SCRIPT)); collector_->RecordURLResponse(resources.back()); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/script1.js", content::RESOURCE_TYPE_SCRIPT)); collector_->RecordURLResponse(resources.back()); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/image1.png", content::RESOURCE_TYPE_IMAGE)); collector_->RecordURLResponse(resources.back()); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/image2.png", content::RESOURCE_TYPE_IMAGE)); collector_->RecordURLResponse(resources.back()); resources.push_back(CreateURLRequestSummary( - 1, "http://www.google.com", "http://google.com/style2.css", + kTabId, "http://www.google.com", "http://google.com/style2.css", content::RESOURCE_TYPE_STYLESHEET)); collector_->RecordURLResponse(resources.back()); auto no_store = - CreateURLRequestSummary(1, "http://www.google.com", + CreateURLRequestSummary(kTabId, "http://www.google.com", "http://static.google.com/style2-no-store.css", content::RESOURCE_TYPE_STYLESHEET); no_store.is_no_store = true; collector_->RecordURLResponse(no_store); auto redirected = CreateURLRequestSummary( - 1, "http://www.google.com", "http://reader.google.com/style.css", + kTabId, "http://www.google.com", "http://reader.google.com/style.css", content::RESOURCE_TYPE_STYLESHEET); redirected.redirect_url = GURL("http://dev.null.google.com/style.css"); collector_->RecordURLRedirect(redirected); @@ -425,18 +426,20 @@ } TEST_F(LoadingDataCollectorTest, SimpleRedirect) { - URLRequestSummary fb1 = CreateURLRequestSummary(1, "http://fb.com/google"); + const SessionID kTabId = SessionID::FromSerializedValue(1); + URLRequestSummary fb1 = + CreateURLRequestSummary(kTabId, "http://fb.com/google"); collector_->RecordURLRequest(fb1); EXPECT_EQ(1U, collector_->inflight_navigations_.size()); URLRequestSummary fb2 = CreateRedirectRequestSummary( - 1, "http://fb.com/google", "http://facebook.com/google"); + kTabId, "http://fb.com/google", "http://facebook.com/google"); collector_->RecordURLRedirect(fb2); URLRequestSummary fb3 = CreateRedirectRequestSummary( - 1, "http://facebook.com/google", "https://facebook.com/google"); + kTabId, "http://facebook.com/google", "https://facebook.com/google"); collector_->RecordURLRedirect(fb3); URLRequestSummary fb4 = - CreateURLRequestSummary(1, "https://facebook.com/google"); + CreateURLRequestSummary(kTabId, "https://facebook.com/google"); collector_->RecordURLResponse(fb4); EXPECT_CALL( @@ -449,15 +452,20 @@ } TEST_F(LoadingDataCollectorTest, OnMainFrameRequest) { + const SessionID kTabId1 = SessionID::FromSerializedValue(1); + const SessionID kTabId2 = SessionID::FromSerializedValue(2); + const SessionID kTabId3 = SessionID::FromSerializedValue(3); + const SessionID kTabId4 = SessionID::FromSerializedValue(4); + URLRequestSummary summary1 = CreateURLRequestSummary( - 1, "http://www.google.com", "http://www.google.com", + kTabId1, "http://www.google.com", "http://www.google.com", content::RESOURCE_TYPE_MAIN_FRAME); URLRequestSummary summary2 = CreateURLRequestSummary( - 2, "http://www.google.com", "http://www.google.com", + kTabId2, "http://www.google.com", "http://www.google.com", content::RESOURCE_TYPE_MAIN_FRAME); - URLRequestSummary summary3 = - CreateURLRequestSummary(3, "http://www.yahoo.com", "http://www.yahoo.com", - content::RESOURCE_TYPE_MAIN_FRAME); + URLRequestSummary summary3 = CreateURLRequestSummary( + kTabId3, "http://www.yahoo.com", "http://www.yahoo.com", + content::RESOURCE_TYPE_MAIN_FRAME); collector_->RecordURLRequest(summary1); EXPECT_EQ(1U, collector_->inflight_navigations_.size()); @@ -467,11 +475,11 @@ EXPECT_EQ(3U, collector_->inflight_navigations_.size()); // Insert another with same navigation id. It should replace. - URLRequestSummary summary4 = - CreateURLRequestSummary(1, "http://www.nike.com", "http://www.nike.com", - content::RESOURCE_TYPE_MAIN_FRAME); + URLRequestSummary summary4 = CreateURLRequestSummary( + kTabId1, "http://www.nike.com", "http://www.nike.com", + content::RESOURCE_TYPE_MAIN_FRAME); URLRequestSummary summary5 = CreateURLRequestSummary( - 2, "http://www.google.com", "http://www.google.com", + kTabId2, "http://www.google.com", "http://www.google.com", content::RESOURCE_TYPE_MAIN_FRAME); collector_->RecordURLRequest(summary4); @@ -483,9 +491,9 @@ collector_->RecordURLRequest(summary5); EXPECT_EQ(3U, collector_->inflight_navigations_.size()); - URLRequestSummary summary6 = - CreateURLRequestSummary(4, "http://www.shoes.com", "http://www.shoes.com", - content::RESOURCE_TYPE_MAIN_FRAME); + URLRequestSummary summary6 = CreateURLRequestSummary( + kTabId4, "http://www.shoes.com", "http://www.shoes.com", + content::RESOURCE_TYPE_MAIN_FRAME); collector_->RecordURLRequest(summary6); EXPECT_EQ(3U, collector_->inflight_navigations_.size()); @@ -498,35 +506,43 @@ } TEST_F(LoadingDataCollectorTest, OnMainFrameRedirect) { - URLRequestSummary yahoo = CreateURLRequestSummary(1, "http://yahoo.com"); + const SessionID kTabId1 = SessionID::FromSerializedValue(1); + const SessionID kTabId2 = SessionID::FromSerializedValue(2); + const SessionID kTabId3 = SessionID::FromSerializedValue(3); + const SessionID kTabId4 = SessionID::FromSerializedValue(4); + const SessionID kTabId5 = SessionID::FromSerializedValue(5); - URLRequestSummary bbc1 = CreateURLRequestSummary(2, "http://bbc.com"); - URLRequestSummary bbc2 = - CreateRedirectRequestSummary(2, "http://bbc.com", "https://www.bbc.com"); - NavigationID bbc_end = CreateNavigationID(2, "https://www.bbc.com"); + URLRequestSummary yahoo = + CreateURLRequestSummary(kTabId1, "http://yahoo.com"); - URLRequestSummary youtube1 = CreateURLRequestSummary(3, "http://youtube.com"); + URLRequestSummary bbc1 = CreateURLRequestSummary(kTabId2, "http://bbc.com"); + URLRequestSummary bbc2 = CreateRedirectRequestSummary( + kTabId2, "http://bbc.com", "https://www.bbc.com"); + NavigationID bbc_end = CreateNavigationID(kTabId2, "https://www.bbc.com"); + + URLRequestSummary youtube1 = + CreateURLRequestSummary(kTabId3, "http://youtube.com"); URLRequestSummary youtube2 = CreateRedirectRequestSummary( - 3, "http://youtube.com", "https://youtube.com"); - NavigationID youtube_end = CreateNavigationID(3, "https://youtube.com"); + kTabId3, "http://youtube.com", "https://youtube.com"); + NavigationID youtube_end = CreateNavigationID(kTabId3, "https://youtube.com"); - URLRequestSummary nyt1 = CreateURLRequestSummary(4, "http://nyt.com"); - URLRequestSummary nyt2 = - CreateRedirectRequestSummary(4, "http://nyt.com", "http://nytimes.com"); - URLRequestSummary nyt3 = CreateRedirectRequestSummary(4, "http://nytimes.com", - "http://m.nytimes.com"); - NavigationID nyt_end = CreateNavigationID(4, "http://m.nytimes.com"); + URLRequestSummary nyt1 = CreateURLRequestSummary(kTabId4, "http://nyt.com"); + URLRequestSummary nyt2 = CreateRedirectRequestSummary( + kTabId4, "http://nyt.com", "http://nytimes.com"); + URLRequestSummary nyt3 = CreateRedirectRequestSummary( + kTabId4, "http://nytimes.com", "http://m.nytimes.com"); + NavigationID nyt_end = CreateNavigationID(kTabId4, "http://m.nytimes.com"); - URLRequestSummary fb1 = CreateURLRequestSummary(5, "http://fb.com"); - URLRequestSummary fb2 = - CreateRedirectRequestSummary(5, "http://fb.com", "http://facebook.com"); - URLRequestSummary fb3 = CreateRedirectRequestSummary(5, "http://facebook.com", - "https://facebook.com"); + URLRequestSummary fb1 = CreateURLRequestSummary(kTabId5, "http://fb.com"); + URLRequestSummary fb2 = CreateRedirectRequestSummary(kTabId5, "http://fb.com", + "http://facebook.com"); + URLRequestSummary fb3 = CreateRedirectRequestSummary( + kTabId5, "http://facebook.com", "https://facebook.com"); URLRequestSummary fb4 = CreateRedirectRequestSummary( - 5, "https://facebook.com", + kTabId5, "https://facebook.com", "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr"); NavigationID fb_end = CreateNavigationID( - 5, + kTabId5, "https://m.facebook.com/?refsrc=https%3A%2F%2Fwww.facebook.com%2F&_rdr"); // Redirect with empty redirect_url will be deleted. @@ -572,26 +588,27 @@ } TEST_F(LoadingDataCollectorTest, OnSubresourceResponse) { + const SessionID kTabId = SessionID::FromSerializedValue(1); // If there is no inflight navigation, nothing happens. URLRequestSummary resource1 = CreateURLRequestSummary( - 1, "http://www.google.com", "http://google.com/style1.css", + kTabId, "http://www.google.com", "http://google.com/style1.css", content::RESOURCE_TYPE_STYLESHEET); collector_->RecordURLResponse(resource1); EXPECT_TRUE(collector_->inflight_navigations_.empty()); // Add an inflight navigation. URLRequestSummary main_frame1 = CreateURLRequestSummary( - 1, "http://www.google.com", "http://www.google.com", + kTabId, "http://www.google.com", "http://www.google.com", content::RESOURCE_TYPE_MAIN_FRAME); collector_->RecordURLRequest(main_frame1); EXPECT_EQ(1U, collector_->inflight_navigations_.size()); // Now add a few subresources. URLRequestSummary resource2 = CreateURLRequestSummary( - 1, "http://www.google.com", "http://google.com/script1.js", + kTabId, "http://www.google.com", "http://google.com/script1.js", content::RESOURCE_TYPE_SCRIPT); URLRequestSummary resource3 = CreateURLRequestSummary( - 1, "http://www.google.com", "http://google.com/script2.js", + kTabId, "http://www.google.com", "http://google.com/script2.js", content::RESOURCE_TYPE_SCRIPT); collector_->RecordURLResponse(resource1); collector_->RecordURLResponse(resource2);
diff --git a/chrome/browser/predictors/loading_predictor_unittest.cc b/chrome/browser/predictors/loading_predictor_unittest.cc index 2836ecb..c6965fd8 100644 --- a/chrome/browser/predictors/loading_predictor_unittest.cc +++ b/chrome/browser/predictors/loading_predictor_unittest.cc
@@ -176,7 +176,8 @@ predictor_->PrepareForPageLoad(url, HintOrigin::EXTERNAL); EXPECT_EQ(1UL, predictor_->active_hints_.size()); - auto summary = CreateURLRequestSummary(12, url.spec()); + auto summary = + CreateURLRequestSummary(SessionID::FromSerializedValue(12), url.spec()); predictor_->OnMainFrameResponse(summary); EXPECT_TRUE(predictor_->active_hints_.empty()); } @@ -184,7 +185,7 @@ TEST_F(LoadingPredictorTest, TestMainFrameRequestCancelsStaleNavigations) { const std::string url = kUrl; const std::string url2 = kUrl2; - const int tab_id = 12; + const SessionID tab_id = SessionID::FromSerializedValue(12); const auto& active_navigations = predictor_->active_navigations_; const auto& active_hints = predictor_->active_hints_; @@ -207,7 +208,7 @@ TEST_F(LoadingPredictorTest, TestMainFrameResponseClearsNavigations) { const std::string url = kUrl; const std::string redirected = kUrl2; - const int tab_id = 12; + const SessionID tab_id = SessionID::FromSerializedValue(12); const auto& active_navigations = predictor_->active_navigations_; const auto& active_hints = predictor_->active_hints_; @@ -240,7 +241,7 @@ TEST_F(LoadingPredictorTest, TestMainFrameRequestDoesntCancelExternalHint) { const GURL url = GURL(kUrl); - const int tab_id = 12; + const SessionID tab_id = SessionID::FromSerializedValue(12); const auto& active_navigations = predictor_->active_navigations_; auto& active_hints = predictor_->active_hints_;
diff --git a/chrome/browser/predictors/loading_stats_collector_unittest.cc b/chrome/browser/predictors/loading_stats_collector_unittest.cc index 6bb6794a..4508b12 100644 --- a/chrome/browser/predictors/loading_stats_collector_unittest.cc +++ b/chrome/browser/predictors/loading_stats_collector_unittest.cc
@@ -81,8 +81,9 @@ .WillOnce(DoAll(SetArgPointee<1>(prediction), Return(true))); // Navigation simulation. - URLRequestSummary script = CreateURLRequestSummary( - 1, navigation_url, script_url, content::RESOURCE_TYPE_SCRIPT); + URLRequestSummary script = + CreateURLRequestSummary(SessionID::FromSerializedValue(1), navigation_url, + script_url, content::RESOURCE_TYPE_SCRIPT); PageRequestSummary summary = CreatePageRequestSummary(navigation_url, initial_url, {script}); @@ -113,10 +114,12 @@ // Simulate a page load with 2 resources, one we know, one we don't, plus we // know the main frame origin. - URLRequestSummary script = CreateURLRequestSummary( - 1, main_frame_url, gen(1), content::RESOURCE_TYPE_SCRIPT); - URLRequestSummary new_script = CreateURLRequestSummary( - 1, main_frame_url, gen(100), content::RESOURCE_TYPE_SCRIPT); + URLRequestSummary script = + CreateURLRequestSummary(SessionID::FromSerializedValue(1), main_frame_url, + gen(1), content::RESOURCE_TYPE_SCRIPT); + URLRequestSummary new_script = + CreateURLRequestSummary(SessionID::FromSerializedValue(1), main_frame_url, + gen(100), content::RESOURCE_TYPE_SCRIPT); PageRequestSummary summary = CreatePageRequestSummary( main_frame_url, main_frame_url, {script, new_script}); @@ -158,6 +161,7 @@ TEST_F(LoadingStatsCollectorTest, TestPreconnectHistograms) { const std::string main_frame_url("http://google.com/?query=cats"); + const SessionID kTabId = SessionID::FromSerializedValue(1); auto gen = [](int index) { return base::StringPrintf("http://cdn%d.google.com/script.js", index); }; @@ -184,11 +188,11 @@ { // Simulate a page load with 3 origins. URLRequestSummary script1 = CreateURLRequestSummary( - 1, main_frame_url, gen(1), content::RESOURCE_TYPE_SCRIPT); + kTabId, main_frame_url, gen(1), content::RESOURCE_TYPE_SCRIPT); URLRequestSummary script2 = CreateURLRequestSummary( - 1, main_frame_url, gen(2), content::RESOURCE_TYPE_SCRIPT); + kTabId, main_frame_url, gen(2), content::RESOURCE_TYPE_SCRIPT); URLRequestSummary script100 = CreateURLRequestSummary( - 1, main_frame_url, gen(100), content::RESOURCE_TYPE_SCRIPT); + kTabId, main_frame_url, gen(100), content::RESOURCE_TYPE_SCRIPT); PageRequestSummary summary = CreatePageRequestSummary( main_frame_url, main_frame_url, {script1, script2, script100}); @@ -209,6 +213,7 @@ // empty. TEST_F(LoadingStatsCollectorTest, TestPreconnectHistogramsEmpty) { const std::string main_frame_url = "http://google.com"; + const SessionID kTabId = SessionID::FromSerializedValue(1); auto stats = std::make_unique<PreconnectStats>(GURL(main_frame_url)); stats_collector_->RecordPreconnectStats(std::move(stats)); @@ -217,7 +222,7 @@ .WillOnce(Return(false)); URLRequestSummary script = CreateURLRequestSummary( - 1, main_frame_url, "http://cdn.google.com/script.js", + kTabId, main_frame_url, "http://cdn.google.com/script.js", content::RESOURCE_TYPE_SCRIPT); PageRequestSummary summary = CreatePageRequestSummary(main_frame_url, main_frame_url, {script}); @@ -238,6 +243,7 @@ // preresolve attempts only. TEST_F(LoadingStatsCollectorTest, TestPreconnectHistogramsPreresolvesOnly) { const std::string main_frame_url("http://google.com/?query=cats"); + const SessionID kTabId = SessionID::FromSerializedValue(1); auto gen = [](int index) { return base::StringPrintf("http://cdn%d.google.com/script.js", index); }; @@ -264,11 +270,11 @@ { // Simulate a page load with 3 origins. URLRequestSummary script1 = CreateURLRequestSummary( - 1, main_frame_url, gen(1), content::RESOURCE_TYPE_SCRIPT); + kTabId, main_frame_url, gen(1), content::RESOURCE_TYPE_SCRIPT); URLRequestSummary script2 = CreateURLRequestSummary( - 1, main_frame_url, gen(2), content::RESOURCE_TYPE_SCRIPT); + kTabId, main_frame_url, gen(2), content::RESOURCE_TYPE_SCRIPT); URLRequestSummary script100 = CreateURLRequestSummary( - 1, main_frame_url, gen(100), content::RESOURCE_TYPE_SCRIPT); + kTabId, main_frame_url, gen(100), content::RESOURCE_TYPE_SCRIPT); PageRequestSummary summary = CreatePageRequestSummary( main_frame_url, main_frame_url, {script1, script2, script100});
diff --git a/chrome/browser/predictors/loading_test_util.cc b/chrome/browser/predictors/loading_test_util.cc index 1c20740..057d5016 100644 --- a/chrome/browser/predictors/loading_test_util.cc +++ b/chrome/browser/predictors/loading_test_util.cc
@@ -79,7 +79,7 @@ return data; } -NavigationID CreateNavigationID(SessionID::id_type tab_id, +NavigationID CreateNavigationID(SessionID tab_id, const std::string& main_frame_url) { NavigationID navigation_id; navigation_id.tab_id = tab_id; @@ -95,13 +95,14 @@ GURL main_frame_gurl(main_frame_url); PageRequestSummary summary(main_frame_gurl); summary.initial_url = GURL(initial_url); - summary.UpdateOrAddToOrigins(CreateURLRequestSummary(1, main_frame_url)); + summary.UpdateOrAddToOrigins(CreateURLRequestSummary( + SessionID::FromSerializedValue(1), main_frame_url)); for (auto& request_summary : subresource_requests) summary.UpdateOrAddToOrigins(request_summary); return summary; } -URLRequestSummary CreateURLRequestSummary(SessionID::id_type tab_id, +URLRequestSummary CreateURLRequestSummary(SessionID tab_id, const std::string& main_frame_url, const std::string& request_url, content::ResourceType resource_type, @@ -121,7 +122,7 @@ } URLRequestSummary CreateRedirectRequestSummary( - SessionID::id_type session_id, + SessionID session_id, const std::string& main_frame_url, const std::string& redirect_url) { URLRequestSummary summary =
diff --git a/chrome/browser/predictors/loading_test_util.h b/chrome/browser/predictors/loading_test_util.h index 62d4a903..ce5fab8 100644 --- a/chrome/browser/predictors/loading_test_util.h +++ b/chrome/browser/predictors/loading_test_util.h
@@ -59,7 +59,7 @@ OriginData CreateOriginData(const std::string& host, uint64_t last_visit_time = 0); -NavigationID CreateNavigationID(SessionID::id_type tab_id, +NavigationID CreateNavigationID(SessionID tab_id, const std::string& main_frame_url); PageRequestSummary CreatePageRequestSummary( @@ -68,7 +68,7 @@ const std::vector<URLRequestSummary>& subresource_requests); URLRequestSummary CreateURLRequestSummary( - SessionID::id_type tab_id, + SessionID tab_id, const std::string& main_frame_url, const std::string& request_url = std::string(), content::ResourceType resource_type = content::RESOURCE_TYPE_MAIN_FRAME, @@ -76,7 +76,7 @@ bool always_revalidate = false); URLRequestSummary CreateRedirectRequestSummary( - SessionID::id_type session_id, + SessionID session_id, const std::string& main_frame_url, const std::string& redirect_url);
diff --git a/chrome/browser/predictors/resource_prefetch_common.cc b/chrome/browser/predictors/resource_prefetch_common.cc index 0dffc83..5f3020ac 100644 --- a/chrome/browser/predictors/resource_prefetch_common.cc +++ b/chrome/browser/predictors/resource_prefetch_common.cc
@@ -18,7 +18,7 @@ namespace predictors { -NavigationID::NavigationID() : tab_id(-1) {} +NavigationID::NavigationID() : tab_id(SessionID::InvalidValue()) {} NavigationID::NavigationID(const NavigationID& other) : tab_id(other.tab_id), @@ -38,7 +38,7 @@ creation_time(creation_time) {} bool NavigationID::is_valid() const { - return tab_id != -1 && !main_frame_url.is_empty(); + return tab_id.is_valid() && !main_frame_url.is_empty(); } bool NavigationID::operator<(const NavigationID& rhs) const {
diff --git a/chrome/browser/predictors/resource_prefetch_common.h b/chrome/browser/predictors/resource_prefetch_common.h index 7d72939..8edd401b 100644 --- a/chrome/browser/predictors/resource_prefetch_common.h +++ b/chrome/browser/predictors/resource_prefetch_common.h
@@ -33,7 +33,7 @@ // Returns true iff the tab_id is valid and the Main frame URL is set. bool is_valid() const; - SessionID::id_type tab_id; + SessionID tab_id; GURL main_frame_url; // NOTE: Even though we store the creation time here, it is not used during
diff --git a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc index bf8e16f..39a369b0 100644 --- a/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc +++ b/chrome/browser/predictors/resource_prefetch_predictor_unittest.cc
@@ -34,10 +34,13 @@ using testing::UnorderedElementsAre; namespace predictors { +namespace { using RedirectDataMap = std::map<std::string, RedirectData>; using OriginDataMap = std::map<std::string, OriginData>; +constexpr SessionID kTabId = SessionID::FromSerializedValue(1); + template <typename T> class FakeGlowplugKeyValueTable : public GlowplugKeyValueTable<T> { public: @@ -100,6 +103,8 @@ MOCK_METHOD1(OnNavigationLearned, void(const PageRequestSummary& summary)); }; +} // namespace + class ResourcePrefetchPredictorTest : public testing::Test { public: ResourcePrefetchPredictorTest(); @@ -248,39 +253,39 @@ // resources and also for number of resources saved. TEST_F(ResourcePrefetchPredictorTest, NavigationUrlNotInDB) { URLRequestSummary main_frame = - CreateURLRequestSummary(1, "http://www.google.com"); + CreateURLRequestSummary(kTabId, "http://www.google.com"); std::vector<URLRequestSummary> resources; resources.push_back(CreateURLRequestSummary( - 1, "http://www.google.com", "http://google.com/style1.css", + kTabId, "http://www.google.com", "http://google.com/style1.css", content::RESOURCE_TYPE_STYLESHEET)); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/script1.js", content::RESOURCE_TYPE_SCRIPT)); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/script2.js", content::RESOURCE_TYPE_SCRIPT)); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/script1.js", content::RESOURCE_TYPE_SCRIPT)); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/image1.png", content::RESOURCE_TYPE_IMAGE)); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/image2.png", content::RESOURCE_TYPE_IMAGE)); resources.push_back(CreateURLRequestSummary( - 1, "http://www.google.com", "http://google.com/style2.css", + kTabId, "http://www.google.com", "http://google.com/style2.css", content::RESOURCE_TYPE_STYLESHEET)); auto no_store = - CreateURLRequestSummary(1, "http://www.google.com", + CreateURLRequestSummary(kTabId, "http://www.google.com", "http://static.google.com/style2-no-store.css", content::RESOURCE_TYPE_STYLESHEET); no_store.is_no_store = true; auto redirected = CreateURLRequestSummary( - 1, "http://www.google.com", "http://reader.google.com/style.css", + kTabId, "http://www.google.com", "http://reader.google.com/style.css", content::RESOURCE_TYPE_STYLESHEET); redirected.redirect_url = GURL("http://dev.null.google.com/style.css"); @@ -330,33 +335,33 @@ InitializePredictor(); URLRequestSummary main_frame = CreateURLRequestSummary( - 1, "http://www.google.com", "http://www.google.com", + kTabId, "http://www.google.com", "http://www.google.com", content::RESOURCE_TYPE_MAIN_FRAME); std::vector<URLRequestSummary> resources; resources.push_back(CreateURLRequestSummary( - 1, "http://www.google.com", "http://google.com/style1.css", + kTabId, "http://www.google.com", "http://google.com/style1.css", content::RESOURCE_TYPE_STYLESHEET)); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/script1.js", content::RESOURCE_TYPE_SCRIPT)); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/script2.js", content::RESOURCE_TYPE_SCRIPT)); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/script1.js", content::RESOURCE_TYPE_SCRIPT)); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/image1.png", content::RESOURCE_TYPE_IMAGE)); - resources.push_back(CreateURLRequestSummary(1, "http://www.google.com", + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", "http://google.com/image2.png", content::RESOURCE_TYPE_IMAGE)); resources.push_back(CreateURLRequestSummary( - 1, "http://www.google.com", "http://google.com/style2.css", + kTabId, "http://www.google.com", "http://google.com/style2.css", content::RESOURCE_TYPE_STYLESHEET)); auto no_store = - CreateURLRequestSummary(1, "http://www.google.com", + CreateURLRequestSummary(kTabId, "http://www.google.com", "http://static.google.com/style2-no-store.css", content::RESOURCE_TYPE_STYLESHEET); no_store.is_no_store = true; @@ -397,15 +402,15 @@ ResetPredictor(); InitializePredictor(); - URLRequestSummary main_frame = - CreateURLRequestSummary(1, "http://www.nike.com", "http://www.nike.com", - content::RESOURCE_TYPE_MAIN_FRAME); + URLRequestSummary main_frame = CreateURLRequestSummary( + kTabId, "http://www.nike.com", "http://www.nike.com", + content::RESOURCE_TYPE_MAIN_FRAME); URLRequestSummary resource1 = CreateURLRequestSummary( - 1, "http://www.nike.com", "http://nike.com/style1.css", + kTabId, "http://www.nike.com", "http://nike.com/style1.css", content::RESOURCE_TYPE_STYLESHEET); URLRequestSummary resource2 = CreateURLRequestSummary( - 1, "http://www.nike.com", "http://nike.com/image2.png", + kTabId, "http://www.nike.com", "http://nike.com/image2.png", content::RESOURCE_TYPE_IMAGE); auto page_summary = CreatePageRequestSummary( @@ -439,7 +444,7 @@ TEST_F(ResourcePrefetchPredictorTest, NavigationManyResourcesWithDifferentOrigins) { URLRequestSummary main_frame = - CreateURLRequestSummary(1, "http://www.google.com"); + CreateURLRequestSummary(kTabId, "http://www.google.com"); auto gen = [](int i) { return base::StringPrintf("http://cdn%d.google.com/script.js", i); @@ -447,8 +452,9 @@ std::vector<URLRequestSummary> resources; const int num_resources = predictor_->config_.max_origins_per_entry + 10; for (int i = 1; i <= num_resources; ++i) { - resources.push_back(CreateURLRequestSummary( - 1, "http://www.google.com", gen(i), content::RESOURCE_TYPE_SCRIPT)); + resources.push_back(CreateURLRequestSummary(kTabId, "http://www.google.com", + gen(i), + content::RESOURCE_TYPE_SCRIPT)); } auto page_summary = CreatePageRequestSummary(
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc index 2803c562..ef60fd9 100644 --- a/chrome/browser/prefs/chrome_pref_service_factory.cc +++ b/chrome/browser/prefs/chrome_pref_service_factory.cc
@@ -17,6 +17,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram_macros.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "build/build_config.h" @@ -301,6 +302,12 @@ // Shows notifications which correspond to PersistentPrefStore's reading errors. void HandleReadError(const base::FilePath& pref_filename, PersistentPrefStore::PrefReadError error) { + // The error callback is always invoked back on the main thread (which is + // BrowserThread::UI unless called during early initialization before the main + // thread is promoted to BrowserThread::UI). + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI) || + !BrowserThread::IsThreadInitialized(BrowserThread::UI)); + // Sample the histogram also for the successful case in order to get a // baseline on the success rate in addition to the error distribution. UMA_HISTOGRAM_ENUMERATION("PrefService.ReadError", error, @@ -319,18 +326,14 @@ } if (message_id) { - auto show_profile_error_dialog = base::BindOnce( - &ShowProfileErrorDialog, ProfileErrorType::PREFERENCES, message_id, - sql::GetCorruptFileDiagnosticsInfo(pref_filename)); - if (BrowserThread::IsThreadInitialized(BrowserThread::UI)) { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - std::move(show_profile_error_dialog)); - } else { - // In early startup (e.g. on error loading Local State before most - // browser pieces are up), the only option is to show the dialog - // synchronously. - std::move(show_profile_error_dialog).Run(); - } + // Note: ThreadTaskRunnerHandle() is usually BrowserThread::UI but during + // early startup it can be ChromeBrowserMainParts::DeferringTaskRunner + // which will forward to BrowserThread::UI when it's initialized. + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&ShowProfileErrorDialog, ProfileErrorType::PREFERENCES, + message_id, + sql::GetCorruptFileDiagnosticsInfo(pref_filename))); } #else // On ChromeOS error screen with message about broken local state @@ -397,7 +400,8 @@ factory->set_command_line_prefs( base::MakeRefCounted<ChromeCommandLinePrefStore>( base::CommandLine::ForCurrentProcess())); - factory->set_read_error_callback(base::Bind(&HandleReadError, pref_filename)); + factory->set_read_error_callback( + base::BindRepeating(&HandleReadError, pref_filename)); factory->set_user_prefs(std::move(user_pref_store)); factory->SetPrefModelAssociatorClient( ChromePrefModelAssociatorClient::GetInstance());
diff --git a/chrome/browser/resource_coordinator/tab_manager.cc b/chrome/browser/resource_coordinator/tab_manager.cc index 0bed292..685ddba2 100644 --- a/chrome/browser/resource_coordinator/tab_manager.cc +++ b/chrome/browser/resource_coordinator/tab_manager.cc
@@ -260,11 +260,6 @@ return sorted_lifecycle_units; } -bool TabManager::IsTabDiscarded(content::WebContents* contents) const { - auto* lifecycle_unit = TabLifecycleUnitExternal::FromWebContents(contents); - return lifecycle_unit && lifecycle_unit->IsDiscarded(); -} - void TabManager::DiscardTab(DiscardReason reason) { if (reason == DiscardReason::kUrgent) stats_collector_->RecordWillDiscardUrgently(GetNumAliveTabs()); @@ -329,11 +324,6 @@ TabLifecycleUnitExternal::RemoveTabLifecycleObserver(observer); } -bool TabManager::IsTabAutoDiscardable(content::WebContents* contents) const { - auto* lifecycle_unit = TabLifecycleUnitExternal::FromWebContents(contents); - return !lifecycle_unit || lifecycle_unit->IsAutoDiscardable(); -} - void TabManager::SetTabAutoDiscardableState(int32_t tab_id, bool state) { for (LifecycleUnit* lifecycle_unit : lifecycle_units_) { if (lifecycle_unit->GetID() == tab_id) { @@ -477,7 +467,7 @@ bool TabManager::ShouldPurgeNow(content::WebContents* content) const { if (GetWebContentsData(content)->is_purged()) return false; - if (IsTabDiscarded(content)) + if (TabLifecycleUnitExternal::FromWebContents(content)->IsDiscarded()) return false; base::TimeDelta time_passed = @@ -880,7 +870,7 @@ TabStripModel* tab_strip_model = browser->tab_strip_model(); for (int index = 0; index < tab_strip_model->count(); ++index) { content::WebContents* contents = tab_strip_model->GetWebContentsAt(index); - if (!IsTabDiscarded(contents)) + if (!TabLifecycleUnitExternal::FromWebContents(contents)->IsDiscarded()) ++tab_count; } }
diff --git a/chrome/browser/resource_coordinator/tab_manager.h b/chrome/browser/resource_coordinator/tab_manager.h index 594b2ea..fa423ab 100644 --- a/chrome/browser/resource_coordinator/tab_manager.h +++ b/chrome/browser/resource_coordinator/tab_manager.h
@@ -98,9 +98,6 @@ // vector after a LifecycleUnit has been destroyed. LifecycleUnitVector GetSortedLifecycleUnits(); - // Returns true if |contents| is currently discarded. - bool IsTabDiscarded(content::WebContents* contents) const; - // Discards a tab to free the memory occupied by its renderer. The tab still // exists in the tab-strip; clicking on it will reload it. If the |reason| is // urgent, an aggressive fast-kill will be attempted if the sudden termination @@ -138,13 +135,6 @@ void AddObserver(TabLifecycleObserver* observer); void RemoveObserver(TabLifecycleObserver* observer); - // Returns the auto-discardable state of the tab. When true, the tab is - // eligible to be automatically discarded when critical memory pressure hits, - // otherwise the tab is ignored and will never be automatically discarded. - // Note that this property doesn't block the discarding of the tab via other - // methods (about:discards for instance). - bool IsTabAutoDiscardable(content::WebContents* contents) const; - // Sets/clears the auto-discardable state of the tab. void SetTabAutoDiscardableState(int32_t tab_id, bool state); void SetTabAutoDiscardableState(content::WebContents* contents, bool state);
diff --git a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc index 960fd945..a6da556 100644 --- a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
@@ -110,6 +110,10 @@ ->entry->GetURL() == expected_url; } +bool IsTabDiscarded(content::WebContents* web_contents) { + return TabLifecycleUnitExternal::FromWebContents(web_contents)->IsDiscarded(); +} + } // namespace IN_PROC_BROWSER_TEST_F(TabManagerTest, TabManagerBasics) { @@ -180,32 +184,32 @@ // and was not selected. EXPECT_TRUE(tab_manager->DiscardTabImpl(DiscardReason::kProactive)); EXPECT_EQ(3, tsm->count()); - EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1))); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2))); + EXPECT_TRUE(IsTabDiscarded(tsm->GetWebContentsAt(0))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(1))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(2))); // Run discard again, make sure it kills the second tab. EXPECT_TRUE(tab_manager->DiscardTabImpl(DiscardReason::kProactive)); EXPECT_EQ(3, tsm->count()); - EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0))); - EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1))); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2))); + EXPECT_TRUE(IsTabDiscarded(tsm->GetWebContentsAt(0))); + EXPECT_TRUE(IsTabDiscarded(tsm->GetWebContentsAt(1))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(2))); // Kill the third tab. It should not kill the last tab, since it is active // tab. EXPECT_FALSE(tab_manager->DiscardTabImpl(DiscardReason::kProactive)); - EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0))); - EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1))); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2))); + EXPECT_TRUE(IsTabDiscarded(tsm->GetWebContentsAt(0))); + EXPECT_TRUE(IsTabDiscarded(tsm->GetWebContentsAt(1))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(2))); // Kill the third tab after making second tab active. tsm->ActivateTabAt(1, true); EXPECT_EQ(1, tsm->active_index()); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(1))); FastForwardAfterDiscardProtectionTime(); tab_manager->DiscardTabImpl(DiscardReason::kProactive); - EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2))); + EXPECT_TRUE(IsTabDiscarded(tsm->GetWebContentsAt(2))); // Force creation of the FindBarController. browser()->GetFindBarController(); @@ -221,9 +225,9 @@ EXPECT_EQ(browser()->GetFindBarController()->web_contents(), tsm->GetActiveWebContents()); EXPECT_EQ(0, tsm->active_index()); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1))); - EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(0))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(1))); + EXPECT_TRUE(IsTabDiscarded(tsm->GetWebContentsAt(2))); // Select the third tab. It should reload. WindowedNotificationObserver reload2( @@ -232,9 +236,9 @@ chrome::SelectNumberedTab(browser(), 2); reload2.Wait(); EXPECT_EQ(2, tsm->active_index()); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1))); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(2))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(0))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(1))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(2))); // Navigate the third tab back twice. We used to crash here due to // crbug.com/121373. @@ -262,7 +266,6 @@ // Test that the MemoryPressureListener event is properly triggering a tab // discard upon |MEMORY_PRESSURE_LEVEL_CRITICAL| event. IN_PROC_BROWSER_TEST_F(TabManagerTest, OomPressureListener) { - TabManager* tab_manager = g_browser_process->GetTabManager(); TabStripModel* tsm = browser()->tab_strip_model(); // Get two tabs open. @@ -287,14 +290,14 @@ ASSERT_EQ(tsm->count(), 2); FastForwardAfterDiscardProtectionTime(); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(0))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(1))); // Nothing should happen with a moderate memory pressure event. base::MemoryPressureListener::NotifyMemoryPressure( base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(0))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(1))); // A critical memory pressure event should discard a tab. base::MemoryPressureListener::NotifyMemoryPressure( @@ -308,11 +311,11 @@ base::PlatformThread::Sleep( base::TimeDelta::FromMilliseconds(kIntervalTimeInMS)); base::RunLoop().RunUntilIdle(); - if (tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0))) + if (IsTabDiscarded(tsm->GetWebContentsAt(0))) break; } - EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(1))); + EXPECT_TRUE(IsTabDiscarded(tsm->GetWebContentsAt(0))); + EXPECT_FALSE(IsTabDiscarded(tsm->GetWebContentsAt(1))); } #endif @@ -536,7 +539,7 @@ // Now it should be able to discard the tab. EXPECT_TRUE(tab_manager->DiscardTabImpl(DiscardReason::kProactive)); - EXPECT_TRUE(tab_manager->IsTabDiscarded(tsm->GetWebContentsAt(0))); + EXPECT_TRUE(IsTabDiscarded(tsm->GetWebContentsAt(0))); } IN_PROC_BROWSER_TEST_F(TabManagerTest, PurgeBackgroundRenderer) { @@ -1090,34 +1093,28 @@ // On ChromeOS, active tabs are discarded if their window is non-visible. On // other platforms, they are never discarded. #if defined(OS_CHROMEOS) - EXPECT_TRUE(tab_manager->IsTabDiscarded( - browser1->tab_strip_model()->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded( - browser2->tab_strip_model()->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded( - browser3->tab_strip_model()->GetWebContentsAt(0))); - EXPECT_TRUE(tab_manager->IsTabDiscarded( - browser4->tab_strip_model()->GetWebContentsAt(0))); + EXPECT_TRUE(IsTabDiscarded(browser1->tab_strip_model()->GetWebContentsAt(0))); + EXPECT_FALSE( + IsTabDiscarded(browser2->tab_strip_model()->GetWebContentsAt(0))); + EXPECT_FALSE( + IsTabDiscarded(browser3->tab_strip_model()->GetWebContentsAt(0))); + EXPECT_TRUE(IsTabDiscarded(browser4->tab_strip_model()->GetWebContentsAt(0))); #else - EXPECT_FALSE(tab_manager->IsTabDiscarded( - browser1->tab_strip_model()->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded( - browser2->tab_strip_model()->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded( - browser3->tab_strip_model()->GetWebContentsAt(0))); - EXPECT_FALSE(tab_manager->IsTabDiscarded( - browser4->tab_strip_model()->GetWebContentsAt(0))); + EXPECT_FALSE( + IsTabDiscarded(browser1->tab_strip_model()->GetWebContentsAt(0))); + EXPECT_FALSE( + IsTabDiscarded(browser2->tab_strip_model()->GetWebContentsAt(0))); + EXPECT_FALSE( + IsTabDiscarded(browser3->tab_strip_model()->GetWebContentsAt(0))); + EXPECT_FALSE( + IsTabDiscarded(browser4->tab_strip_model()->GetWebContentsAt(0))); #endif // Non-active tabs can be discarded on all platforms. - EXPECT_TRUE(tab_manager->IsTabDiscarded( - browser1->tab_strip_model()->GetWebContentsAt(1))); - EXPECT_TRUE(tab_manager->IsTabDiscarded( - browser2->tab_strip_model()->GetWebContentsAt(1))); - EXPECT_TRUE(tab_manager->IsTabDiscarded( - browser3->tab_strip_model()->GetWebContentsAt(1))); - EXPECT_TRUE(tab_manager->IsTabDiscarded( - browser4->tab_strip_model()->GetWebContentsAt(1))); + EXPECT_TRUE(IsTabDiscarded(browser1->tab_strip_model()->GetWebContentsAt(1))); + EXPECT_TRUE(IsTabDiscarded(browser2->tab_strip_model()->GetWebContentsAt(1))); + EXPECT_TRUE(IsTabDiscarded(browser3->tab_strip_model()->GetWebContentsAt(1))); + EXPECT_TRUE(IsTabDiscarded(browser4->tab_strip_model()->GetWebContentsAt(1))); } } // namespace resource_coordinator
diff --git a/chrome/browser/resource_coordinator/tab_manager_unittest.cc b/chrome/browser/resource_coordinator/tab_manager_unittest.cc index fcecd96..e4c17164 100644 --- a/chrome/browser/resource_coordinator/tab_manager_unittest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_unittest.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/resource_coordinator/background_tab_navigation_throttle.h" +#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" #include "chrome/browser/resource_coordinator/tab_manager_features.h" #include "chrome/browser/resource_coordinator/tab_manager_resource_coordinator_signal_observer.h" #include "chrome/browser/resource_coordinator/tab_manager_stats_collector.h" @@ -130,6 +131,10 @@ kInternalPage, }; +bool IsTabDiscarded(content::WebContents* web_contents) { + return TabLifecycleUnitExternal::FromWebContents(web_contents)->IsDiscarded(); +} + } // namespace class TabManagerTest : public ChromeRenderViewHostTestHarness { @@ -434,20 +439,20 @@ tab_manager_->DiscardTab(DiscardReason::kProactive); // Active tab in a visible window should not be discarded. - EXPECT_FALSE(tab_manager_->IsTabDiscarded(tab_strip1->GetWebContentsAt(0))); + EXPECT_FALSE(IsTabDiscarded(tab_strip1->GetWebContentsAt(0))); // Non-active tabs should be discarded. - EXPECT_TRUE(tab_manager_->IsTabDiscarded(tab_strip1->GetWebContentsAt(1))); - EXPECT_TRUE(tab_manager_->IsTabDiscarded(tab_strip2->GetWebContentsAt(1))); + EXPECT_TRUE(IsTabDiscarded(tab_strip1->GetWebContentsAt(1))); + EXPECT_TRUE(IsTabDiscarded(tab_strip2->GetWebContentsAt(1))); #if defined(OS_CHROMEOS) // On ChromeOS, a non-visible tab should be discarded even if it's active in // its tab strip. - EXPECT_TRUE(tab_manager_->IsTabDiscarded(tab_strip2->GetWebContentsAt(0))); + EXPECT_TRUE(IsTabDiscarded(tab_strip2->GetWebContentsAt(0))); #else // On other platforms, an active tab is never discarded, even if it's not // visible. - EXPECT_FALSE(tab_manager_->IsTabDiscarded(tab_strip2->GetWebContentsAt(0))); + EXPECT_FALSE(IsTabDiscarded(tab_strip2->GetWebContentsAt(0))); #endif // defined(OS_CHROMEOS) // Tabs with a committed URL must be closed explicitly to avoid DCHECK errors.
diff --git a/chrome/browser/resource_coordinator/tab_metrics_logger.cc b/chrome/browser/resource_coordinator/tab_metrics_logger.cc index c7ab1dc5..9e990ec 100644 --- a/chrome/browser/resource_coordinator/tab_metrics_logger.cc +++ b/chrome/browser/resource_coordinator/tab_metrics_logger.cc
@@ -15,7 +15,7 @@ #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h" #include "chrome/browser/engagement/site_engagement_service.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/browser/resource_coordinator/tab_manager.h" +#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_list.h" @@ -236,10 +236,6 @@ // audio indicator in the tab strip. entry.SetWasRecentlyAudible(web_contents->WasRecentlyAudible()); - resource_coordinator::TabManager* tab_manager = - g_browser_process->GetTabManager(); - DCHECK(tab_manager); - PopulatePageTransitionMetrics(&entry, tab_metrics.page_transition); entry .SetHasBeforeUnloadHandler( @@ -247,9 +243,10 @@ blink::kBeforeUnloadHandler)) .SetHasFormEntry( web_contents->GetPageImportanceSignals().had_form_interaction) - // TODO(michaelpg): This dependency should be reversed during the - // resource_coordinator refactor: https://crbug.com/775644. - .SetIsExtensionProtected(!tab_manager->IsTabAutoDiscardable(web_contents)) + .SetIsExtensionProtected( + !resource_coordinator::TabLifecycleUnitExternal::FromWebContents( + web_contents) + ->IsAutoDiscardable()) .SetIsPinned(tab_strip_model->IsTabPinned(index)) .SetNavigationEntryCount(web_contents->GetController().GetEntryCount()) .SetSequenceId(++sequence_id_)
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service.cc b/chrome/browser/safe_browsing/certificate_reporting_service.cc index 9b4dd6b2..9bb9997 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service.cc +++ b/chrome/browser/safe_browsing/certificate_reporting_service.cc
@@ -14,7 +14,7 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "content/public/browser/browser_thread.h" -#include "net/traffic_annotation/network_traffic_annotation.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" namespace { @@ -44,11 +44,6 @@ CertificateReportingService::ReportOutcome::EVENT_COUNT); } -void CleanupOnIOThread( - std::unique_ptr<CertificateReportingService::Reporter> reporter) { - reporter.reset(); -} - } // namespace const char CertificateReportingService::kReportEventHistogram[] = @@ -110,12 +105,10 @@ void CertificateReportingService::Reporter::Send( const std::string& serialized_report) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); SendInternal(Report(current_report_id_++, clock_->Now(), serialized_report)); } void CertificateReportingService::Reporter::SendPending() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); if (!retries_enabled_) { return; } @@ -153,25 +146,27 @@ return retry_list_.get(); } +void CertificateReportingService::Reporter:: + SetClosureWhenNoInflightReportsForTesting(const base::Closure& closure) { + no_in_flight_reports_ = closure; +} + void CertificateReportingService::Reporter::SendInternal( const CertificateReportingService::Report& report) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); inflight_reports_.insert(std::make_pair(report.report_id, report)); RecordUMAEvent(ReportOutcome::SUBMITTED); error_reporter_->SendExtendedReportingReport( report.serialized_report, - base::Bind(&CertificateReportingService::Reporter::SuccessCallback, - weak_factory_.GetWeakPtr(), report.report_id), - base::Bind(&CertificateReportingService::Reporter::ErrorCallback, - weak_factory_.GetWeakPtr(), report.report_id)); + base::BindOnce(&CertificateReportingService::Reporter::SuccessCallback, + weak_factory_.GetWeakPtr(), report.report_id), + base::BindOnce(&CertificateReportingService::Reporter::ErrorCallback, + weak_factory_.GetWeakPtr(), report.report_id)); } void CertificateReportingService::Reporter::ErrorCallback( int report_id, - const GURL& url, int net_error, int http_response_code) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); RecordUMAOnFailure(net_error); RecordUMAEvent(ReportOutcome::FAILED); if (retries_enabled_) { @@ -180,17 +175,20 @@ retry_list_->Add(it->second); } CHECK_GT(inflight_reports_.erase(report_id), 0u); + if (inflight_reports_.empty() && no_in_flight_reports_) + no_in_flight_reports_.Run(); } void CertificateReportingService::Reporter::SuccessCallback(int report_id) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); RecordUMAEvent(ReportOutcome::SUCCESSFUL); CHECK_GT(inflight_reports_.erase(report_id), 0u); + if (inflight_reports_.empty() && no_in_flight_reports_) + no_in_flight_reports_.Run(); } CertificateReportingService::CertificateReportingService( safe_browsing::SafeBrowsingService* safe_browsing_service, - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, Profile* profile, uint8_t server_public_key[/* 32 */], uint32_t server_public_key_version, @@ -199,7 +197,7 @@ base::Clock* clock, const base::Callback<void()>& reset_callback) : pref_service_(*profile->GetPrefs()), - url_request_context_(nullptr), + url_loader_factory_(url_loader_factory), max_queued_report_count_(max_queued_report_count), max_report_age_(max_report_age), clock_(clock), @@ -208,10 +206,6 @@ server_public_key_version_(server_public_key_version) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); DCHECK(clock_); - // Subscribe to SafeBrowsing shutdown notifications. - safe_browsing_service_shutdown_subscription_ = - safe_browsing_service->RegisterShutdownCallback(base::Bind( - &CertificateReportingService::Shutdown, base::Unretained(this))); // Subscribe to SafeBrowsing preference change notifications. safe_browsing_state_subscription_ = @@ -219,13 +213,8 @@ base::Bind(&CertificateReportingService::OnPreferenceChanged, base::Unretained(this))); - content::BrowserThread::PostTaskAndReply( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&CertificateReportingService::InitializeOnIOThread, - base::Unretained(this), true, url_request_context_getter, - max_queued_report_count_, max_report_age_, clock_, - server_public_key_, server_public_key_version_), - reset_callback_); + Reset(true); + reset_callback_.Run(); } CertificateReportingService::~CertificateReportingService() { @@ -233,65 +222,25 @@ } void CertificateReportingService::Shutdown() { - // Shutdown will be called twice: Once after SafeBrowsing shuts down, and once - // when all KeyedServices shut down. All calls after the first one are no-op. - url_request_context_ = nullptr; - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&CleanupOnIOThread, std::move(reporter_))); + reporter_.reset(); } void CertificateReportingService::Send(const std::string& serialized_report) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!reporter_) { - return; - } - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&CertificateReportingService::Reporter::Send, - base::Unretained(reporter_.get()), serialized_report)); + if (reporter_) + reporter_->Send(serialized_report); } void CertificateReportingService::SendPending() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - if (!reporter_) { - return; - } - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&CertificateReportingService::Reporter::SendPending, - base::Unretained(reporter_.get()))); -} - -void CertificateReportingService::InitializeOnIOThread( - bool enabled, - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, - size_t max_queued_report_count, - base::TimeDelta max_report_age, - base::Clock* clock, - uint8_t* server_public_key, - uint32_t server_public_key_version) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - DCHECK(!url_request_context_); - url_request_context_ = url_request_context_getter->GetURLRequestContext(); - ResetOnIOThread(enabled, url_request_context_, max_queued_report_count, - max_report_age, clock, server_public_key, - server_public_key_version); + if (reporter_) + reporter_->SendPending(); } void CertificateReportingService::SetEnabled(bool enabled) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - // Don't reset if the service is already shut down. - if (!url_request_context_) - return; - - content::BrowserThread::PostTaskAndReply( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&CertificateReportingService::ResetOnIOThread, - base::Unretained(this), enabled, url_request_context_, - max_queued_report_count_, max_report_age_, clock_, - server_public_key_, server_public_key_version_), - reset_callback_); + Reset(enabled); + reset_callback_.Run(); } CertificateReportingService::Reporter* @@ -304,57 +253,26 @@ return GURL(kExtendedReportingUploadUrl); } -void CertificateReportingService::ResetOnIOThread( - bool enabled, - net::URLRequestContext* url_request_context, - size_t max_queued_report_count, - base::TimeDelta max_report_age, - base::Clock* clock, - uint8_t* const server_public_key, - uint32_t server_public_key_version) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - // url_request_context_ is null during shutdown. - if (!enabled || !url_request_context) { +void CertificateReportingService::Reset(bool enabled) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + if (!enabled) { reporter_.reset(); return; } std::unique_ptr<CertificateErrorReporter> error_reporter; - if (server_public_key) { - // Only used in tests. - net::NetworkTrafficAnnotationTag traffic_annotation = - net::DefineNetworkTrafficAnnotation( - "certificate_reporting_service_test", R"( - semantics { - sender: "Certificate Reporting Service Test" - description: - "This request is used for testing certificate reporting service." - trigger: "Upon request from testing API." - data: - "No user data." - destination: GOOGLE_OWNED_SERVICE - } - policy { - cookies_allowed: NO - setting: - "This feature is only used for testing." - policy_exception_justification: - "This feature is only used for testing." - } - )"); - std::unique_ptr<net::ReportSender> report_sender( - new net::ReportSender(url_request_context, traffic_annotation)); + if (server_public_key_) { error_reporter.reset(new CertificateErrorReporter( - GURL(kExtendedReportingUploadUrl), server_public_key, - server_public_key_version, std::move(report_sender))); + url_loader_factory_, GURL(kExtendedReportingUploadUrl), + server_public_key_, server_public_key_version_)); } else { error_reporter.reset(new CertificateErrorReporter( - url_request_context, GURL(kExtendedReportingUploadUrl))); + url_loader_factory_, GURL(kExtendedReportingUploadUrl))); } reporter_.reset( new Reporter(std::move(error_reporter), std::unique_ptr<BoundedReportList>( - new BoundedReportList(max_queued_report_count)), - clock, max_report_age, true /* retries_enabled */)); + new BoundedReportList(max_queued_report_count_)), + clock_, max_report_age_, true /* retries_enabled */)); } void CertificateReportingService::OnPreferenceChanged() {
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service.h b/chrome/browser/safe_browsing/certificate_reporting_service.h index c2dc0494..dba0255 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service.h +++ b/chrome/browser/safe_browsing/certificate_reporting_service.h
@@ -17,7 +17,7 @@ #include "base/time/time.h" #include "chrome/browser/ssl/certificate_error_reporter.h" #include "components/keyed_service/core/keyed_service.h" -#include "net/url_request/url_request_context_getter.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" class PrefService; class Profile; @@ -26,8 +26,8 @@ class Clock; } -namespace net { -class URLRequestContextGetter; +namespace network { +class SharedURLLoaderFactory; } namespace safe_browsing { @@ -41,16 +41,11 @@ // // Lifetime and dependencies: // -// CertificateReportingService uses the url request context from SafeBrowsing +// CertificateReportingService uses the URLLoaderFactory from SafeBrowsing // service. SafeBrowsingService is created before CertificateReportingService, -// but is also shut down before any KeyedService is shut down. This means that -// CertificateReportingService cannot depend on SafeBrowsing's url request being -// available at all times, and it should know when SafeBrowsing shuts down. It -// does this by subscribing to SafeBrowsingService shut downs when it's -// created. When SafeBrowsingService shuts down, CertificateReportingService -// also shuts down. +// but is also shut down before any KeyedService is shut down. // -// This class also observes SafeBrowsing preference changes to enable/disable +// This class observes SafeBrowsing preference changes to enable/disable // reporting. It does this by subscribing to changes in SafeBrowsing and // extended reporting preferences. class CertificateReportingService : public KeyedService { @@ -142,6 +137,9 @@ // Getter and setters for testing: size_t inflight_report_count_for_testing() const; BoundedReportList* GetQueueForTesting() const; + // Sets a closure that is called when there are no more inflight reports. + void SetClosureWhenNoInflightReportsForTesting( + const base::Closure& closure); private: void SendInternal(const Report& report); @@ -149,7 +147,6 @@ // non-HTTP 200 response code. See // TransportSecurityState::ReportSenderInterface for parameters. void ErrorCallback(int report_id, - const GURL& url, int net_error, int http_response_code); // Called when a report upload is successful. @@ -167,6 +164,8 @@ std::map<int, Report> inflight_reports_; + base::Closure no_in_flight_reports_; + base::WeakPtrFactory<Reporter> weak_factory_; DISALLOW_COPY_AND_ASSIGN(Reporter); @@ -177,7 +176,7 @@ CertificateReportingService( safe_browsing::SafeBrowsingService* safe_browsing_service, - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, Profile* profile, uint8_t server_public_key[/* 32 */], uint32_t server_public_key_version, @@ -208,40 +207,18 @@ static GURL GetReportingURLForTesting(); private: - void InitializeOnIOThread( - bool enabled, - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter, - size_t max_queued_report_count, - base::TimeDelta max_report_age, - base::Clock* const clock, - uint8_t* server_public_key, - uint32_t server_public_key_version); - - // Resets the reporter on the IO thread. Changes in SafeBrowsing or extended - // reporting enabled states cause the reporter to be reset. - // If |enabled| is false or |url_request_context_getter| is null, report is - // set to null, effectively cancelling all in flight uploads and clearing the + // Resets the reporter. Changes in SafeBrowsing or extended reporting enabled + // states cause the reporter to be reset. If |enabled| is false, report is set + // to null, effectively cancelling all in flight uploads and clearing the // pending reports queue. - void ResetOnIOThread(bool enabled, - net::URLRequestContext* url_request_context, - size_t max_queued_report_count, - base::TimeDelta max_report_age, - base::Clock* const clock, - uint8_t* server_public_key, - uint32_t server_public_key_version); + void Reset(bool enabled); void OnPreferenceChanged(); const PrefService& pref_service_; - net::URLRequestContext* url_request_context_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; std::unique_ptr<Reporter> reporter_; - // Subscription for url request context shutdowns. When this subscription is - // notified, it means SafeBrowsingService is shutting down, and this service - // must also shut down. - std::unique_ptr<base::CallbackList<void(void)>::Subscription> - safe_browsing_service_shutdown_subscription_; - // Subscription for state changes. When this subscription is notified, it // means SafeBrowsingService is enabled/disabled or one of the preferences // related to it is changed.
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc b/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc index f6755fc..86198277 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc +++ b/chrome/browser/safe_browsing/certificate_reporting_service_browsertest.cc
@@ -82,7 +82,8 @@ https_server_.ServeFilesFromSourceDirectory("chrome/test/data"); ASSERT_TRUE(https_server_.Start()); - test_helper()->SetUpInterceptor(); + test_helper_ = + base::MakeRefCounted<CertificateReportingServiceTestHelper>(); CertificateReportingServiceFactory::GetInstance() ->SetReportEncryptionParamsForTesting( @@ -92,6 +93,8 @@ ->SetServiceResetCallbackForTesting( base::Bind(&CertificateReportingServiceObserver::OnServiceReset, base::Unretained(&service_observer_))); + CertificateReportingServiceFactory::GetInstance() + ->SetURLLoaderFactoryForTesting(test_helper_); event_histogram_tester_.reset(new EventHistogramTester()); InProcessBrowserTest::SetUpOnMainThread(); @@ -126,7 +129,23 @@ } } - CertificateReportingServiceTestHelper* test_helper() { return &test_helper_; } + CertificateReportingServiceTestHelper* test_helper() { + return test_helper_.get(); + } + + void WaitForNoReports() { + if (!service()->GetReporterForTesting() || + !service() + ->GetReporterForTesting() + ->inflight_report_count_for_testing()) + return; + + base::RunLoop run_loop; + service() + ->GetReporterForTesting() + ->SetClosureWhenNoInflightReportsForTesting(run_loop.QuitClosure()); + run_loop.Run(); + } protected: CertificateReportingServiceFactory* factory() { @@ -157,7 +176,10 @@ content::WaitForInterstitialDetach(contents); } - void SendPendingReports() { service()->SendPending(); } + void SendPendingReports() { + WaitForNoReports(); + service()->SendPending(); + } // Changes opt-in status and waits for the cert reporting service to reset. // Can only be used after the service is initialized. When changing the @@ -216,7 +238,7 @@ int num_expected_failed_report_ = -1; - CertificateReportingServiceTestHelper test_helper_; + scoped_refptr<CertificateReportingServiceTestHelper> test_helper_; CertificateReportingServiceObserver service_observer_; @@ -434,6 +456,8 @@ test_helper()->WaitForRequestsDestroyed( ReportExpectation::Successful({{"report1", RetryStatus::RETRIED}})); + WaitForNoReports(); + // report0 was submitted once, failed once, then cleared. // report1 was submitted twice, failed once, succeeded once. event_histogram_tester()->SetExpectedValues( @@ -512,6 +536,8 @@ test_helper()->WaitForRequestsDestroyed( ReportExpectation::Successful({{"report3", RetryStatus::NOT_RETRIED}})); + WaitForNoReports(); + // report0 was submitted once, failed once, dropped once. // report1 was submitted twice, failed twice, dropped once. // report2 was submitted twice, failed twice, dropped once. @@ -593,6 +619,8 @@ test_helper()->WaitForRequestsDestroyed(ReportExpectation::Successful( {{"report2", RetryStatus::RETRIED}, {"report3", RetryStatus::RETRIED}})); + WaitForNoReports(); + // report0 was submitted once, failed once, dropped once. // report1 was submitted twice, failed twice, dropped once. // report2 was submitted thrice, failed twice, succeeded once. @@ -623,6 +651,8 @@ test_helper()->WaitForRequestsDestroyed( ReportExpectation::Delayed({{"report0", RetryStatus::NOT_RETRIED}})); + WaitForNoReports(); + // report0 was submitted once and succeeded once. event_histogram_tester()->SetExpectedValues( 1 /* submitted */, 0 /* failed */, 1 /* successful */, 0 /* dropped */); @@ -674,6 +704,11 @@ // Disable SafeBrowsing. This should clear all pending reports. ToggleSafeBrowsingAndWaitForServiceReset(false); + + // In production, the request would have already went out to the network. For + // this test, we manually resume it which will cause it to be cancelled. + test_helper()->ResumeDelayedRequest(); + test_helper()->WaitForRequestsDestroyed( ReportExpectation::Delayed({{"report0", RetryStatus::NOT_RETRIED}})); @@ -695,6 +730,8 @@ test_helper()->WaitForRequestsDestroyed( ReportExpectation::Delayed({{"report1", RetryStatus::NOT_RETRIED}})); + WaitForNoReports(); + // report0 was submitted once and delayed, then cleared. // report1 was submitted once and delayed, then succeeded. event_histogram_tester()->SetExpectedValues(
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc b/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc index a69205d9..5a4607e 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc +++ b/chrome/browser/safe_browsing/certificate_reporting_service_factory.cc
@@ -2,13 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/safe_browsing/certificate_reporting_service_factory.h" + #include "base/time/default_clock.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/safe_browsing/certificate_reporting_service.h" -#include "chrome/browser/safe_browsing/certificate_reporting_service_factory.h" #include "chrome/browser/safe_browsing/safe_browsing_service.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" namespace { @@ -65,6 +67,11 @@ service_reset_callback_ = service_reset_callback; } +void CertificateReportingServiceFactory::SetURLLoaderFactoryForTesting( + scoped_refptr<network::SharedURLLoaderFactory> factory) { + url_loader_factory_ = factory; +} + CertificateReportingServiceFactory::CertificateReportingServiceFactory() : BrowserContextKeyedServiceFactory( "cert_reporting::Factory", @@ -83,7 +90,9 @@ safe_browsing::SafeBrowsingService* safe_browsing_service = g_browser_process->safe_browsing_service(); return new CertificateReportingService( - safe_browsing_service, safe_browsing_service->url_request_context(), + safe_browsing_service, + url_loader_factory_.get() ? url_loader_factory_ + : safe_browsing_service->GetURLLoaderFactory(), static_cast<Profile*>(profile), server_public_key_, server_public_key_version_, max_queued_report_count_, queued_report_ttl_, clock_, service_reset_callback_);
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_factory.h b/chrome/browser/safe_browsing/certificate_reporting_service_factory.h index b898bbe1..5fb3e1ce 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service_factory.h +++ b/chrome/browser/safe_browsing/certificate_reporting_service_factory.h
@@ -7,6 +7,7 @@ #include "base/memory/singleton.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" namespace base { class Clock; @@ -36,6 +37,8 @@ void SetMaxQueuedReportCountForTesting(size_t max_report_count); void SetServiceResetCallbackForTesting( const base::Callback<void()>& service_reset_callback); + void SetURLLoaderFactoryForTesting( + scoped_refptr<network::SharedURLLoaderFactory> factory); private: friend struct base::DefaultSingletonTraits< @@ -58,6 +61,7 @@ base::TimeDelta queued_report_ttl_; size_t max_queued_report_count_; base::Callback<void()> service_reset_callback_; + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; DISALLOW_COPY_AND_ASSIGN(CertificateReportingServiceFactory); };
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc index 0b6d2af..8b1ccf2 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc +++ b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.cc
@@ -23,26 +23,16 @@ static const char kHkdfLabel[] = "certificate report"; const uint32_t kServerPublicKeyTestVersion = 16; -void SetUpURLHandlersOnIOThread( - std::unique_ptr<net::URLRequestInterceptor> url_request_interceptor) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance(); - filter->AddUrlInterceptor( - CertificateReportingService::GetReportingURLForTesting(), - std::move(url_request_interceptor)); +std::string GetUploadData(const network::ResourceRequest& request) { + auto body = request.request_body; + CHECK(body.get()); + CHECK_EQ(1u, body->elements()->size()); + const auto& element = body->elements()->at(0); + CHECK_EQ(network::DataElement::TYPE_BYTES, element.type()); + return std::string(element.bytes(), element.length()); } -std::string GetUploadData(net::URLRequest* request) { - const net::UploadDataStream* stream = request->get_upload(); - EXPECT_TRUE(stream); - EXPECT_TRUE(stream->GetElementReaders()); - EXPECT_EQ(1u, stream->GetElementReaders()->size()); - const net::UploadBytesElementReader* reader = - (*stream->GetElementReaders())[0]->AsBytesReader(); - return std::string(reader->bytes(), reader->length()); -} - -std::string GetReportContents(net::URLRequest* request, +std::string GetReportContents(const network::ResourceRequest& request, const uint8_t* server_private_key) { std::string serialized_report(GetUploadData(request)); encrypted_messages::EncryptedMessage encrypted_message; @@ -235,108 +225,6 @@ weak_factory_.GetWeakPtr())); } -CertReportJobInterceptor::CertReportJobInterceptor( - ReportSendingResult expected_report_result, - const uint8_t* server_private_key) - : expected_report_result_(expected_report_result), - server_private_key_(server_private_key) {} - -CertReportJobInterceptor::~CertReportJobInterceptor() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); -} - -net::URLRequestJob* CertReportJobInterceptor::MaybeInterceptRequest( - net::URLRequest* request, - net::NetworkDelegate* network_delegate) const { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - - const std::string serialized_report = - GetReportContents(request, server_private_key_); - RequestCreated(serialized_report, expected_report_result_); - - if (expected_report_result_ == REPORTS_FAIL) { - return new DelayableCertReportURLRequestJob( - false, true, request, network_delegate, - base::Bind(&CertReportJobInterceptor::RequestDestructed, - base::Unretained(this), serialized_report, - expected_report_result_)); - - } else if (expected_report_result_ == REPORTS_DELAY) { - DCHECK(!delayed_request_) << "Supports only one delayed request at a time"; - DelayableCertReportURLRequestJob* job = - new DelayableCertReportURLRequestJob( - true, false, request, network_delegate, - base::Bind(&CertReportJobInterceptor::RequestDestructed, - base::Unretained(this), serialized_report, - expected_report_result_)); - delayed_request_ = job->GetWeakPtr(); - return job; - } - // Successful url request job. - return new DelayableCertReportURLRequestJob( - false, false, request, network_delegate, - base::Bind(&CertReportJobInterceptor::RequestDestructed, - base::Unretained(this), serialized_report, - expected_report_result_)); -} - -void CertReportJobInterceptor::SetFailureMode( - ReportSendingResult expected_report_result) { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&CertReportJobInterceptor::SetFailureModeOnIOThread, - base::Unretained(this), expected_report_result)); -} - -void CertReportJobInterceptor::Resume() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&CertReportJobInterceptor::ResumeOnIOThread, - base::Unretained(this))); -} - -RequestObserver* CertReportJobInterceptor::request_created_observer() const { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - return &request_created_observer_; -} - -RequestObserver* CertReportJobInterceptor::request_destroyed_observer() const { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - return &request_destroyed_observer_; -} - -void CertReportJobInterceptor::SetFailureModeOnIOThread( - ReportSendingResult expected_report_result) { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - expected_report_result_ = expected_report_result; -} - -void CertReportJobInterceptor::ResumeOnIOThread() { - DCHECK_CURRENTLY_ON(content::BrowserThread::IO); - EXPECT_EQ(REPORTS_DELAY, expected_report_result_); - if (delayed_request_) - delayed_request_->Resume(); -} - -void CertReportJobInterceptor::RequestCreated( - const std::string& serialized_report, - ReportSendingResult expected_report_result) const { - content::BrowserThread::PostTask( - content::BrowserThread::UI, FROM_HERE, - base::BindOnce(&RequestObserver::OnRequest, - base::Unretained(&request_created_observer_), - serialized_report, expected_report_result)); -} - -void CertReportJobInterceptor::RequestDestructed( - const std::string& serialized_report, - ReportSendingResult expected_report_result) const { - request_destroyed_observer_.OnRequest(serialized_report, - expected_report_result); -} - ReportExpectation::ReportExpectation() {} ReportExpectation::ReportExpectation(const ReportExpectation& other) = default; @@ -393,7 +281,8 @@ run_loop_->Quit(); } -CertificateReportingServiceTestHelper::CertificateReportingServiceTestHelper() { +CertificateReportingServiceTestHelper::CertificateReportingServiceTestHelper() + : expected_report_result_(REPORTS_FAIL) { memset(server_private_key_, 1, sizeof(server_private_key_)); X25519_public_from_private(server_public_key_, server_private_key_); } @@ -401,26 +290,19 @@ CertificateReportingServiceTestHelper:: ~CertificateReportingServiceTestHelper() {} -void CertificateReportingServiceTestHelper::SetUpInterceptor() { - DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - url_request_interceptor_ = - new CertReportJobInterceptor(REPORTS_FAIL, server_private_key_); - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&SetUpURLHandlersOnIOThread, - std::unique_ptr<net::URLRequestInterceptor>( - url_request_interceptor_))); -} - void CertificateReportingServiceTestHelper::SetFailureMode( ReportSendingResult expected_report_result) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - url_request_interceptor_->SetFailureMode(expected_report_result); + expected_report_result_ = expected_report_result; } void CertificateReportingServiceTestHelper::ResumeDelayedRequest() { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); - url_request_interceptor_->Resume(); + EXPECT_EQ(REPORTS_DELAY, expected_report_result_); + if (delayed_client_) { + SendResponse(std::move(delayed_client_), delayed_result_ == REPORTS_FAIL); + request_destroyed_observer_.OnRequest(delayed_report_, delayed_result_); + } } uint8_t* CertificateReportingServiceTestHelper::server_public_key() { @@ -434,41 +316,33 @@ void CertificateReportingServiceTestHelper::WaitForRequestsCreated( const ReportExpectation& expectation) { - WaitReports(interceptor()->request_created_observer(), expectation, nullptr); + WaitReports(&request_created_observer_, expectation, nullptr); } void CertificateReportingServiceTestHelper::WaitForRequestsCreated( const ReportExpectation& expectation, std::vector<std::string>* full_reports) { - WaitReports(interceptor()->request_created_observer(), expectation, - full_reports); + WaitReports(&request_created_observer_, expectation, full_reports); } void CertificateReportingServiceTestHelper::WaitForRequestsDestroyed( const ReportExpectation& expectation) { - WaitReports(interceptor()->request_destroyed_observer(), expectation, - nullptr); + WaitReports(&request_destroyed_observer_, expectation, nullptr); } void CertificateReportingServiceTestHelper::WaitForRequestsDestroyed( const ReportExpectation& expectation, std::vector<std::string>* full_reports) { - WaitReports(interceptor()->request_destroyed_observer(), expectation, - full_reports); + WaitReports(&request_destroyed_observer_, expectation, full_reports); } void CertificateReportingServiceTestHelper::ExpectNoRequests( CertificateReportingService* service) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // Check that all requests have been destroyed. - EXPECT_TRUE(interceptor() - ->request_destroyed_observer() - ->successful_reports() - .empty()); - EXPECT_TRUE( - interceptor()->request_destroyed_observer()->failed_reports().empty()); - EXPECT_TRUE( - interceptor()->request_destroyed_observer()->delayed_reports().empty()); + EXPECT_TRUE(request_destroyed_observer_.successful_reports().empty()); + EXPECT_TRUE(request_destroyed_observer_.failed_reports().empty()); + EXPECT_TRUE(request_destroyed_observer_.delayed_reports().empty()); if (service->GetReporterForTesting()) { // Reporter can be null if reporting is disabled. @@ -478,6 +352,62 @@ } } +void CertificateReportingServiceTestHelper::SendResponse( + network::mojom::URLLoaderClientPtr client, + bool fail) { + if (fail) { + client->OnComplete( + network::URLLoaderCompletionStatus(net::ERR_SSL_PROTOCOL_ERROR)); + return; + } + + network::ResourceResponseHead head; + head.headers = new net::HttpResponseHeaders( + "HTTP/1.1 200 OK\nContent-type: text/html\n\n"); + head.mime_type = "text/html"; + client->OnReceiveResponse(head, nullptr); + client->OnComplete(network::URLLoaderCompletionStatus()); +} + +std::unique_ptr<network::SharedURLLoaderFactoryInfo> +CertificateReportingServiceTestHelper::Clone() { + NOTREACHED(); + return nullptr; +} + +void CertificateReportingServiceTestHelper::CreateLoaderAndStart( + network::mojom::URLLoaderRequest request, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& url_request, + network::mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& traffic_annotation) { + const std::string serialized_report = + GetReportContents(url_request, server_private_key_); + request_created_observer_.OnRequest(serialized_report, + expected_report_result_); + + if (expected_report_result_ == REPORTS_FAIL) { + SendResponse(std::move(client), true); + request_destroyed_observer_.OnRequest(serialized_report, + expected_report_result_); + return; + } + + if (expected_report_result_ == REPORTS_DELAY) { + DCHECK(!delayed_client_) << "Supports only one delayed request at a time"; + delayed_client_ = std::move(client); + delayed_report_ = serialized_report; + delayed_result_ = expected_report_result_; + return; + } + + SendResponse(std::move(client), false); + request_destroyed_observer_.OnRequest(serialized_report, + expected_report_result_); +} + EventHistogramTester::EventHistogramTester() {} EventHistogramTester::~EventHistogramTester() {
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h index 41a8631..c061afa1 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h +++ b/chrome/browser/safe_browsing/certificate_reporting_service_test_utils.h
@@ -17,6 +17,7 @@ #include "net/base/network_delegate_impl.h" #include "net/url_request/url_request_interceptor.h" #include "net/url_request/url_request_job.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" namespace net { class NetworkDelegate; @@ -139,51 +140,6 @@ DISALLOW_COPY_AND_ASSIGN(DelayableCertReportURLRequestJob); }; -// A job interceptor that returns a failed, succesful or delayed request job. -// Used to simulate report uploads that fail, succeed or hang. -// The caller is responsible for guaranteeing that |this| is kept alive for -// all posted tasks and URLRequestJob objects. -class CertReportJobInterceptor : public net::URLRequestInterceptor { - public: - CertReportJobInterceptor(ReportSendingResult expected_report_result, - const uint8_t* server_private_key); - ~CertReportJobInterceptor() override; - - // net::URLRequestInterceptor method: - net::URLRequestJob* MaybeInterceptRequest( - net::URLRequest* request, - net::NetworkDelegate* network_delegate) const override; - - // Sets the failure mode for reports. Must be called on the UI thread. - void SetFailureMode(ReportSendingResult expected_report_result); - // Resumes any hanging URL request and runs callback when the request - // is resumed (i.e. response starts). Must be called on the UI thread. - void Resume(); - - RequestObserver* request_created_observer() const; - RequestObserver* request_destroyed_observer() const; - - private: - void SetFailureModeOnIOThread(ReportSendingResult expected_report_result); - void ResumeOnIOThread(); - void RequestCreated(const std::string& serialized_report, - ReportSendingResult expected_report_result) const; - void RequestDestructed(const std::string& serialized_report, - ReportSendingResult expected_report_result) const; - - ReportSendingResult expected_report_result_; - - // Private key to decrypt certificate reports. - const uint8_t* server_private_key_; - - mutable RequestObserver request_created_observer_; - mutable RequestObserver request_destroyed_observer_; - - mutable base::WeakPtr<DelayableCertReportURLRequestJob> delayed_request_; - - DISALLOW_COPY_AND_ASSIGN(CertReportJobInterceptor); -}; - // Class to wait for the CertificateReportingService to reset. class CertificateReportingServiceObserver { public: @@ -204,14 +160,11 @@ std::unique_ptr<base::RunLoop> run_loop_; }; -// Base class for CertificateReportingService tests. Sets up an interceptor to -// keep track of reports that are being sent. -class CertificateReportingServiceTestHelper { +// Base class for CertificateReportingService tests. +class CertificateReportingServiceTestHelper + : public network::SharedURLLoaderFactory { public: CertificateReportingServiceTestHelper(); - ~CertificateReportingServiceTestHelper(); - - void SetUpInterceptor(); // Changes the behavior of report uploads to fail, succeed or hang. void SetFailureMode(ReportSendingResult expected_report_result); @@ -235,10 +188,30 @@ uint32_t server_public_key_version() const; private: - CertReportJobInterceptor* interceptor() { return url_request_interceptor_; } - void SetUpInterceptorOnIOThread(); + friend class base::RefCounted<CertificateReportingServiceTestHelper>; + ~CertificateReportingServiceTestHelper() override; - CertReportJobInterceptor* url_request_interceptor_; + void SendResponse(network::mojom::URLLoaderClientPtr client, bool fail); + + // network::SharedURLLoaderFactory + std::unique_ptr<network::SharedURLLoaderFactoryInfo> Clone() override; + void CreateLoaderAndStart(network::mojom::URLLoaderRequest request, + int32_t routing_id, + int32_t request_id, + uint32_t options, + const network::ResourceRequest& url_request, + network::mojom::URLLoaderClientPtr client, + const net::MutableNetworkTrafficAnnotationTag& + traffic_annotation) override; + + ReportSendingResult expected_report_result_; + + network::mojom::URLLoaderClientPtr delayed_client_; + std::string delayed_report_; + ReportSendingResult delayed_result_; + + RequestObserver request_created_observer_; + RequestObserver request_destroyed_observer_; uint8_t server_public_key_[32]; uint8_t server_private_key_[32];
diff --git a/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc b/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc index c4f6b19c..30cbfef7 100644 --- a/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc +++ b/chrome/browser/safe_browsing/certificate_reporting_service_unittest.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/ssl/certificate_error_report.h" #include "chrome/test/base/testing_profile.h" #include "content/public/browser/browser_thread.h" +#include "content/public/common/weak_wrapper_shared_url_loader_factory.h" #include "content/public/test/test_browser_thread.h" #include "content/public/test/test_browser_thread_bundle.h" #include "crypto/rsa_private_key.h" @@ -33,6 +34,7 @@ #include "net/test/url_request/url_request_mock_data_job.h" #include "net/url_request/url_request_filter.h" #include "net/url_request/url_request_test_util.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" using certificate_reporting_test_utils::CertificateReportingServiceTestHelper; @@ -90,10 +92,6 @@ EXPECT_EQ(expected_creation_time, report.creation_time); } -void ClearURLHandlers() { - net::URLRequestFilter::GetInstance()->ClearHandlers(); -} - // Class for histogram testing. The failed report histogram is checked once // after teardown to ensure all in flight requests have completed. class ReportHistogramTestHelper { @@ -167,19 +165,15 @@ : public ::testing::Test { public: void SetUp() override { - message_loop_.reset(new base::MessageLoopForIO()); - io_thread_.reset(new content::TestBrowserThread(content::BrowserThread::IO, - message_loop_.get())); - url_request_context_getter_ = - new net::TestURLRequestContextGetter(message_loop_->task_runner()); - net::URLRequestFailedJob::AddUrlHandler(); - net::URLRequestMockDataJob::AddUrlHandler(); + test_shared_loader_factory_ = + base::MakeRefCounted<content::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_); + message_loop_.reset(new base::MessageLoopForIO()); event_histogram_tester_.reset(new EventHistogramTester()); } void TearDown() override { - ClearURLHandlers(); // Check histograms as the last thing. This makes sure no in-flight report // is missed. histogram_test_helper_.CheckHistogram(); @@ -187,8 +181,11 @@ } protected: - net::URLRequestContextGetter* url_request_context_getter() { - return url_request_context_getter_.get(); + network::TestURLLoaderFactory* test_url_loader_factory() { + return &test_url_loader_factory_; + } + scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory() { + return test_shared_loader_factory_; } void SetExpectedFailedReportCountOnTearDown(unsigned int count) { @@ -203,7 +200,8 @@ std::unique_ptr<base::MessageLoopForIO> message_loop_; std::unique_ptr<content::TestBrowserThread> io_thread_; - scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; ReportHistogramTestHelper histogram_test_helper_; // Histogram tester for reporting events. This is a member instead of a local // so that we can check the histogram after the test teardown. At that point @@ -220,11 +218,14 @@ const base::Time reference_time = base::Time::Now(); clock->SetNow(reference_time); - const GURL kFailureURL = - net::URLRequestFailedJob::GetMockHttpsUrl(net::ERR_SSL_PROTOCOL_ERROR); + const GURL kFailureURL("https://www.foo.com/"); + + test_url_loader_factory()->AddResponse( + kFailureURL, network::ResourceResponseHead(), std::string(), + network::URLLoaderCompletionStatus(net::ERR_SSL_PROTOCOL_ERROR)); + CertificateErrorReporter* certificate_error_reporter = - new CertificateErrorReporter( - url_request_context_getter()->GetURLRequestContext(), kFailureURL); + new CertificateErrorReporter(test_shared_loader_factory(), kFailureURL); CertificateReportingService::BoundedReportList* list = new CertificateReportingService::BoundedReportList(2); @@ -290,8 +291,10 @@ // Send pending reports again, this time successfully. There should be no // pending reports left. - const GURL kSuccessURL = - net::URLRequestMockDataJob::GetMockHttpsUrl("dummy data", 1); + const GURL kSuccessURL("https://www.bar.com/"); + + test_url_loader_factory()->AddResponse(kSuccessURL.spec(), "dummy data"); + certificate_error_reporter->set_upload_url_for_testing(kSuccessURL); clock->Advance(base::TimeDelta::FromSeconds(1)); reporter.SendPending(); @@ -315,11 +318,14 @@ base::Time reference_time = base::Time::Now(); clock->SetNow(reference_time); - const GURL kFailureURL = - net::URLRequestFailedJob::GetMockHttpsUrl(net::ERR_SSL_PROTOCOL_ERROR); + const GURL kFailureURL("https://www.foo.com/"); + + test_url_loader_factory()->AddResponse( + kFailureURL, network::ResourceResponseHead(), std::string(), + network::URLLoaderCompletionStatus(net::ERR_SSL_PROTOCOL_ERROR)); + CertificateErrorReporter* certificate_error_reporter = - new CertificateErrorReporter( - url_request_context_getter()->GetURLRequestContext(), kFailureURL); + new CertificateErrorReporter(test_shared_loader_factory(), kFailureURL); CertificateReportingService::BoundedReportList* list = new CertificateReportingService::BoundedReportList(2); @@ -369,24 +375,18 @@ void SetUp() override { service_observer_.Clear(); - test_helper_.SetUpInterceptor(); - WaitForIOThread(); - - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce( - &CertificateReportingServiceTest::SetUpURLRequestContextOnIOThread, - base::Unretained(this))); - WaitForIOThread(); safe_browsing::SafeBrowsingService::RegisterFactory(&sb_service_factory); sb_service_ = sb_service_factory.CreateSafeBrowsingService(); + test_helper_ = + base::MakeRefCounted<CertificateReportingServiceTestHelper>(); + clock_.reset(new base::SimpleTestClock()); service_.reset(new CertificateReportingService( - sb_service_.get(), url_request_context_getter(), &profile_, - test_helper_.server_public_key(), - test_helper_.server_public_key_version(), kMaxReportCountInQueue, + sb_service_.get(), test_helper_, &profile_, + test_helper_->server_public_key(), + test_helper_->server_public_key_version(), kMaxReportCountInQueue, base::TimeDelta::FromHours(24), clock_.get(), base::Bind(&CertificateReportingServiceObserver::OnServiceReset, base::Unretained(&service_observer_)))); @@ -396,36 +396,16 @@ } void TearDown() override { - WaitForIOThread(); test_helper()->ExpectNoRequests(service()); service_->Shutdown(); - WaitForIOThread(); service_.reset(nullptr); - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&CertificateReportingServiceTest::TearDownOnIOThread, - base::Unretained(this))); - content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&ClearURLHandlers)); - WaitForIOThread(); - histogram_test_helper_.CheckHistogram(); event_histogram_tester_.reset(); } protected: - net::URLRequestContextGetter* url_request_context_getter() { - return url_request_context_getter_.get(); - } - - void WaitForIOThread() { - scoped_refptr<base::ThreadTestHelper> io_helper( - new base::ThreadTestHelper(io_task_runner_)); - ASSERT_TRUE(io_helper->Run()); - } - CertificateReportingService* service() { return service_.get(); } // Sets service enabled state and waits for a reset event. @@ -435,42 +415,33 @@ service_observer_.WaitForReset(); } - void AdvanceClock(base::TimeDelta delta) { - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&base::SimpleTestClock::Advance, - base::Unretained(clock_.get()), delta)); - } + void AdvanceClock(base::TimeDelta delta) { clock_->Advance(delta); } - void SetNow(base::Time now) { - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&base::SimpleTestClock::SetNow, - base::Unretained(clock_.get()), now)); - } + void SetNow(base::Time now) { clock_->SetNow(now); } void SetExpectedFailedReportCountOnTearDown(unsigned int count) { histogram_test_helper_.SetExpectedFailedReportCount(count); } - CertificateReportingServiceTestHelper* test_helper() { return &test_helper_; } + CertificateReportingServiceTestHelper* test_helper() { + return test_helper_.get(); + } EventHistogramTester* event_histogram_tester() { return event_histogram_tester_.get(); } + void WaitForNoReports() { + if (!service_->GetReporterForTesting()->inflight_report_count_for_testing()) + return; + + base::RunLoop run_loop; + service_->GetReporterForTesting() + ->SetClosureWhenNoInflightReportsForTesting(run_loop.QuitClosure()); + run_loop.Run(); + } + private: - void SetUpURLRequestContextOnIOThread() { - std::unique_ptr<net::TestURLRequestContext> url_request_context( - new net::TestURLRequestContext(false)); - url_request_context_getter_ = new net::TestURLRequestContextGetter( - io_task_runner_, std::move(url_request_context)); - } - - void TearDownOnIOThread() { - url_request_context_getter_ = nullptr; - } - // Must be initialized before url_request_context_getter_ content::TestBrowserThreadBundle thread_bundle_; @@ -484,7 +455,7 @@ safe_browsing::TestSafeBrowsingServiceFactory sb_service_factory; TestingProfile profile_; - CertificateReportingServiceTestHelper test_helper_; + scoped_refptr<CertificateReportingServiceTestHelper> test_helper_; ReportHistogramTestHelper histogram_test_helper_; CertificateReportingServiceObserver service_observer_; @@ -504,6 +475,7 @@ ReportExpectation::Successful({{"report0", RetryStatus::NOT_RETRIED}, {"report1", RetryStatus::NOT_RETRIED}})); + WaitForNoReports(); // report0 and report1 were both submitted once, succeeded once. event_histogram_tester()->SetExpectedValues( 2 /* submitted */, 0 /* failed */, 2 /* successful */, 0 /* dropped */); @@ -523,6 +495,9 @@ ReportExpectation::Failed({{"report0", RetryStatus::NOT_RETRIED}, {"report1", RetryStatus::NOT_RETRIED}})); + // Need this to ensure the pending reports are queued. + WaitForNoReports(); + // Send pending reports. Previously queued reports should be queued again. service()->SendPending(); test_helper()->WaitForRequestsDestroyed(ReportExpectation::Failed( @@ -537,12 +512,16 @@ test_helper()->WaitForRequestsDestroyed( ReportExpectation::Successful({{"report2", RetryStatus::NOT_RETRIED}})); + // Need this to ensure the pending reports are queued. + WaitForNoReports(); + // Send pending reports. Previously failed and queued two reports should be // observed. service()->SendPending(); test_helper()->WaitForRequestsDestroyed(ReportExpectation::Successful( {{"report0", RetryStatus::RETRIED}, {"report1", RetryStatus::RETRIED}})); + WaitForNoReports(); // report0 and report1 were both submitted thrice, failed twice, succeeded // once. report2 was submitted once, succeeded once. event_histogram_tester()->SetExpectedValues( @@ -570,6 +549,7 @@ test_helper()->WaitForRequestsDestroyed( ReportExpectation::Successful({{"report1", RetryStatus::NOT_RETRIED}})); + WaitForNoReports(); // report0 was never sent. report1 was submitted once, succeeded once. event_histogram_tester()->SetExpectedValues( 1 /* submitted */, 0 /* failed */, 1 /* successful */, 0 /* dropped */); @@ -586,6 +566,9 @@ test_helper()->WaitForRequestsDestroyed( ReportExpectation::Failed({{"report0", RetryStatus::NOT_RETRIED}})); + // Need this to ensure the pending reports are queued. + WaitForNoReports(); + // Disable the service. SetServiceEnabledAndWait(false); @@ -599,6 +582,7 @@ // Sending with empty queue has no effect. service()->SendPending(); + WaitForNoReports(); // report0 was submitted once, failed once. event_histogram_tester()->SetExpectedValues( 1 /* submitted */, 1 /* failed */, 0 /* successful */, 0 /* dropped */); @@ -624,6 +608,10 @@ // time. This makes the report0 older than max age (24 hours). The report1 is // now 20 hours old. AdvanceClock(base::TimeDelta::FromHours(20)); + + // Need this to ensure the pending reports are queued. + WaitForNoReports(); + // Send pending reports. report0 should be discarded since it's too old. // report1 should be queued again. service()->SendPending(); @@ -637,6 +625,10 @@ // Advance the clock 5 hours. The report1 will now be 25 hours old. AdvanceClock(base::TimeDelta::FromHours(5)); + + // Need this to ensure the pending reports are queued. + WaitForNoReports(); + // Send pending reports. report1 should be discarded since it's too old. // report2 should be queued again. service()->SendPending(); @@ -646,10 +638,15 @@ // Advance the clock 20 hours again so that report2 is 25 hours old and is // older than max age (24 hours) AdvanceClock(base::TimeDelta::FromHours(20)); + + // Need this to ensure the pending reports are queued. + WaitForNoReports(); + // Send pending reports. report2 should be discarded since it's too old. No // other reports remain. service()->SendPending(); + WaitForNoReports(); // report0 was submitted once, failed once, dropped once. // report1 was submitted twice, failed twice, dropped once. // report2 was submitted twice, failed twice, dropped once. @@ -687,6 +684,9 @@ {"report2", RetryStatus::NOT_RETRIED}, {"report3", RetryStatus::NOT_RETRIED}})); + // Need this to ensure the pending reports are queued. + WaitForNoReports(); + // Send pending reports. Four reports were generated above, but the service // only queues three reports, so the very first one should be dropped since // it's the oldest. @@ -706,6 +706,10 @@ // report2 is 20 hours old. // report3 is 15 hours old. AdvanceClock(base::TimeDelta::FromHours(15)); + + // Need this to ensure the pending reports are queued. + WaitForNoReports(); + // Send pending reports. Only report2 and report3 should be sent, report1 // should be ignored because it's too old. service()->SendPending(); @@ -715,6 +719,7 @@ // Do a final send. No reports should be sent. service()->SendPending(); + WaitForNoReports(); // report0 was submitted once, failed once, dropped once. // report1 was submitted twice, failed twice, dropped once. // report2 was submitted thrice, failed twice, succeeded once. @@ -740,6 +745,7 @@ test_helper()->WaitForRequestsDestroyed( ReportExpectation::Delayed({{"report0", RetryStatus::NOT_RETRIED}})); + WaitForNoReports(); // report0 was submitted once, succeeded once. event_histogram_tester()->SetExpectedValues( 1 /* submitted */, 0 /* failed */, 1 /* successful */, 0 /* dropped */); @@ -779,6 +785,7 @@ ReportExpectation::Delayed({{"report0", RetryStatus::NOT_RETRIED}, {"report1", RetryStatus::NOT_RETRIED}})); + WaitForNoReports(); // report0 was submitted once, but neither failed nor succeeded because the // report queue was cleared. report1 was submitted once, succeeded once. event_histogram_tester()->SetExpectedValues(
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.cc b/chrome/browser/safe_browsing/chrome_password_protection_service.cc index e60e885..e906e44 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.cc +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.cc
@@ -229,7 +229,7 @@ void ChromePasswordProtectionService::FillReferrerChain( const GURL& event_url, - int event_tab_id, + SessionID event_tab_id, LoginReputationClientRequest::Frame* frame) { DCHECK_CURRENTLY_ON(BrowserThread::UI); SafeBrowsingNavigationObserverManager::AttributionResult result =
diff --git a/chrome/browser/safe_browsing/chrome_password_protection_service.h b/chrome/browser/safe_browsing/chrome_password_protection_service.h index 9ff7dfa..745d372 100644 --- a/chrome/browser/safe_browsing/chrome_password_protection_service.h +++ b/chrome/browser/safe_browsing/chrome_password_protection_service.h
@@ -11,6 +11,7 @@ #include "build/build_config.h" #include "components/safe_browsing/password_protection/password_protection_service.h" #include "components/safe_browsing/triggers/trigger_manager.h" +#include "components/sessions/core/session_id.h" #include "components/sync/protocol/user_event_specifics.pb.h" #include "ui/base/ui_features.h" #include "url/origin.h" @@ -153,7 +154,7 @@ // Obtains referrer chain of |event_url| and |event_tab_id| and add this // info into |frame|. void FillReferrerChain(const GURL& event_url, - int event_tab_id, + SessionID event_tab_id, LoginReputationClientRequest::Frame* frame) override; bool IsExtendedReporting() override;
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc index 59ab62af..67e32ec 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service.cc
@@ -375,10 +375,10 @@ content::WebContents* web_contents = content::DownloadItemUtils::GetWebContents( const_cast<download::DownloadItem*>(&item)); - int download_tab_id = SessionTabHelper::IdForTab(web_contents); + SessionID download_tab_id = SessionTabHelper::IdForTab(web_contents); UMA_HISTOGRAM_BOOLEAN( "SafeBrowsing.ReferrerHasInvalidTabID.DownloadAttribution", - download_tab_id == -1); + !download_tab_id.is_valid()); // We look for the referrer chain that leads to the download url first. SafeBrowsingNavigationObserverManager::AttributionResult result = navigation_observer_manager_->IdentifyReferrerChainByEventURL( @@ -423,14 +423,15 @@ void DownloadProtectionService::AddReferrerChainToPPAPIClientDownloadRequest( const GURL& initiating_frame_url, const GURL& initiating_main_frame_url, - int tab_id, + SessionID tab_id, bool has_user_gesture, ClientDownloadRequest* out_request) { if (!navigation_observer_manager_) return; UMA_HISTOGRAM_BOOLEAN( - "SafeBrowsing.ReferrerHasInvalidTabID.DownloadAttribution", tab_id == -1); + "SafeBrowsing.ReferrerHasInvalidTabID.DownloadAttribution", + !tab_id.is_valid()); SafeBrowsingNavigationObserverManager::AttributionResult result = navigation_observer_manager_->IdentifyReferrerChainByHostingPage( initiating_frame_url, initiating_main_frame_url, tab_id,
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_service.h b/chrome/browser/safe_browsing/download_protection/download_protection_service.h index f0e7d07..0736e8e 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_service.h +++ b/chrome/browser/safe_browsing/download_protection/download_protection_service.h
@@ -27,6 +27,7 @@ #include "chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h" #include "chrome/browser/safe_browsing/ui_manager.h" #include "components/safe_browsing/db/database_manager.h" +#include "components/sessions/core/session_id.h" #include "url/gurl.h" namespace content { @@ -242,7 +243,7 @@ void AddReferrerChainToPPAPIClientDownloadRequest( const GURL& initiating_frame_url, const GURL& initiating_main_frame_url, - int tab_id, + SessionID tab_id, bool has_user_gesture, ClientDownloadRequest* out_request);
diff --git a/chrome/browser/safe_browsing/download_protection/ppapi_download_request.h b/chrome/browser/safe_browsing/download_protection/ppapi_download_request.h index afdd6345..81eaabb 100644 --- a/chrome/browser/safe_browsing/download_protection/ppapi_download_request.h +++ b/chrome/browser/safe_browsing/download_protection/ppapi_download_request.h
@@ -11,6 +11,7 @@ #include "base/files/file_path.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_util.h" +#include "components/sessions/core/session_id.h" #include "url/gurl.h" namespace content { @@ -134,7 +135,7 @@ // Tab id that associated with the PPAPI plugin, computed by // SessionTabHelper::IdForTab(). - int tab_id_; + SessionID tab_id_; // If the user interacted with this PPAPI plugin to trigger the download. bool has_user_gesture_;
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc index 009fa96..d2ec7d2 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
@@ -35,8 +35,8 @@ : source_url(), source_main_frame_url(), original_request_url(), - source_tab_id(-1), - target_tab_id(-1), + source_tab_id(SessionID::InvalidValue()), + target_tab_id(SessionID::InvalidValue()), frame_id(-1), last_updated(base::Time::Now()), navigation_initiation(ReferrerChainEntry::UNDEFINED),
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h index 0d95c5c5..67d5047 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.h
@@ -10,6 +10,7 @@ #include "components/content_settings/core/browser/content_settings_observer.h" #include "components/content_settings/core/common/content_settings.h" #include "components/safe_browsing/proto/csd.pb.h" +#include "components/sessions/core/session_id.h" #include "content/public/browser/web_contents_observer.h" #include "url/gurl.h" @@ -48,10 +49,10 @@ // Which tab contains the frame with source_url. Tab ID is returned by // SessionTabHelper::IdForTab. This ID is immutable for a given tab and unique // across Chrome within the current session. - int source_tab_id; + SessionID source_tab_id; // Which tab this request url is targeting to. - int target_tab_id; + SessionID target_tab_id; // Frame tree node ID of the frame where this navigation takes place. int frame_id;
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc index 548f908d..8f0da3f 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_browsertest.cc
@@ -84,7 +84,6 @@ const char kPageBeforeLandingReferrerURL[] = "/safe_browsing/download_protection/navigation_observer/" "page_before_landing_referrer.html"; -const char kTestExeURL[] = "/temporary/test.exe"; class DownloadItemCreatedObserver : public DownloadManager::Observer { public: @@ -364,7 +363,7 @@ void IdentifyReferrerChainForDownload( DownloadItem* download, ReferrerChain* referrer_chain) { - int download_tab_id = SessionTabHelper::IdForTab( + SessionID download_tab_id = SessionTabHelper::IdForTab( content::DownloadItemUtils::GetWebContents(download)); auto result = observer_manager_->IdentifyReferrerChainByEventURL( download->GetURL(), download_tab_id, @@ -393,7 +392,7 @@ const GURL& initiating_frame_url, content::WebContents* web_contents, ReferrerChain* referrer_chain) { - int tab_id = SessionTabHelper::IdForTab(web_contents); + SessionID tab_id = SessionTabHelper::IdForTab(web_contents); bool has_user_gesture = observer_manager_->HasUserGesture(web_contents); observer_manager_->OnUserGestureConsumed(web_contents, base::Time::Now()); EXPECT_LE(observer_manager_->IdentifyReferrerChainByHostingPage( @@ -454,7 +453,7 @@ const GURL& target_url) { NavigationEvent* nav_event = observer_manager_->navigation_event_list()->FindNavigationEvent( - target_url, GURL(), -1); + target_url, GURL(), SessionID::InvalidValue()); if (nav_event) { observer_manager_->AddToReferrerChain(referrer_chain, nav_event, GURL(), ReferrerChainEntry::EVENT_URL); @@ -2124,8 +2123,6 @@ GURL hosting_url = embedded_test_server()->GetURL(kSingleFrameTestURL); TriggerDownloadViaHtml5FileApi(); std::string test_server_ip(embedded_test_server()->host_port_pair().host()); - GURL filesystem_url(std::string(url::kFileSystemScheme) + ":" + - embedded_test_server()->GetURL(kTestExeURL).spec()); auto* nav_list = navigation_event_list(); ASSERT_TRUE(nav_list); ASSERT_EQ(1U, nav_list->Size()); @@ -2140,19 +2137,7 @@ VerifyHostToIpMap(); ReferrerChain referrer_chain; IdentifyReferrerChainForDownload(GetDownload(), &referrer_chain); - ASSERT_EQ(2, referrer_chain.size()); - - VerifyReferrerChainEntry( - filesystem_url, // url - GURL(), // main_frame_url - ReferrerChainEntry::EVENT_URL, // type - std::string(), // ip_address - hosting_url, // referrer_url - GURL(), // referrer_main_frame_url - false, // is_retargeting - std::vector<GURL>(), // server redirects - ReferrerChainEntry::RENDERER_INITIATED_WITHOUT_USER_GESTURE, - referrer_chain.Get(0)); + ASSERT_EQ(1, referrer_chain.size()); VerifyReferrerChainEntry(hosting_url, // url GURL(), // main_frame_url @@ -2163,7 +2148,7 @@ false, // is_retargeting std::vector<GURL>(), // server redirects ReferrerChainEntry::BROWSER_INITIATED, - referrer_chain.Get(1)); + referrer_chain.Get(0)); } // Verify referrer chain when there are URL fragments.
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc index a2d7d56d..25b6590 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.cc
@@ -117,7 +117,7 @@ NavigationEvent* NavigationEventList::FindNavigationEvent( const GURL& target_url, const GURL& target_main_frame_url, - int target_tab_id) { + SessionID target_tab_id) { if (target_url.is_empty() && target_main_frame_url.is_empty()) return nullptr; @@ -132,7 +132,8 @@ auto* nav_event = rit->get(); // If tab id is not valid, we only compare url, otherwise we compare both. if (nav_event->GetDestinationUrl() == search_url && - (target_tab_id == -1 || nav_event->target_tab_id == target_tab_id)) { + (!target_tab_id.is_valid() || + nav_event->target_tab_id == target_tab_id)) { // If both source_url and source_main_frame_url are empty, and this // navigation is not triggered by user, a retargeting navigation probably // causes this navigation. In this case, we skip this navigation event and @@ -165,7 +166,7 @@ NavigationEvent* NavigationEventList::FindRetargetingNavigationEvent( const GURL& target_url, - int target_tab_id) { + SessionID target_tab_id) { if (target_url.is_empty()) return nullptr; @@ -347,7 +348,7 @@ SafeBrowsingNavigationObserverManager::AttributionResult SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByEventURL( const GURL& event_url, - int event_tab_id, + SessionID event_tab_id, int user_gesture_count_limit, ReferrerChain* out_referrer_chain) { if (!event_url.is_valid()) @@ -383,7 +384,7 @@ if (!last_committed_url.is_valid()) return INVALID_URL; bool has_user_gesture = HasUserGesture(web_contents); - int tab_id = SessionTabHelper::IdForTab(web_contents); + SessionID tab_id = SessionTabHelper::IdForTab(web_contents); return IdentifyReferrerChainByHostingPage( ClearURLRef(last_committed_url), GURL(), tab_id, has_user_gesture, user_gesture_count_limit, out_referrer_chain); @@ -393,7 +394,7 @@ SafeBrowsingNavigationObserverManager::IdentifyReferrerChainByHostingPage( const GURL& initiating_frame_url, const GURL& initiating_main_frame_url, - int tab_id, + SessionID tab_id, bool has_user_gesture, int user_gesture_count_limit, ReferrerChain* out_referrer_chain) {
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h index 562c1d04..cde1f5fee 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_manager.h
@@ -9,6 +9,7 @@ #include "base/feature_list.h" #include "base/supports_user_data.h" #include "components/safe_browsing/proto/csd.pb.h" +#include "components/sessions/core/session_id.h" #include "content/public/browser/web_contents_observer.h" #include "third_party/protobuf/src/google/protobuf/repeated_field.h" #include "url/gurl.h" @@ -66,7 +67,7 @@ // |target_main_frame_url| are the same. // If |target_url| is empty, we use its main frame url (a.k.a. // |target_main_frame_url|) to search for navigation events. - // If |target_tab_id| is not available (-1), we look for all tabs for the most + // If |target_tab_id| is invalid, we look for all tabs for the most // recent navigation to |target_url| or |target_main_frame_url|. // For some cases, the most recent navigation to |target_url| may not be // relevant. @@ -83,12 +84,12 @@ // of all these navigations. NavigationEvent* FindNavigationEvent(const GURL& target_url, const GURL& target_main_frame_url, - int target_tab_id); + SessionID target_tab_id); // Finds the most recent retargeting NavigationEvent that satisfies // |target_url|, and |target_tab_id|. NavigationEvent* FindRetargetingNavigationEvent(const GURL& target_url, - int target_tab_id); + SessionID target_tab_id); void RecordNavigationEvent(std::unique_ptr<NavigationEvent> nav_event); @@ -175,7 +176,7 @@ // |out_referrer_chain|. AttributionResult IdentifyReferrerChainByEventURL( const GURL& event_url, - int event_tab_id, // -1 if tab id is unknown or not available + SessionID event_tab_id, // Invalid if tab id is unknown or not available. int user_gesture_count_limit, ReferrerChain* out_referrer_chain); @@ -201,7 +202,7 @@ AttributionResult IdentifyReferrerChainByHostingPage( const GURL& initiating_frame_url, const GURL& initiating_main_frame_url, - int tab_id, + SessionID tab_id, bool has_user_gesture, int user_gesture_count_limit, ReferrerChain* out_referrer_chain);
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc index 6baf731..9241ef41 100644 --- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc +++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer_unittest.cc
@@ -49,8 +49,8 @@ const GURL& expected_source_main_frame_url, const GURL& expected_original_request_url, const GURL& expected_destination_url, - int expected_source_tab, - int expected_target_tab, + SessionID expected_source_tab, + SessionID expected_target_tab, ReferrerChainEntry::NavigationInitiation expected_nav_initiation, bool expected_has_committed, bool expected_has_server_redirect, @@ -119,7 +119,8 @@ NavigationEventList events(3); EXPECT_EQ(nullptr, - events.FindNavigationEvent(GURL("http://invalid.com"), GURL(), -1)); + events.FindNavigationEvent(GURL("http://invalid.com"), GURL(), + SessionID::InvalidValue())); EXPECT_EQ(0U, events.CleanUpNavigationEvents()); EXPECT_EQ(0U, events.Size()); @@ -133,9 +134,10 @@ CreateNavigationEventUniquePtr(GURL("http://foo1.com"), now)); EXPECT_EQ(2U, events.Size()); // FindNavigationEvent should return the latest matching event. - EXPECT_EQ(now, - events.FindNavigationEvent(GURL("http://foo1.com"), GURL(), -1) - ->last_updated); + EXPECT_EQ(now, events + .FindNavigationEvent(GURL("http://foo1.com"), GURL(), + SessionID::InvalidValue()) + ->last_updated); // One event should get removed. EXPECT_EQ(1U, events.CleanUpNavigationEvents()); EXPECT_EQ(1U, events.Size()); @@ -164,7 +166,7 @@ WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_AUTO_BOOKMARK, false)); CommitPendingLoad(controller); - int tab_id = SessionTabHelper::IdForTab(controller->GetWebContents()); + SessionID tab_id = SessionTabHelper::IdForTab(controller->GetWebContents()); auto* nav_list = navigation_event_list(); ASSERT_EQ(1U, nav_list->Size()); VerifyNavigationEvent(GURL(), // source_url @@ -186,7 +188,7 @@ navigation->Start(); navigation->Redirect(GURL("http://redirect/1")); navigation->Commit(); - int tab_id = SessionTabHelper::IdForTab( + SessionID tab_id = SessionTabHelper::IdForTab( browser()->tab_strip_model()->GetWebContentsAt(0)); auto* nav_list = navigation_event_list(); ASSERT_EQ(1U, nav_list->Size()); @@ -238,8 +240,8 @@ // Verifies all stale and invalid navigation events are removed. ASSERT_EQ(2U, navigation_event_list()->Size()); - EXPECT_EQ(nullptr, - navigation_event_list()->FindNavigationEvent(url_1, GURL(), -1)); + EXPECT_EQ(nullptr, navigation_event_list()->FindNavigationEvent( + url_1, GURL(), SessionID::InvalidValue())); EXPECT_THAT(histograms.GetAllSamples(kNavigationEventCleanUpHistogramName), testing::ElementsAre(base::Bucket(4, 1))); }
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc index da80777f..e3e4877 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.cc +++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -176,7 +176,6 @@ void SafeBrowsingService::ShutDown() { DCHECK_CURRENTLY_ON(BrowserThread::UI); - shutdown_callback_list_.Notify(); // Remove Profile creation/destruction observers. profiles_registrar_.RemoveAll(); @@ -546,13 +545,6 @@ return state_callback_list_.Add(callback); } -std::unique_ptr<SafeBrowsingService::ShutdownSubscription> -SafeBrowsingService::RegisterShutdownCallback( - const base::Callback<void(void)>& callback) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - return shutdown_callback_list_.Add(callback); -} - void SafeBrowsingService::RefreshState() { DCHECK_CURRENTLY_ON(BrowserThread::UI); // Check if any profile requires the service to be active.
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h index ddc20fc..58c2dd4 100644 --- a/chrome/browser/safe_browsing/safe_browsing_service.h +++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -210,12 +210,6 @@ std::unique_ptr<StateSubscription> RegisterStateCallback( const base::Callback<void(void)>& callback); - // Adds a listener for when SafeBrowsingService starts shutting down. - // The callbacks run on the UI thread, and give the subscribers an opportunity - // to clean up any references they hold to SafeBrowsingService. - std::unique_ptr<ShutdownSubscription> RegisterShutdownCallback( - const base::Callback<void(void)>& callback); - // Sends serialized download report to backend. virtual void SendSerializedDownloadReport(const std::string& report); @@ -350,10 +344,6 @@ // Should only be accessed on the UI thread. base::CallbackList<void(void)> state_callback_list_; - // Callbacks when SafeBrowsing service starts shutting down. - // Should only be accessed on the UI thread. - base::CallbackList<void(void)> shutdown_callback_list_; - // The UI manager handles showing interstitials. Accessed on both UI and IO // thread. scoped_refptr<SafeBrowsingUIManager> ui_manager_;
diff --git a/chrome/browser/sessions/chrome_tab_restore_service_client.cc b/chrome/browser/sessions/chrome_tab_restore_service_client.cc index 50940c5..17b168f 100644 --- a/chrome/browser/sessions/chrome_tab_restore_service_client.cc +++ b/chrome/browser/sessions/chrome_tab_restore_service_client.cc
@@ -80,9 +80,9 @@ sessions::LiveTabContext* ChromeTabRestoreServiceClient::FindLiveTabContextWithID(SessionID desired_id) { #if defined(OS_ANDROID) - return AndroidLiveTabContext::FindContextWithID(desired_id.id()); + return AndroidLiveTabContext::FindContextWithID(desired_id); #else - return BrowserLiveTabContext::FindContextWithID(desired_id.id()); + return BrowserLiveTabContext::FindContextWithID(desired_id); #endif }
diff --git a/chrome/browser/sessions/session_tab_helper.cc b/chrome/browser/sessions/session_tab_helper.cc index a5d23d8..a639716 100644 --- a/chrome/browser/sessions/session_tab_helper.cc +++ b/chrome/browser/sessions/session_tab_helper.cc
@@ -18,8 +18,9 @@ DEFINE_WEB_CONTENTS_USER_DATA_KEY(SessionTabHelper); SessionTabHelper::SessionTabHelper(content::WebContents* contents) - : content::WebContentsObserver(contents) { -} + : content::WebContentsObserver(contents), + session_id_(SessionID::NewUnique()), + window_id_(SessionID::InvalidValue()) {} SessionTabHelper::~SessionTabHelper() { } @@ -36,18 +37,20 @@ } // static -SessionID::id_type SessionTabHelper::IdForTab(const content::WebContents* tab) { +SessionID SessionTabHelper::IdForTab(const content::WebContents* tab) { const SessionTabHelper* session_tab_helper = tab ? SessionTabHelper::FromWebContents(tab) : NULL; - return session_tab_helper ? session_tab_helper->session_id().id() : -1; + return session_tab_helper ? session_tab_helper->session_id() + : SessionID::InvalidValue(); } // static -SessionID::id_type SessionTabHelper::IdForWindowContainingTab( +SessionID SessionTabHelper::IdForWindowContainingTab( const content::WebContents* tab) { const SessionTabHelper* session_tab_helper = tab ? SessionTabHelper::FromWebContents(tab) : NULL; - return session_tab_helper ? session_tab_helper->window_id().id() : -1; + return session_tab_helper ? session_tab_helper->window_id() + : SessionID::InvalidValue(); } #if BUILDFLAG(ENABLE_SESSION_SERVICE)
diff --git a/chrome/browser/sessions/session_tab_helper.h b/chrome/browser/sessions/session_tab_helper.h index 0345f97..a43d485 100644 --- a/chrome/browser/sessions/session_tab_helper.h +++ b/chrome/browser/sessions/session_tab_helper.h
@@ -29,9 +29,10 @@ // If the specified WebContents has a SessionTabHelper (probably because it // was used as the contents of a tab), returns a tab id. This value is // immutable for a given tab. It will be unique across Chrome within the - // current session, but may be re-used across sessions. Returns -1 - // for a NULL WebContents or if the WebContents has no SessionTabHelper. - static SessionID::id_type IdForTab(const content::WebContents* tab); + // current session, but may be re-used across sessions. Returns + // SessionID::InvalidValue() for a NULL WebContents or if the WebContents has + // no SessionTabHelper. + static SessionID IdForTab(const content::WebContents* tab); // If the specified WebContents has a SessionTabHelper (probably because it // was used as the contents of a tab), and has ever been attached to a Browser @@ -39,10 +40,9 @@ // being dragged between Browser windows, returns the old window's id value. // If the WebContents has a SessionTabHelper but has never been attached to a // Browser window, returns an id value that is different from that of any - // Browser. Returns -1 for a NULL WebContents or if the WebContents has no - // SessionTabHelper. - static SessionID::id_type IdForWindowContainingTab( - const content::WebContents* tab); + // Browser. Returns SessionID::InvalidValue() for a NULL WebContents or if the + // WebContents has no SessionTabHelper. + static SessionID IdForWindowContainingTab(const content::WebContents* tab); // content::WebContentsObserver: #if BUILDFLAG(ENABLE_SESSION_SERVICE)
diff --git a/chrome/browser/ssl/DEPS b/chrome/browser/ssl/DEPS index 82a694f..c99cacb 100644 --- a/chrome/browser/ssl/DEPS +++ b/chrome/browser/ssl/DEPS
@@ -2,6 +2,7 @@ "+components/captive_portal", "+components/certificate_transparency", "+components/wifi", + "+services/network/test", ] specific_include_rules = {
diff --git a/chrome/browser/ssl/certificate_error_reporter.cc b/chrome/browser/ssl/certificate_error_reporter.cc index f2621529..3a98874b 100644 --- a/chrome/browser/ssl/certificate_error_reporter.cc +++ b/chrome/browser/ssl/certificate_error_reporter.cc
@@ -13,10 +13,12 @@ #include "base/logging.h" #include "base/strings/string_piece.h" +#include "chrome/browser/net/chrome_report_sender.h" #include "components/encrypted_messages/encrypted_message.pb.h" #include "components/encrypted_messages/message_encrypter.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/report_sender.h" +#include "services/network/public/cpp/shared_url_loader_factory.h" namespace { @@ -72,26 +74,22 @@ } // namespace CertificateErrorReporter::CertificateErrorReporter( - net::URLRequestContext* request_context, + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, const GURL& upload_url) - : CertificateErrorReporter( - upload_url, - kServerPublicKey, - kServerPublicKeyVersion, - std::make_unique<net::ReportSender>( - request_context, - kSafeBrowsingCertificateErrorReportingTrafficAnnotation)) {} + : CertificateErrorReporter(url_loader_factory, + upload_url, + kServerPublicKey, + kServerPublicKeyVersion) {} CertificateErrorReporter::CertificateErrorReporter( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, const GURL& upload_url, const uint8_t server_public_key[/* 32 */], - const uint32_t server_public_key_version, - std::unique_ptr<net::ReportSender> certificate_report_sender) - : certificate_report_sender_(std::move(certificate_report_sender)), + const uint32_t server_public_key_version) + : url_loader_factory_(url_loader_factory), upload_url_(upload_url), server_public_key_(server_public_key), server_public_key_version_(server_public_key_version) { - DCHECK(certificate_report_sender_); DCHECK(!upload_url.is_empty()); } @@ -99,31 +97,32 @@ void CertificateErrorReporter::SendExtendedReportingReport( const std::string& serialized_report, - const base::Callback<void()>& success_callback, - const base::Callback<void(const GURL&, int, int)>& error_callback) { - if (upload_url_.SchemeIsCryptographic()) { - certificate_report_sender_->Send(upload_url_, "application/octet-stream", - serialized_report, success_callback, - error_callback); - return; - } - encrypted_messages::EncryptedMessage encrypted_report; - // By mistake, the HKDF label here ends up with an extra null byte on - // the end, due to using sizeof(kHkdfLabel) in the StringPiece - // constructor instead of strlen(kHkdfLabel). This has since been changed - // to strlen() + 1, but will need to be fixed in future to just be strlen. - // TODO(estark): fix this... - // https://crbug.com/517746 - if (!encrypted_messages::EncryptSerializedMessage( - server_public_key_, server_public_key_version_, - base::StringPiece(kHkdfLabel, strlen(kHkdfLabel) + 1), - serialized_report, &encrypted_report)) { - LOG(ERROR) << "Failed to encrypt serialized report."; - return; - } + base::OnceCallback<void()> success_callback, + base::OnceCallback<void(int, int)> error_callback) { std::string serialized_encrypted_report; - encrypted_report.SerializeToString(&serialized_encrypted_report); - certificate_report_sender_->Send(upload_url_, "application/octet-stream", - serialized_encrypted_report, - success_callback, error_callback); + const std::string* string_to_send = &serialized_report; + if (!upload_url_.SchemeIsCryptographic()) { + encrypted_messages::EncryptedMessage encrypted_report; + // By mistake, the HKDF label here ends up with an extra null byte on + // the end, due to using sizeof(kHkdfLabel) in the StringPiece + // constructor instead of strlen(kHkdfLabel). This has since been changed + // to strlen() + 1, but will need to be fixed in future to just be strlen. + // TODO(estark): fix this... + // https://crbug.com/517746 + if (!encrypted_messages::EncryptSerializedMessage( + server_public_key_, server_public_key_version_, + base::StringPiece(kHkdfLabel, strlen(kHkdfLabel) + 1), + serialized_report, &encrypted_report)) { + LOG(ERROR) << "Failed to encrypt serialized report."; + return; + } + + encrypted_report.SerializeToString(&serialized_encrypted_report); + string_to_send = &serialized_encrypted_report; + } + + SendReport(url_loader_factory_, + kSafeBrowsingCertificateErrorReportingTrafficAnnotation, + upload_url_, "application/octet-stream", *string_to_send, + std::move(success_callback), std::move(error_callback)); }
diff --git a/chrome/browser/ssl/certificate_error_reporter.h b/chrome/browser/ssl/certificate_error_reporter.h index 9a06275..f9f8832 100644 --- a/chrome/browser/ssl/certificate_error_reporter.h +++ b/chrome/browser/ssl/certificate_error_reporter.h
@@ -13,11 +13,11 @@ #include "base/callback.h" #include "base/macros.h" -#include "net/url_request/report_sender.h" +#include "base/memory/ref_counted.h" #include "url/gurl.h" -namespace net { -class URLRequestContext; +namespace network { +class SharedURLLoaderFactory; } // Provides functionality for sending reports about invalid SSL @@ -25,19 +25,19 @@ class CertificateErrorReporter { public: // Creates a certificate error reporter that will send certificate - // error reports to |upload_url|, using |request_context| as the + // error reports to |upload_url|, using |url_loader_factory| as the // context for the reports. - CertificateErrorReporter(net::URLRequestContext* request_context, - const GURL& upload_url); - - // Allows tests to use a server public key with known private key and - // a mock ReportSender. |server_public_key| must outlive - // the ErrorReporter. CertificateErrorReporter( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, + const GURL& upload_url); + + // Allows tests to use a server public key with known private key. + // |server_public_key| must outlive the ErrorReporter. + CertificateErrorReporter( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory, const GURL& upload_url, const uint8_t server_public_key[/* 32 */], - const uint32_t server_public_key_version, - std::unique_ptr<net::ReportSender> certificate_report_sender); + const uint32_t server_public_key_version); virtual ~CertificateErrorReporter(); @@ -63,16 +63,14 @@ // net error and HTTP response code parameters. virtual void SendExtendedReportingReport( const std::string& serialized_report, - const base::Callback<void()>& success_callback, - const base::Callback<void(const GURL&, - int /* net_error */, - int /* http_response_code */)>& error_callback); + base::OnceCallback<void()> success_callback, + base::OnceCallback<void(int /* net_error */, + int /* http_response_code */)> error_callback); void set_upload_url_for_testing(const GURL& url) { upload_url_ = url; } private: - std::unique_ptr<net::ReportSender> certificate_report_sender_; - + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_; GURL upload_url_; const uint8_t* server_public_key_;
diff --git a/chrome/browser/ssl/certificate_error_reporter_unittest.cc b/chrome/browser/ssl/certificate_error_reporter_unittest.cc index a0f9ba3..1cd8fe4 100644 --- a/chrome/browser/ssl/certificate_error_reporter_unittest.cc +++ b/chrome/browser/ssl/certificate_error_reporter_unittest.cc
@@ -17,14 +17,14 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/string_piece.h" +#include "base/test/bind_test_util.h" #include "components/encrypted_messages/encrypted_message.pb.h" #include "components/encrypted_messages/message_encrypter.h" +#include "content/public/common/weak_wrapper_shared_url_loader_factory.h" #include "net/http/http_status_code.h" -#include "net/test/url_request/url_request_failed_job.h" -#include "net/test/url_request/url_request_mock_data_job.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" -#include "net/url_request/report_sender.h" -#include "net/url_request/url_request_test_util.h" +#include "services/network/public/cpp/resource_request.h" +#include "services/network/test/test_url_loader_factory.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/boringssl/src/include/openssl/curve25519.h" @@ -36,79 +36,12 @@ const char kDummyReport[] = "a dummy report"; const uint32_t kServerPublicKeyTestVersion = 16; -void ErrorCallback(bool* called, - const GURL& report_uri, - int net_error, - int http_response_code) { - EXPECT_NE(net::OK, net_error); - EXPECT_EQ(-1, http_response_code); - *called = true; -} - -void SuccessCallback(bool* called) { - *called = true; -} - -// A mock ReportSender that keeps track of the last report -// sent. -class MockCertificateReportSender : public net::ReportSender { - public: - MockCertificateReportSender() - : net::ReportSender(nullptr, TRAFFIC_ANNOTATION_FOR_TESTS) {} - ~MockCertificateReportSender() override {} - - void Send(const GURL& report_uri, - base::StringPiece content_type, - base::StringPiece report, - const base::Callback<void()>& success_callback, - const base::Callback<void(const GURL&, int, int)>& error_callback) - override { - latest_report_uri_ = report_uri; - report.CopyToString(&latest_report_); - content_type.CopyToString(&latest_content_type_); - } - - const GURL& latest_report_uri() const { return latest_report_uri_; } - - const std::string& latest_report() const { return latest_report_; } - - const std::string& latest_content_type() const { - return latest_content_type_; - } - - private: - GURL latest_report_uri_; - std::string latest_report_; - std::string latest_content_type_; - - DISALLOW_COPY_AND_ASSIGN(MockCertificateReportSender); -}; - -// A test network delegate that allows the user to specify a callback to -// be run whenever a net::URLRequest is destroyed. -class TestCertificateReporterNetworkDelegate : public net::NetworkDelegateImpl { - public: - TestCertificateReporterNetworkDelegate() - : url_request_destroyed_callback_(base::DoNothing()) {} - - void set_url_request_destroyed_callback(const base::Closure& callback) { - url_request_destroyed_callback_ = callback; - } - - // net::NetworkDelegateImpl: - void OnURLRequestDestroyed(net::URLRequest* request) override { - url_request_destroyed_callback_.Run(); - } - - private: - base::Closure url_request_destroyed_callback_; - - DISALLOW_COPY_AND_ASSIGN(TestCertificateReporterNetworkDelegate); -}; - class ErrorReporterTest : public ::testing::Test { public: - ErrorReporterTest() { + ErrorReporterTest() + : test_shared_loader_factory_( + base::MakeRefCounted<content::WeakWrapperSharedURLLoaderFactory>( + &test_url_loader_factory_)) { memset(server_private_key_, 1, sizeof(server_private_key_)); X25519_public_from_private(server_public_key_, server_private_key_); } @@ -120,44 +53,57 @@ uint8_t server_public_key_[32]; uint8_t server_private_key_[32]; + network::TestURLLoaderFactory test_url_loader_factory_; + scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; + DISALLOW_COPY_AND_ASSIGN(ErrorReporterTest); }; // Test that ErrorReporter::SendExtendedReportingReport sends // an encrypted or plaintext extended reporting report as appropriate. TEST_F(ErrorReporterTest, ExtendedReportingSendReport) { + GURL latest_report_uri; + std::string latest_report; + std::string latest_content_type; + + test_url_loader_factory_.SetInterceptor( + base::BindLambdaForTesting([&](const network::ResourceRequest& request) { + latest_report_uri = request.url; + request.headers.GetHeader(net::HttpRequestHeaders::kContentType, + &latest_content_type); + auto body = request.request_body; + CHECK_EQ(1u, body->elements()->size()); + auto& element = body->elements()->at(0); + CHECK_EQ(network::DataElement::TYPE_BYTES, element.type()); + latest_report = std::string(element.bytes(), element.length()); + })); + // Data should not be encrypted when sent to an HTTPS URL. - MockCertificateReportSender* mock_report_sender = - new MockCertificateReportSender(); - GURL https_url(kDummyHttpsReportUri); - CertificateErrorReporter https_reporter(https_url, server_public_key_, - kServerPublicKeyTestVersion, - base::WrapUnique(mock_report_sender)); + const GURL https_url(kDummyHttpsReportUri); + CertificateErrorReporter https_reporter(test_shared_loader_factory_, + https_url, server_public_key_, + kServerPublicKeyTestVersion); https_reporter.SendExtendedReportingReport( - kDummyReport, base::Callback<void()>(), - base::Callback<void(const GURL&, int, int)>()); - EXPECT_EQ(mock_report_sender->latest_report_uri(), https_url); - EXPECT_EQ(mock_report_sender->latest_report(), kDummyReport); + kDummyReport, base::OnceCallback<void()>(), + base::OnceCallback<void(int, int)>()); + EXPECT_EQ(latest_report_uri, https_url); + EXPECT_EQ(latest_report, kDummyReport); // Data should be encrypted when sent to an HTTP URL. - MockCertificateReportSender* http_mock_report_sender = - new MockCertificateReportSender(); const GURL http_url(kDummyHttpReportUri); - CertificateErrorReporter http_reporter( - http_url, server_public_key_, kServerPublicKeyTestVersion, - base::WrapUnique(http_mock_report_sender)); + CertificateErrorReporter http_reporter(test_shared_loader_factory_, http_url, + server_public_key_, + kServerPublicKeyTestVersion); http_reporter.SendExtendedReportingReport( - kDummyReport, base::Callback<void()>(), - base::Callback<void(const GURL&, int, int)>()); + kDummyReport, base::OnceCallback<void()>(), + base::OnceCallback<void(int, int)>()); - EXPECT_EQ(http_mock_report_sender->latest_report_uri(), http_url); - EXPECT_EQ("application/octet-stream", - http_mock_report_sender->latest_content_type()); + EXPECT_EQ(latest_report_uri, http_url); + EXPECT_EQ("application/octet-stream", latest_content_type); std::string uploaded_report; encrypted_messages::EncryptedMessage encrypted_report; - ASSERT_TRUE(encrypted_report.ParseFromString( - http_mock_report_sender->latest_report())); + ASSERT_TRUE(encrypted_report.ParseFromString(latest_report)); EXPECT_EQ(kServerPublicKeyTestVersion, encrypted_report.server_public_key_version()); EXPECT_EQ( @@ -177,54 +123,37 @@ // Tests that an UMA histogram is recorded if a report fails to send. TEST_F(ErrorReporterTest, ErroredRequestCallsCallback) { - net::URLRequestFailedJob::AddUrlHandler(); - base::RunLoop run_loop; - net::TestURLRequestContext context(true); - TestCertificateReporterNetworkDelegate test_delegate; - test_delegate.set_url_request_destroyed_callback(run_loop.QuitClosure()); - context.set_network_delegate(&test_delegate); - context.Init(); - const GURL report_uri( - net::URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_FAILED)); - CertificateErrorReporter reporter(&context, report_uri); + const GURL report_uri("http://foo.com/bar"); - bool error_callback_called = false; - bool success_callback_called = false; + test_url_loader_factory_.AddResponse( + report_uri, network::ResourceResponseHead(), std::string(), + network::URLLoaderCompletionStatus(net::ERR_CONNECTION_FAILED)); + + CertificateErrorReporter reporter(test_shared_loader_factory_, report_uri); + reporter.SendExtendedReportingReport( - kDummyReport, base::Bind(&SuccessCallback, &success_callback_called), - base::Bind(&ErrorCallback, &error_callback_called)); + kDummyReport, base::BindLambdaForTesting([&]() { FAIL(); }), + base::BindLambdaForTesting( + [&](int net_error, int http_response_code) { run_loop.Quit(); })); run_loop.Run(); - - EXPECT_TRUE(error_callback_called); - EXPECT_FALSE(success_callback_called); } // Tests that an UMA histogram is recorded if a report is successfully sent. TEST_F(ErrorReporterTest, SuccessfulRequestCallsCallback) { - net::URLRequestMockDataJob::AddUrlHandler(); - base::RunLoop run_loop; - net::TestURLRequestContext context(true); - TestCertificateReporterNetworkDelegate test_delegate; - test_delegate.set_url_request_destroyed_callback(run_loop.QuitClosure()); - context.set_network_delegate(&test_delegate); - context.Init(); - const GURL report_uri( - net::URLRequestMockDataJob::GetMockHttpUrl("some data", 1)); - CertificateErrorReporter reporter(&context, report_uri); + const GURL report_uri("http://foo.com/bar"); + test_url_loader_factory_.AddResponse(report_uri.spec(), "some data"); - bool error_callback_called = false; - bool success_callback_called = false; + CertificateErrorReporter reporter(test_shared_loader_factory_, report_uri); + reporter.SendExtendedReportingReport( - kDummyReport, base::Bind(&SuccessCallback, &success_callback_called), - base::Bind(&ErrorCallback, &error_callback_called)); + kDummyReport, base::BindLambdaForTesting([&]() { run_loop.Quit(); }), + base::BindLambdaForTesting( + [&](int net_error, int http_response_code) { FAIL(); })); run_loop.Run(); - - EXPECT_FALSE(error_callback_called); - EXPECT_TRUE(success_callback_called); } } // namespace
diff --git a/chrome/browser/sync/glue/synced_window_delegates_getter_android.cc b/chrome/browser/sync/glue/synced_window_delegates_getter_android.cc index 18591fb..006c576 100644 --- a/chrome/browser/sync/glue/synced_window_delegates_getter_android.cc +++ b/chrome/browser/sync/glue/synced_window_delegates_getter_android.cc
@@ -27,7 +27,7 @@ const SyncedWindowDelegate* SyncedWindowDelegatesGetterAndroid::FindById( SessionID session_id) { - TabModel* tab_model = TabModelList::FindTabModelWithId(session_id.id()); + TabModel* tab_model = TabModelList::FindTabModelWithId(session_id); // In case we don't find the browser (e.g. for Developer Tools). return tab_model ? tab_model->GetSyncedWindowDelegate() : nullptr;
diff --git a/chrome/browser/sync/profile_sync_service_factory.cc b/chrome/browser/sync/profile_sync_service_factory.cc index b2b1764..ecdf5ab 100644 --- a/chrome/browser/sync/profile_sync_service_factory.cc +++ b/chrome/browser/sync/profile_sync_service_factory.cc
@@ -25,6 +25,7 @@ #include "chrome/browser/signin/about_signin_internals_factory.h" #include "chrome/browser/signin/chrome_signin_client_factory.h" #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/spellchecker/spellcheck_factory.h" @@ -137,6 +138,7 @@ DependsOn(ThemeServiceFactory::GetInstance()); #endif // !defined(OS_ANDROID) DependsOn(HistoryServiceFactory::GetInstance()); + DependsOn(IdentityManagerFactory::GetInstance()); DependsOn(invalidation::ProfileInvalidationProviderFactory::GetInstance()); DependsOn(PasswordStoreFactory::GetInstance()); DependsOn(ProfileOAuth2TokenServiceFactory::GetInstance()); @@ -218,10 +220,6 @@ #endif // defined(OS_WIN) if (!local_sync_backend_enabled) { - SigninManagerBase* signin = SigninManagerFactory::GetForProfile(profile); - SigninClient* signin_client = - ChromeSigninClientFactory::GetForProfile(profile); - // Always create the GCMProfileService instance such that we can listen to // the profile notifications and purge the GCM store when the profile is // being signed out. @@ -232,13 +230,15 @@ AboutSigninInternalsFactory::GetForProfile(profile); init_params.signin_wrapper = - std::make_unique<SupervisedUserSigninManagerWrapper>(profile, signin); + std::make_unique<SupervisedUserSigninManagerWrapper>( + profile, IdentityManagerFactory::GetForProfile(profile), + SigninManagerFactory::GetForProfile(profile)); // Note: base::Unretained(signin_client) is safe because the SigninClient is // guaranteed to outlive the PSS, per a DependsOn() above (and because PSS // clears the callback in its Shutdown()). - init_params.signin_scoped_device_id_callback = - base::BindRepeating(&SigninClient::GetSigninScopedDeviceId, - base::Unretained(signin_client)); + init_params.signin_scoped_device_id_callback = base::BindRepeating( + &SigninClient::GetSigninScopedDeviceId, + base::Unretained(ChromeSigninClientFactory::GetForProfile(profile))); init_params.oauth2_token_service = ProfileOAuth2TokenServiceFactory::GetForProfile(profile); init_params.gaia_cookie_manager_service =
diff --git a/chrome/browser/sync/profile_sync_test_util.cc b/chrome/browser/sync/profile_sync_test_util.cc index d3930f21..fe02d73 100644 --- a/chrome/browser/sync/profile_sync_test_util.cc +++ b/chrome/browser/sync/profile_sync_test_util.cc
@@ -11,6 +11,7 @@ #include "base/location.h" #include "base/single_thread_task_runner.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/sync/chrome_sync_client.h" @@ -45,6 +46,7 @@ ProfileSyncService::InitParams init_params; init_params.signin_wrapper = std::make_unique<SigninManagerWrapper>( + IdentityManagerFactory::GetForProfile(profile), SigninManagerFactory::GetForProfile(profile)); init_params.signin_scoped_device_id_callback = base::BindRepeating([]() { return std::string(); });
diff --git a/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.cc b/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.cc index 62fc3f1..6836374 100644 --- a/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.cc +++ b/chrome/browser/sync/sessions/sync_sessions_router_tab_helper.cc
@@ -74,8 +74,7 @@ void SyncSessionsRouterTabHelper::SetSourceTabIdForChild( content::WebContents* child_contents) { - SessionID source_tab_id = SessionID::FromSerializedValue( - SessionTabHelper::IdForTab(web_contents())); + SessionID source_tab_id = SessionTabHelper::IdForTab(web_contents()); if (child_contents && SyncSessionsRouterTabHelper::FromWebContents(child_contents) && child_contents != web_contents() && source_tab_id.is_valid()) {
diff --git a/chrome/browser/sync/supervised_user_signin_manager_wrapper.cc b/chrome/browser/sync/supervised_user_signin_manager_wrapper.cc index 1d1ac6e..1724f679 100644 --- a/chrome/browser/sync/supervised_user_signin_manager_wrapper.cc +++ b/chrome/browser/sync/supervised_user_signin_manager_wrapper.cc
@@ -15,8 +15,10 @@ SupervisedUserSigninManagerWrapper::SupervisedUserSigninManagerWrapper( Profile* profile, - SigninManagerBase* original) - : SigninManagerWrapper(original), profile_(profile) {} + identity::IdentityManager* identity_manager, + SigninManagerBase* signin_manager) + : SigninManagerWrapper(identity_manager, signin_manager), + profile_(profile) {} SupervisedUserSigninManagerWrapper::~SupervisedUserSigninManagerWrapper() {}
diff --git a/chrome/browser/sync/supervised_user_signin_manager_wrapper.h b/chrome/browser/sync/supervised_user_signin_manager_wrapper.h index 6d49080..9233d75 100644 --- a/chrome/browser/sync/supervised_user_signin_manager_wrapper.h +++ b/chrome/browser/sync/supervised_user_signin_manager_wrapper.h
@@ -13,6 +13,10 @@ class Profile; class SigninManagerBase; +namespace identity { +class IdentityManager; +} + // Some chrome cloud services support supervised users as well as normally // authenticated users that sign in through SigninManager. To facilitate // getting the "effective" username and account identifiers, services can @@ -20,8 +24,10 @@ // information when appropriate. class SupervisedUserSigninManagerWrapper : public SigninManagerWrapper { public: - SupervisedUserSigninManagerWrapper(Profile* profile, - SigninManagerBase* original); + SupervisedUserSigninManagerWrapper( + Profile* profile, + identity::IdentityManager* identity_manager, + SigninManagerBase* signin_manager); ~SupervisedUserSigninManagerWrapper() override; // SigninManagerWrapper implementation
diff --git a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc index 3872aeac..26ec0db4 100644 --- a/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc +++ b/chrome/browser/sync/test/integration/single_client_sessions_sync_test.cc
@@ -370,12 +370,11 @@ content::WebContents* new_tab_contents = GetBrowser(0)->tab_strip_model()->GetWebContentsAt(1); - SessionID::id_type source_tab_id = - SessionTabHelper::IdForTab(original_tab_contents); + SessionID source_tab_id = SessionTabHelper::IdForTab(original_tab_contents); sync_sessions::SyncSessionsRouterTabHelper* new_tab_helper = sync_sessions::SyncSessionsRouterTabHelper::FromWebContents( new_tab_contents); - EXPECT_EQ(new_tab_helper->source_tab_id().id(), source_tab_id); + EXPECT_EQ(new_tab_helper->source_tab_id(), source_tab_id); } void DumpSessionsOnServer(fake_server::FakeServer* fake_server) {
diff --git a/chrome/browser/task_manager/providers/fallback_task_provider_unittest.cc b/chrome/browser/task_manager/providers/fallback_task_provider_unittest.cc index 9af40935..2bc257d 100644 --- a/chrome/browser/task_manager/providers/fallback_task_provider_unittest.cc +++ b/chrome/browser/task_manager/providers/fallback_task_provider_unittest.cc
@@ -33,7 +33,7 @@ const Task* GetParentTask() const override { return nullptr; } - int GetTabId() const override { return 0; } + SessionID GetTabId() const override { return SessionID::InvalidValue(); } private: Type type_;
diff --git a/chrome/browser/task_manager/providers/task.cc b/chrome/browser/task_manager/providers/task.cc index d8905b8..9ff36e9c 100644 --- a/chrome/browser/task_manager/providers/task.cc +++ b/chrome/browser/task_manager/providers/task.cc
@@ -147,8 +147,8 @@ return base::string16(); } -int Task::GetTabId() const { - return -1; +SessionID Task::GetTabId() const { + return SessionID::InvalidValue(); } bool Task::HasParentTask() const {
diff --git a/chrome/browser/task_manager/providers/task.h b/chrome/browser/task_manager/providers/task.h index 6e493bafc..e92eeee 100644 --- a/chrome/browser/task_manager/providers/task.h +++ b/chrome/browser/task_manager/providers/task.h
@@ -14,6 +14,7 @@ #include "base/process/process_handle.h" #include "base/strings/string16.h" #include "base/time/time.h" +#include "components/sessions/core/session_id.h" #include "third_party/WebKit/public/platform/WebCache.h" #include "ui/gfx/image/image_skia.h" @@ -121,9 +122,9 @@ virtual base::string16 GetProfileName() const; // Returns the unique ID of the tab if this task represents a renderer - // WebContents used for a tab. Returns -1 if this task does not represent - // a renderer, or a contents of a tab. - virtual int GetTabId() const; + // WebContents used for a tab. Returns SessionID::InvalidValue() if this task + // does not represent a renderer, or a contents of a tab. + virtual SessionID GetTabId() const; // For Tasks that represent a subactivity of some other task (e.g. a plugin // embedded in a page), this returns the Task representing the parent
diff --git a/chrome/browser/task_manager/providers/web_contents/renderer_task.cc b/chrome/browser/task_manager/providers/web_contents/renderer_task.cc index b8da268c..21849f8 100644 --- a/chrome/browser/task_manager/providers/web_contents/renderer_task.cc +++ b/chrome/browser/task_manager/providers/web_contents/renderer_task.cc
@@ -158,7 +158,7 @@ return profile_name_; } -int RendererTask::GetTabId() const { +SessionID RendererTask::GetTabId() const { return SessionTabHelper::IdForTab(web_contents_); }
diff --git a/chrome/browser/task_manager/providers/web_contents/renderer_task.h b/chrome/browser/task_manager/providers/web_contents/renderer_task.h index 2fbf6149..2ae37c46 100644 --- a/chrome/browser/task_manager/providers/web_contents/renderer_task.h +++ b/chrome/browser/task_manager/providers/web_contents/renderer_task.h
@@ -62,7 +62,7 @@ void GetTerminationStatus(base::TerminationStatus* out_status, int* out_error_code) const override; base::string16 GetProfileName() const override; - int GetTabId() const override; + SessionID GetTabId() const override; int64_t GetV8MemoryAllocated() const override; int64_t GetV8MemoryUsed() const override; bool ReportsWebCacheStats() const override;
diff --git a/chrome/browser/task_manager/sampling/task_group_unittest.cc b/chrome/browser/task_manager/sampling/task_group_unittest.cc index ac6e0d7..9f0fcbc 100644 --- a/chrome/browser/task_manager/sampling/task_group_unittest.cc +++ b/chrome/browser/task_manager/sampling/task_group_unittest.cc
@@ -42,7 +42,7 @@ const Task* GetParentTask() const override { return nullptr; } - int GetTabId() const override { return 0; } + SessionID GetTabId() const override { return SessionID::InvalidValue(); } private: Type type_;
diff --git a/chrome/browser/task_manager/sampling/task_manager_impl.cc b/chrome/browser/task_manager/sampling/task_manager_impl.cc index c9315271..7b1c342 100644 --- a/chrome/browser/task_manager/sampling/task_manager_impl.cc +++ b/chrome/browser/task_manager/sampling/task_manager_impl.cc
@@ -232,7 +232,7 @@ return GetTaskByTaskId(task_id)->GetType(); } -int TaskManagerImpl::GetTabId(TaskId task_id) const { +SessionID TaskManagerImpl::GetTabId(TaskId task_id) const { return GetTaskByTaskId(task_id)->GetTabId(); }
diff --git a/chrome/browser/task_manager/sampling/task_manager_impl.h b/chrome/browser/task_manager/sampling/task_manager_impl.h index 7e31f64..dd64db2 100644 --- a/chrome/browser/task_manager/sampling/task_manager_impl.h +++ b/chrome/browser/task_manager/sampling/task_manager_impl.h
@@ -68,7 +68,7 @@ const base::ProcessHandle& GetProcessHandle(TaskId task_id) const override; const base::ProcessId& GetProcessId(TaskId task_id) const override; Task::Type GetType(TaskId task_id) const override; - int GetTabId(TaskId task_id) const override; + SessionID GetTabId(TaskId task_id) const override; int GetChildProcessUniqueId(TaskId task_id) const override; void GetTerminationStatus(TaskId task_id, base::TerminationStatus* out_status,
diff --git a/chrome/browser/task_manager/sampling/task_manager_impl_unittest.cc b/chrome/browser/task_manager/sampling/task_manager_impl_unittest.cc index 52a2dee..e513926f 100644 --- a/chrome/browser/task_manager/sampling/task_manager_impl_unittest.cc +++ b/chrome/browser/task_manager/sampling/task_manager_impl_unittest.cc
@@ -25,7 +25,7 @@ FakeTask(base::ProcessId process_id, Type type, const std::string& title, - int tab_id) + SessionID tab_id) : Task(base::ASCIIToUTF16(title), "FakeTask", nullptr, @@ -45,14 +45,14 @@ const Task* GetParentTask() const override { return parent_; } - int GetTabId() const override { return tab_id_; } + SessionID GetTabId() const override { return tab_id_; } void SetParent(Task* parent) { parent_ = parent; } private: Type type_; Task* parent_; - int tab_id_; + SessionID tab_id_; DISALLOW_COPY_AND_ASSIGN(FakeTask); }; @@ -74,7 +74,7 @@ FakeTask* AddTask(int pid_offset, Task::Type type, const std::string& title, - int tab_id) { + SessionID tab_id) { // Offset based on the current process id, to avoid collisions with the // browser process task. base::ProcessId process_id = base::GetCurrentProcId() + pid_offset; @@ -98,31 +98,38 @@ }; TEST_F(TaskManagerImplTest, SortingTypes) { - AddTask(100, Task::GPU, "Gpu Process", -1); + constexpr SessionID kTabId1 = SessionID::FromSerializedValue(10); + constexpr SessionID kTabId2 = SessionID::FromSerializedValue(20); - Task* tab1 = AddTask(200, Task::RENDERER, "Tab One", 10); - AddTask(400, Task::EXTENSION, "Extension Subframe: Tab One", 10) + AddTask(100, Task::GPU, "Gpu Process", /*tab_id=*/SessionID::InvalidValue()); + + Task* tab1 = AddTask(200, Task::RENDERER, "Tab One", kTabId1); + AddTask(400, Task::EXTENSION, "Extension Subframe: Tab One", kTabId1) ->SetParent(tab1); - AddTask(300, Task::RENDERER, "Subframe: Tab One", 10)->SetParent(tab1); + AddTask(300, Task::RENDERER, "Subframe: Tab One", kTabId1)->SetParent(tab1); - Task* tab2 = - AddTask(200, Task::RENDERER, "Tab Two: sharing process with Tab One", 20); + Task* tab2 = AddTask(200, Task::RENDERER, + "Tab Two: sharing process with Tab One", kTabId2); - AddTask(301, Task::RENDERER, "Subframe: Tab Two", 20)->SetParent(tab2); - AddTask(400, Task::EXTENSION, "Extension Subframe: Tab Two", 20) + AddTask(301, Task::RENDERER, "Subframe: Tab Two", kTabId2)->SetParent(tab2); + AddTask(400, Task::EXTENSION, "Extension Subframe: Tab Two", kTabId2) ->SetParent(tab2); - AddTask(600, Task::ARC, "ARC", -1); - AddTask(800, Task::UTILITY, "Utility One", -1); - AddTask(700, Task::UTILITY, "Utility Two", -1); - AddTask(1000, Task::GUEST, "Guest", 20); - AddTask(900, Task::WORKER, "Worker", -1); - AddTask(500, Task::ZYGOTE, "Zygote", -1); + AddTask(600, Task::ARC, "ARC", /*tab_id=*/SessionID::InvalidValue()); + AddTask(800, Task::UTILITY, "Utility One", + /*tab_id=*/SessionID::InvalidValue()); + AddTask(700, Task::UTILITY, "Utility Two", + /*tab_id=*/SessionID::InvalidValue()); + AddTask(1000, Task::GUEST, "Guest", kTabId2); + AddTask(900, Task::WORKER, "Worker", /*tab_id=*/SessionID::InvalidValue()); + AddTask(500, Task::ZYGOTE, "Zygote", /*tab_id=*/SessionID::InvalidValue()); - AddTask(300, Task::RENDERER, "Subframe: Tab One (2)", 10)->SetParent(tab1); - AddTask(300, Task::RENDERER, "Subframe: Tab One (third)", 10) + AddTask(300, Task::RENDERER, "Subframe: Tab One (2)", kTabId1) ->SetParent(tab1); - AddTask(300, Task::RENDERER, "Subframe: Tab One (4)", 10)->SetParent(tab1); + AddTask(300, Task::RENDERER, "Subframe: Tab One (third)", kTabId1) + ->SetParent(tab1); + AddTask(300, Task::RENDERER, "Subframe: Tab One (4)", kTabId1) + ->SetParent(tab1); EXPECT_EQ( "Browser\n" @@ -146,49 +153,60 @@ } TEST_F(TaskManagerImplTest, SortingCycles) { + constexpr SessionID kTabId1 = SessionID::FromSerializedValue(10); + constexpr SessionID kTabId2 = SessionID::FromSerializedValue(20); + constexpr SessionID kTabId3 = SessionID::FromSerializedValue(5); + constexpr SessionID kTabId4 = SessionID::FromSerializedValue(30); + // Two tabs, with subframes in the other's process. This induces a cycle in // the TaskGroup dependencies, without being a cycle in the Tasks. This can // happen in practice. - Task* tab1 = AddTask(200, Task::RENDERER, "Tab 1: Process 200", 10); - AddTask(300, Task::RENDERER, "Subframe in Tab 1: Process 300", 10) + Task* tab1 = AddTask(200, Task::RENDERER, "Tab 1: Process 200", kTabId1); + AddTask(300, Task::RENDERER, "Subframe in Tab 1: Process 300", kTabId1) ->SetParent(tab1); - Task* tab2 = AddTask(300, Task::RENDERER, "Tab 2: Process 300", 20); - AddTask(200, Task::RENDERER, "Subframe in Tab 2: Process 200", 20) + Task* tab2 = AddTask(300, Task::RENDERER, "Tab 2: Process 300", kTabId2); + AddTask(200, Task::RENDERER, "Subframe in Tab 2: Process 200", kTabId2) ->SetParent(tab2); // Simulated GPU process. - AddTask(100, Task::GPU, "Gpu Process", -1); + AddTask(100, Task::GPU, "Gpu Process", /*tab_id=*/SessionID::InvalidValue()); // Two subframes that list each other as a parent (a true cycle). This // shouldn't happen in practice, but we want the sorting code to handle it // gracefully. - FakeTask* cycle1 = AddTask(501, Task::SANDBOX_HELPER, "Cycle 1", -1); - FakeTask* cycle2 = AddTask(500, Task::ARC, "Cycle 2", -1); + FakeTask* cycle1 = AddTask(501, Task::SANDBOX_HELPER, "Cycle 1", + /*tab_id=*/SessionID::InvalidValue()); + FakeTask* cycle2 = + AddTask(500, Task::ARC, "Cycle 2", /*tab_id=*/SessionID::InvalidValue()); cycle1->SetParent(cycle2); cycle2->SetParent(cycle1); // A cycle where both elements are in the same group. - FakeTask* cycle3 = AddTask(600, Task::SANDBOX_HELPER, "Cycle 3", -1); - FakeTask* cycle4 = AddTask(600, Task::ARC, "Cycle 4", -1); + FakeTask* cycle3 = AddTask(600, Task::SANDBOX_HELPER, "Cycle 3", + /*tab_id=*/SessionID::InvalidValue()); + FakeTask* cycle4 = + AddTask(600, Task::ARC, "Cycle 4", /*tab_id=*/SessionID::InvalidValue()); cycle3->SetParent(cycle4); cycle4->SetParent(cycle3); // Tasks listing a cycle as their parent. - FakeTask* lollipop5 = AddTask(701, Task::EXTENSION, "Child of Cycle 3", -1); + FakeTask* lollipop5 = AddTask(701, Task::EXTENSION, "Child of Cycle 3", + /*tab_id=*/SessionID::InvalidValue()); lollipop5->SetParent(cycle3); - FakeTask* lollipop6 = AddTask(700, Task::PLUGIN, "Child of Cycle 4", -1); + FakeTask* lollipop6 = AddTask(700, Task::PLUGIN, "Child of Cycle 4", + /*tab_id=*/SessionID::InvalidValue()); lollipop6->SetParent(cycle4); // A task listing itself as parent. - FakeTask* self_cycle = AddTask(800, Task::RENDERER, "Self Cycle", 5); + FakeTask* self_cycle = AddTask(800, Task::RENDERER, "Self Cycle", kTabId3); self_cycle->SetParent(self_cycle); // Add a plugin child to tab1 and tab2. - AddTask(900, Task::PLUGIN, "Plugin: Tab 2", 20)->SetParent(tab1); - AddTask(901, Task::PLUGIN, "Plugin: Tab 1", 10)->SetParent(tab1); + AddTask(900, Task::PLUGIN, "Plugin: Tab 2", kTabId2)->SetParent(tab1); + AddTask(901, Task::PLUGIN, "Plugin: Tab 1", kTabId1)->SetParent(tab1); // Finish with a normal renderer task. - AddTask(903, Task::RENDERER, "Tab: Normal Renderer", 30); + AddTask(903, Task::RENDERER, "Tab: Normal Renderer", kTabId4); // Cycles should wind up on the bottom of the list. EXPECT_EQ(
diff --git a/chrome/browser/task_manager/task_manager_browsertest.cc b/chrome/browser/task_manager/task_manager_browsertest.cc index 9f237c33..6c6c754 100644 --- a/chrome/browser/task_manager/task_manager_browsertest.cc +++ b/chrome/browser/task_manager/task_manager_browsertest.cc
@@ -268,7 +268,7 @@ // Killing the tab via task manager should remove the row. int tab = FindResourceIndex(MatchTab("title1.html")); ASSERT_NE(-1, tab); - ASSERT_NE(-1, model()->GetTabId(tab)); + ASSERT_TRUE(model()->GetTabId(tab).is_valid()); model()->Kill(tab); ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(0, MatchTab("title1.html"))); ASSERT_NO_FATAL_FAILURE(WaitForTaskManagerRows(1, MatchAnyTab())); @@ -365,11 +365,11 @@ int extension_tab = FindResourceIndex(MatchExtension("Foobar")); ASSERT_NE(-1, extension_tab); - ASSERT_NE(-1, model()->GetTabId(extension_tab)); + ASSERT_TRUE(model()->GetTabId(extension_tab).is_valid()); int background_page = FindResourceIndex(MatchExtension("My extension 1")); ASSERT_NE(-1, background_page); - ASSERT_EQ(-1, model()->GetTabId(background_page)); + ASSERT_FALSE(model()->GetTabId(background_page).is_valid()); } IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeExtensionTab) { @@ -395,11 +395,11 @@ int extension_tab = FindResourceIndex(MatchExtension("Foobar")); ASSERT_NE(-1, extension_tab); - ASSERT_NE(-1, model()->GetTabId(extension_tab)); + ASSERT_TRUE(model()->GetTabId(extension_tab).is_valid()); int background_page = FindResourceIndex(MatchExtension("My extension 1")); ASSERT_NE(-1, background_page); - ASSERT_EQ(-1, model()->GetTabId(background_page)); + ASSERT_FALSE(model()->GetTabId(background_page).is_valid()); } IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeAppTabChanges) { @@ -432,7 +432,7 @@ // a tab contents and an extension. int app_tab = FindResourceIndex(MatchApp("Packaged App Test")); ASSERT_NE(-1, app_tab); - ASSERT_NE(-1, model()->GetTabId(app_tab)); + ASSERT_TRUE(model()->GetTabId(app_tab).is_valid()); ASSERT_EQ(2, browser()->tab_strip_model()->count()); // Unload extension to make sure the tab goes away. @@ -469,7 +469,7 @@ // a tab contents and an extension. int app_tab = FindResourceIndex(MatchApp("Packaged App Test")); ASSERT_NE(-1, app_tab); - ASSERT_NE(-1, model()->GetTabId(app_tab)); + ASSERT_TRUE(model()->GetTabId(app_tab).is_valid()); } IN_PROC_BROWSER_TEST_F(TaskManagerBrowserTest, NoticeHostedAppTabChanges) { @@ -1011,7 +1011,7 @@ int subframe_b = FindResourceIndex(MatchSubframe("http://b.com/")); ASSERT_NE(-1, subframe_b); - ASSERT_NE(-1, model()->GetTabId(subframe_b)); + ASSERT_TRUE(model()->GetTabId(subframe_b).is_valid()); model()->Kill(subframe_b); ASSERT_NO_FATAL_FAILURE(
diff --git a/chrome/browser/task_manager/task_manager_interface.h b/chrome/browser/task_manager/task_manager_interface.h index 5893811..7aa902b 100644 --- a/chrome/browser/task_manager/task_manager_interface.h +++ b/chrome/browser/task_manager/task_manager_interface.h
@@ -20,6 +20,7 @@ #include "base/timer/timer.h" #include "chrome/browser/task_manager/providers/task.h" #include "chrome/browser/task_manager/task_manager_observer.h" +#include "components/sessions/core/session_id.h" #include "third_party/WebKit/public/platform/WebCache.h" #include "ui/gfx/image/image_skia.h" @@ -159,7 +160,7 @@ // Gets the unique ID of the tab if the task with |task_id| represents a // WebContents of a tab. Returns -1 otherwise. - virtual int GetTabId(TaskId task_id) const = 0; + virtual SessionID GetTabId(TaskId task_id) const = 0; // Returns the unique ID of the BrowserChildProcessHost/RenderProcessHost on // which the task with |task_id| is running. It is not the PID nor the handle
diff --git a/chrome/browser/task_manager/task_manager_tester.cc b/chrome/browser/task_manager/task_manager_tester.cc index 4bd243ce..dfa95c6 100644 --- a/chrome/browser/task_manager/task_manager_tester.cc +++ b/chrome/browser/task_manager/task_manager_tester.cc
@@ -172,7 +172,7 @@ return value; } -int32_t TaskManagerTester::GetTabId(int row) { +SessionID TaskManagerTester::GetTabId(int row) { TaskId task_id = model_->tasks_[row]; return task_manager()->GetTabId(task_id); }
diff --git a/chrome/browser/task_manager/task_manager_tester.h b/chrome/browser/task_manager/task_manager_tester.h index d762beb..f1398c5 100644 --- a/chrome/browser/task_manager/task_manager_tester.h +++ b/chrome/browser/task_manager/task_manager_tester.h
@@ -13,6 +13,7 @@ #include "base/memory/memory_coordinator_client.h" #include "base/strings/string16.h" #include "chrome/browser/task_manager/task_manager_browsertest_util.h" +#include "components/sessions/core/session_id.h" namespace task_manager { @@ -48,8 +49,8 @@ int64_t GetColumnValue(ColumnSpecifier column, int row); // If |row| is associated with a WebContents, return its SessionID. Otherwise, - // return -1. - int32_t GetTabId(int row); + // return SessionID::InvalidValue(). + SessionID GetTabId(int row); // Return the memory state of the process which is associated with |row|. base::MemoryState GetMemoryState(int row);
diff --git a/chrome/browser/task_manager/test_task_manager.cc b/chrome/browser/task_manager/test_task_manager.cc index 4ff357b..b12d21f 100644 --- a/chrome/browser/task_manager/test_task_manager.cc +++ b/chrome/browser/task_manager/test_task_manager.cc
@@ -112,8 +112,8 @@ return Task::UNKNOWN; } -int TestTaskManager::GetTabId(TaskId task_id) const { - return -1; +SessionID TestTaskManager::GetTabId(TaskId task_id) const { + return SessionID::InvalidValue(); } int TestTaskManager::GetChildProcessUniqueId(TaskId task_id) const {
diff --git a/chrome/browser/task_manager/test_task_manager.h b/chrome/browser/task_manager/test_task_manager.h index f99892a..3bb9c01b 100644 --- a/chrome/browser/task_manager/test_task_manager.h +++ b/chrome/browser/task_manager/test_task_manager.h
@@ -52,7 +52,7 @@ const base::ProcessHandle& GetProcessHandle(TaskId task_id) const override; const base::ProcessId& GetProcessId(TaskId task_id) const override; Task::Type GetType(TaskId task_id) const override; - int GetTabId(TaskId task_id) const override; + SessionID GetTabId(TaskId task_id) const override; int GetChildProcessUniqueId(TaskId task_id) const override; void GetTerminationStatus(TaskId task_id, base::TerminationStatus* out_status,
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 4c6ace2..4b92eba 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -347,6 +347,8 @@ "cocoa/infobars/before_translate_infobar_controller.mm", "cocoa/infobars/confirm_infobar_controller.h", "cocoa/infobars/confirm_infobar_controller.mm", + "cocoa/infobars/infobar_background_view.h", + "cocoa/infobars/infobar_background_view.mm", "cocoa/infobars/infobar_cocoa.h", "cocoa/infobars/infobar_cocoa.mm", "cocoa/infobars/infobar_container_cocoa.h", @@ -355,8 +357,6 @@ "cocoa/infobars/infobar_container_controller.mm", "cocoa/infobars/infobar_controller.h", "cocoa/infobars/infobar_controller.mm", - "cocoa/infobars/infobar_gradient_view.h", - "cocoa/infobars/infobar_gradient_view.mm", "cocoa/infobars/infobar_utilities.h", "cocoa/infobars/infobar_utilities.mm", "cocoa/infobars/translate_infobar_base.h", @@ -2865,6 +2865,8 @@ "views/harmony/harmony_layout_provider.h", "views/harmony/harmony_typography_provider.cc", "views/harmony/harmony_typography_provider.h", + "views/harmony/material_refresh_layout_provider.cc", + "views/harmony/material_refresh_layout_provider.h", "views/harmony/textfield_layout.cc", "views/harmony/textfield_layout.h", "views/hover_button.cc", @@ -3513,6 +3515,8 @@ "app_list/search/arc/arc_playstore_search_result.h", "app_list/search/arc/icon_decode_request.cc", "app_list/search/arc/icon_decode_request.h", + "app_list/search/chrome_search_result.cc", + "app_list/search/chrome_search_result.h", "app_list/search/common/json_response_fetcher.cc", "app_list/search/common/json_response_fetcher.h", "app_list/search/common/url_icon_source.cc",
diff --git a/chrome/browser/ui/android/tab_model/android_live_tab_context.cc b/chrome/browser/ui/android/tab_model/android_live_tab_context.cc index fd30458..6afed5d7 100644 --- a/chrome/browser/ui/android/tab_model/android_live_tab_context.cc +++ b/chrome/browser/ui/android/tab_model/android_live_tab_context.cc
@@ -127,15 +127,14 @@ if (!tab_android) return nullptr; - TabModel* model = TabModelList::FindTabModelWithId( - tab_android->window_id().id()); + TabModel* model = TabModelList::FindTabModelWithId(tab_android->window_id()); return model ? model->GetLiveTabContext() : nullptr; } // static. sessions::LiveTabContext* AndroidLiveTabContext::FindContextWithID( - SessionID::id_type desired_id) { + SessionID desired_id) { // Find the model with desired id. TabModel* tab_model = TabModelList::FindTabModelWithId(desired_id);
diff --git a/chrome/browser/ui/android/tab_model/android_live_tab_context.h b/chrome/browser/ui/android/tab_model/android_live_tab_context.h index 50d844e1..f5e12139 100644 --- a/chrome/browser/ui/android/tab_model/android_live_tab_context.h +++ b/chrome/browser/ui/android/tab_model/android_live_tab_context.h
@@ -57,8 +57,7 @@ static LiveTabContext* FindContextForWebContents( const content::WebContents* contents); - static sessions::LiveTabContext* FindContextWithID( - SessionID::id_type desired_id); + static sessions::LiveTabContext* FindContextWithID(SessionID desired_id); private: TabModel* tab_model_;
diff --git a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc index 5bb7320c..3811f64 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_jni_bridge.cc
@@ -72,7 +72,7 @@ // the window id. TabAndroid* tab = TabAndroid::GetNativeTab(env, jtab); if (tab) - tab->SetWindowSessionID(GetSessionId().id()); + tab->SetWindowSessionID(GetSessionId()); } int TabModelJniBridge::GetTabCount() const {
diff --git a/chrome/browser/ui/android/tab_model/tab_model_list.cc b/chrome/browser/ui/android/tab_model/tab_model_list.cc index 7e02839..0f9f9e8 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_list.cc +++ b/chrome/browser/ui/android/tab_model/tab_model_list.cc
@@ -79,11 +79,10 @@ return NULL; } -TabModel* TabModelList::FindTabModelWithId( - SessionID::id_type desired_id) { +TabModel* TabModelList::FindTabModelWithId(SessionID desired_id) { for (TabModelList::const_iterator i = TabModelList::begin(); i != TabModelList::end(); i++) { - if ((*i)->GetSessionId().id() == desired_id) + if ((*i)->GetSessionId() == desired_id) return *i; }
diff --git a/chrome/browser/ui/android/tab_model/tab_model_list.h b/chrome/browser/ui/android/tab_model/tab_model_list.h index e599ffc..223763ba 100644 --- a/chrome/browser/ui/android/tab_model/tab_model_list.h +++ b/chrome/browser/ui/android/tab_model/tab_model_list.h
@@ -39,7 +39,7 @@ static TabModel* GetTabModelForWebContents( content::WebContents* web_contents); - static TabModel* FindTabModelWithId(SessionID::id_type desired_id); + static TabModel* FindTabModelWithId(SessionID desired_id); static bool IsOffTheRecordSessionActive(); static const_iterator begin();
diff --git a/chrome/browser/ui/android/usb_chooser_dialog_android.cc b/chrome/browser/ui/android/usb_chooser_dialog_android.cc index 8c4f37f..02becb02 100644 --- a/chrome/browser/ui/android/usb_chooser_dialog_android.cc +++ b/chrome/browser/ui/android/usb_chooser_dialog_android.cc
@@ -13,169 +13,129 @@ #include "base/android/jni_string.h" #include "base/bind.h" #include "base/strings/utf_string_conversions.h" -#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/security_state_tab_helper.h" -#include "chrome/browser/usb/usb_blocklist.h" -#include "chrome/browser/usb/usb_chooser_context.h" -#include "chrome/browser/usb/usb_chooser_context_factory.h" -#include "chrome/browser/usb/usb_util.h" -#include "chrome/browser/usb/web_usb_histograms.h" #include "chrome/browser/vr/vr_tab_helper.h" #include "chrome/common/url_constants.h" #include "components/security_state/core/security_state.h" #include "components/url_formatter/elide_url.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" -#include "device/base/device_client.h" -#include "device/usb/mojo/type_converters.h" -#include "device/usb/public/cpp/filter_utils.h" -#include "device/usb/usb_device.h" -#include "device/usb/webusb_descriptors.h" #include "device/vr/buildflags/buildflags.h" #include "jni/UsbChooserDialog_jni.h" #include "ui/android/window_android.h" #include "url/gurl.h" -using device::UsbDevice; - -namespace { - -void OnDevicePermissionRequestComplete( - scoped_refptr<UsbDevice> device, - device::mojom::UsbChooserService::GetPermissionCallback callback, - bool granted) { - device::mojom::UsbDeviceInfoPtr device_info; - if (granted) - device_info = device::mojom::UsbDeviceInfo::From(*device); - std::move(callback).Run(std::move(device_info)); -} - -} // namespace - -UsbChooserDialogAndroid::UsbChooserDialogAndroid( - std::vector<device::mojom::UsbDeviceFilterPtr> filters, +// static +std::unique_ptr<UsbChooserDialogAndroid> UsbChooserDialogAndroid::Create( content::RenderFrameHost* render_frame_host, - device::mojom::UsbChooserService::GetPermissionCallback callback) - : render_frame_host_(render_frame_host), - callback_(std::move(callback)), - usb_service_observer_(this), - filters_(std::move(filters)), - weak_factory_(this) { + std::unique_ptr<ChooserController> controller, + base::OnceClosure on_close) { content::WebContents* web_contents = - content::WebContents::FromRenderFrameHost(render_frame_host_); + content::WebContents::FromRenderFrameHost(render_frame_host); // TODO(asimjour): This should be removed once we have proper // implementation of USB chooser in VR. if (vr::VrTabHelper::IsInVr(web_contents)) { - DCHECK(!callback_.is_null()); - std::move(callback_).Run(nullptr); vr::VrTabHelper::UISuppressed(vr::UiSuppressedElement::kUsbChooser); - return; + return nullptr; } - device::UsbService* usb_service = - device::DeviceClient::Get()->GetUsbService(); - if (!usb_service) - return; - - if (!usb_service_observer_.IsObserving(usb_service)) - usb_service_observer_.Add(usb_service); - // Create (and show) the UsbChooser dialog. base::android::ScopedJavaLocalRef<jobject> window_android = web_contents->GetNativeView()->GetWindowAndroid()->GetJavaObject(); JNIEnv* env = base::android::AttachCurrentThread(); base::android::ScopedJavaLocalRef<jstring> origin_string = base::android::ConvertUTF16ToJavaString( - env, url_formatter::FormatUrlForSecurityDisplay(GURL( - render_frame_host->GetLastCommittedOrigin().Serialize()))); + env, url_formatter::FormatOriginForSecurityDisplay( + render_frame_host->GetLastCommittedOrigin())); SecurityStateTabHelper* helper = SecurityStateTabHelper::FromWebContents(web_contents); DCHECK(helper); security_state::SecurityInfo security_info; helper->GetSecurityInfo(&security_info); - java_dialog_.Reset(Java_UsbChooserDialog_create( - env, window_android, origin_string, security_info.security_level, - reinterpret_cast<intptr_t>(this))); - if (!java_dialog_.is_null()) { - usb_service->GetDevices( - base::Bind(&UsbChooserDialogAndroid::GotUsbDeviceList, - weak_factory_.GetWeakPtr())); - } + auto dialog = std::make_unique<UsbChooserDialogAndroid>(std::move(controller), + std::move(on_close)); + dialog->java_dialog_.Reset(Java_UsbChooserDialog_create( + env, window_android, origin_string, security_info.security_level, + reinterpret_cast<intptr_t>(dialog.get()))); + if (dialog->java_dialog_.is_null()) + return nullptr; + + return dialog; +} + +UsbChooserDialogAndroid::UsbChooserDialogAndroid( + std::unique_ptr<ChooserController> controller, + base::OnceClosure on_close) + : controller_(std::move(controller)), on_close_(std::move(on_close)) { + controller_->set_view(this); } UsbChooserDialogAndroid::~UsbChooserDialogAndroid() { - if (!callback_.is_null()) - std::move(callback_).Run(nullptr); - if (!java_dialog_.is_null()) { Java_UsbChooserDialog_closeDialog(base::android::AttachCurrentThread(), java_dialog_); } + controller_->set_view(nullptr); } -void UsbChooserDialogAndroid::OnDeviceAdded(scoped_refptr<UsbDevice> device) { - if (DisplayDevice(device)) { - AddDeviceToChooserDialog(device); - devices_.push_back(device); - } +void UsbChooserDialogAndroid::OnOptionsInitialized() { + for (size_t i = 0; i < controller_->NumOptions(); ++i) + OnOptionAdded(i); + + JNIEnv* env = base::android::AttachCurrentThread(); + Java_UsbChooserDialog_setIdleState(env, java_dialog_); } -void UsbChooserDialogAndroid::OnDeviceRemoved(scoped_refptr<UsbDevice> device) { - auto it = std::find(devices_.begin(), devices_.end(), device); - if (it != devices_.end()) { - RemoveDeviceFromChooserDialog(device); - devices_.erase(it); - } +void UsbChooserDialogAndroid::OnOptionAdded(size_t index) { + JNIEnv* env = base::android::AttachCurrentThread(); + + DCHECK_LE(index, item_id_map_.size()); + int item_id = next_item_id_++; + std::string item_id_str = base::IntToString(item_id); + item_id_map_.insert(item_id_map_.begin() + index, item_id_str); + + base::string16 device_name = controller_->GetOption(index); + Java_UsbChooserDialog_addDevice( + env, java_dialog_, + base::android::ConvertUTF8ToJavaString(env, item_id_str), + base::android::ConvertUTF16ToJavaString(env, device_name)); } -void UsbChooserDialogAndroid::Select(const std::string& guid) { - for (size_t i = 0; i < devices_.size(); ++i) { - scoped_refptr<UsbDevice>& device = devices_[i]; - if (device->guid() == guid) { - content::WebContents* web_contents = - content::WebContents::FromRenderFrameHost(render_frame_host_); - GURL embedding_origin = - web_contents->GetMainFrame()->GetLastCommittedURL().GetOrigin(); - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); - UsbChooserContext* chooser_context = - UsbChooserContextFactory::GetForProfile(profile); - chooser_context->GrantDevicePermission( - render_frame_host_->GetLastCommittedURL().GetOrigin(), - embedding_origin, device->guid()); +void UsbChooserDialogAndroid::OnOptionRemoved(size_t index) { + JNIEnv* env = base::android::AttachCurrentThread(); - device->RequestPermission(base::BindOnce( - &OnDevicePermissionRequestComplete, device, std::move(callback_))); + DCHECK_LT(index, item_id_map_.size()); + std::string item_id = item_id_map_[index]; + item_id_map_.erase(item_id_map_.begin() + index); - Java_UsbChooserDialog_closeDialog(base::android::AttachCurrentThread(), - java_dialog_); - RecordWebUsbChooserClosure( - device->serial_number().empty() - ? WEBUSB_CHOOSER_CLOSED_EPHEMERAL_PERMISSION_GRANTED - : WEBUSB_CHOOSER_CLOSED_PERMISSION_GRANTED); - return; - } - } + Java_UsbChooserDialog_removeDevice( + env, java_dialog_, base::android::ConvertUTF8ToJavaString(env, item_id)); } -void UsbChooserDialogAndroid::Cancel() { - DCHECK(!callback_.is_null()); - std::move(callback_).Run(nullptr); - Java_UsbChooserDialog_closeDialog(base::android::AttachCurrentThread(), - java_dialog_); +void UsbChooserDialogAndroid::OnOptionUpdated(size_t index) { + NOTREACHED(); +} - RecordWebUsbChooserClosure(devices_.size() == 0 - ? WEBUSB_CHOOSER_CLOSED_CANCELLED_NO_DEVICES - : WEBUSB_CHOOSER_CLOSED_CANCELLED); +void UsbChooserDialogAndroid::OnAdapterEnabledChanged(bool enabled) { + NOTREACHED(); +} + +void UsbChooserDialogAndroid::OnRefreshStateChanged(bool refreshing) { + NOTREACHED(); } void UsbChooserDialogAndroid::OnItemSelected( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& device_id) { - Select(base::android::ConvertJavaStringToUTF8(env, device_id)); + const base::android::JavaParamRef<jstring>& item_id_jstring) { + std::string item_id = + base::android::ConvertJavaStringToUTF8(env, item_id_jstring); + auto it = std::find(item_id_map_.begin(), item_id_map_.end(), item_id); + DCHECK(it != item_id_map_.end()); + controller_->Select({std::distance(item_id_map_.begin(), it)}); + base::ResetAndReturn(&on_close_).Run(); } void UsbChooserDialogAndroid::OnDialogCancelled( @@ -187,59 +147,11 @@ void UsbChooserDialogAndroid::LoadUsbHelpPage( JNIEnv* env, const base::android::JavaParamRef<jobject>& obj) { - OpenUrl(chrome::kChooserUsbOverviewURL); + controller_->OpenHelpCenterUrl(); Cancel(); } -// Get a list of devices that can be shown in the chooser bubble UI for -// user to grant permsssion. -void UsbChooserDialogAndroid::GotUsbDeviceList( - const std::vector<scoped_refptr<UsbDevice>>& devices) { - for (const auto& device : devices) { - if (DisplayDevice(device)) { - AddDeviceToChooserDialog(device); - devices_.push_back(device); - } - } - - JNIEnv* env = base::android::AttachCurrentThread(); - Java_UsbChooserDialog_setIdleState(env, java_dialog_); -} - -void UsbChooserDialogAndroid::AddDeviceToChooserDialog( - scoped_refptr<UsbDevice> device) const { - JNIEnv* env = base::android::AttachCurrentThread(); - base::android::ScopedJavaLocalRef<jstring> device_guid = - base::android::ConvertUTF8ToJavaString(env, device->guid()); - base::android::ScopedJavaLocalRef<jstring> device_name = - base::android::ConvertUTF16ToJavaString(env, FormatUsbDeviceName(device)); - Java_UsbChooserDialog_addDevice(env, java_dialog_, device_guid, device_name); -} - -void UsbChooserDialogAndroid::RemoveDeviceFromChooserDialog( - scoped_refptr<UsbDevice> device) const { - JNIEnv* env = base::android::AttachCurrentThread(); - base::android::ScopedJavaLocalRef<jstring> device_guid = - base::android::ConvertUTF8ToJavaString(env, device->guid()); - Java_UsbChooserDialog_removeDevice(env, java_dialog_, device_guid); -} - -void UsbChooserDialogAndroid::OpenUrl(const std::string& url) { - content::WebContents::FromRenderFrameHost(render_frame_host_) - ->OpenURL( - content::OpenURLParams(GURL(url), content::Referrer(), - WindowOpenDisposition::NEW_FOREGROUND_TAB, - ui::PAGE_TRANSITION_AUTO_TOPLEVEL, - false)); // is_renderer_initiated -} - -bool UsbChooserDialogAndroid::DisplayDevice( - scoped_refptr<UsbDevice> device) const { - if (!UsbDeviceFilterMatchesAny(filters_, *device)) - return false; - - if (UsbBlocklist::Get().IsExcluded(device)) - return false; - - return true; +void UsbChooserDialogAndroid::Cancel() { + controller_->Cancel(); + base::ResetAndReturn(&on_close_).Run(); }
diff --git a/chrome/browser/ui/android/usb_chooser_dialog_android.h b/chrome/browser/ui/android/usb_chooser_dialog_android.h index c29f17e..97f5498 100644 --- a/chrome/browser/ui/android/usb_chooser_dialog_android.h +++ b/chrome/browser/ui/android/usb_chooser_dialog_android.h
@@ -5,78 +5,66 @@ #ifndef CHROME_BROWSER_UI_ANDROID_USB_CHOOSER_DIALOG_ANDROID_H_ #define CHROME_BROWSER_UI_ANDROID_USB_CHOOSER_DIALOG_ANDROID_H_ +#include <memory> #include <string> #include <vector> #include "base/android/scoped_java_ref.h" +#include "base/callback.h" #include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/scoped_observer.h" -#include "base/strings/string16.h" -#include "device/usb/public/mojom/chooser_service.mojom.h" -#include "device/usb/usb_service.h" +#include "chrome/browser/chooser_controller/chooser_controller.h" namespace content { class RenderFrameHost; } -namespace device { -class UsbDevice; -} - // Represents a way to ask the user to select a USB device from a list of // options. -class UsbChooserDialogAndroid : public device::UsbService::Observer { +class UsbChooserDialogAndroid : public ChooserController::View { public: - UsbChooserDialogAndroid( - std::vector<device::mojom::UsbDeviceFilterPtr> filters, + // Creates and shows the dialog. Will return nullptr if the dialog was not + // displayed. Otherwise |on_close| will be called when the user closes the + // dialog. + static std::unique_ptr<UsbChooserDialogAndroid> Create( content::RenderFrameHost* render_frame_host, - device::mojom::UsbChooserService::GetPermissionCallback callback); + std::unique_ptr<ChooserController> controller, + base::OnceClosure on_close); + + explicit UsbChooserDialogAndroid( + std::unique_ptr<ChooserController> controller, + base::OnceClosure on_close); ~UsbChooserDialogAndroid() override; - // device::UsbService::Observer: - void OnDeviceAdded(scoped_refptr<device::UsbDevice> device) override; - void OnDeviceRemoved(scoped_refptr<device::UsbDevice> device) override; + // ChooserController::View implementation + void OnOptionsInitialized() override; + void OnOptionAdded(size_t index) override; + void OnOptionRemoved(size_t index) override; + void OnOptionUpdated(size_t index) override; + void OnAdapterEnabledChanged(bool enabled) override; + void OnRefreshStateChanged(bool refreshing) override; // Report the dialog's result. void OnItemSelected(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj, - const base::android::JavaParamRef<jstring>& device_id); + const base::android::JavaParamRef<jstring>& item_id); void OnDialogCancelled(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); - void LoadUsbHelpPage(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj); private: - void GotUsbDeviceList( - const std::vector<scoped_refptr<device::UsbDevice>>& devices); - - // Called when the user selects the USB device with |guid| from the chooser - // dialog. - void Select(const std::string& guid); // Called when the chooser dialog is closed. void Cancel(); - void AddDeviceToChooserDialog(scoped_refptr<device::UsbDevice> device) const; - void RemoveDeviceFromChooserDialog( - scoped_refptr<device::UsbDevice> device) const; + std::unique_ptr<ChooserController> controller_; + base::OnceClosure on_close_; - void OpenUrl(const std::string& url); - - bool DisplayDevice(scoped_refptr<device::UsbDevice> device) const; - - content::RenderFrameHost* const render_frame_host_; - device::mojom::UsbChooserService::GetPermissionCallback callback_; - ScopedObserver<device::UsbService, device::UsbService::Observer> - usb_service_observer_; - std::vector<device::mojom::UsbDeviceFilterPtr> filters_; - - std::vector<scoped_refptr<device::UsbDevice>> devices_; + // The Java dialog code expects items to have unique string IDs while the + // ChooserController code refers to devices by their position in the list. + int next_item_id_ = 0; + std::vector<std::string> item_id_map_; base::android::ScopedJavaGlobalRef<jobject> java_dialog_; - base::WeakPtrFactory<UsbChooserDialogAndroid> weak_factory_; DISALLOW_COPY_AND_ASSIGN(UsbChooserDialogAndroid); };
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h index ffa9d61..798fe6c 100644 --- a/chrome/browser/ui/app_list/app_list_model_updater.h +++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -16,6 +16,7 @@ #include "base/strings/string16.h" #include "chrome/browser/ui/app_list/app_list_model_updater_delegate.h" #include "chrome/browser/ui/app_list/app_list_syncable_service.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" class ChromeAppListItem; @@ -64,7 +65,7 @@ virtual void UpdateSearchBox(const base::string16& text, bool initiated_by_user) {} virtual void PublishSearchResults( - std::vector<std::unique_ptr<app_list::SearchResult>> results) {} + std::vector<std::unique_ptr<ChromeSearchResult>> results) {} // Item field setters only used by ChromeAppListItem and its derived classes. virtual void SetItemIcon(const std::string& id, const gfx::ImageSkia& icon) {} @@ -118,10 +119,9 @@ virtual size_t BadgedItemCount() = 0; // For SearchModel: virtual bool SearchEngineIsGoogle() = 0; - virtual app_list::SearchResult* FindSearchResult( + virtual ChromeSearchResult* FindSearchResult( const std::string& result_id) = 0; - virtual app_list::SearchResult* GetResultByTitle( - const std::string& title) = 0; + virtual ChromeSearchResult* GetResultByTitle(const std::string& title) = 0; // Methods for handle model updates in ash: virtual void OnFolderCreated(ash::mojom::AppListItemMetadataPtr item) = 0;
diff --git a/chrome/browser/ui/app_list/app_list_view_delegate.cc b/chrome/browser/ui/app_list/app_list_view_delegate.cc index 86e032d..b2d72c7 100644 --- a/chrome/browser/ui/app_list/app_list_view_delegate.cc +++ b/chrome/browser/ui/app_list/app_list_view_delegate.cc
@@ -177,7 +177,7 @@ void AppListViewDelegate::OpenSearchResult(const std::string& result_id, int event_flags) { - app_list::SearchResult* result = model_updater_->FindSearchResult(result_id); + ChromeSearchResult* result = model_updater_->FindSearchResult(result_id); if (result) search_controller_->OpenResult(result, event_flags); } @@ -185,7 +185,7 @@ void AppListViewDelegate::InvokeSearchResultAction(const std::string& result_id, int action_index, int event_flags) { - app_list::SearchResult* result = model_updater_->FindSearchResult(result_id); + ChromeSearchResult* result = model_updater_->FindSearchResult(result_id); if (result) search_controller_->InvokeResultAction(result, action_index, event_flags); }
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc index d22bd25..b02b1fce5 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -8,6 +8,7 @@ #include <utility> #include "ash/app_list/model/search/search_model.h" +#include "ash/app_list/model/search/search_result.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/app_list/app_list_service_impl.h" #include "chrome/browser/ui/app_list/chrome_app_list_item.h" @@ -15,6 +16,26 @@ #include "extensions/common/constants.h" #include "ui/base/models/menu_model.h" +namespace { + +// TODO(hejq): Get rid of these after refactoring ChromeSearchResult. +ChromeSearchResult* ConvertToChromeSearchResult( + app_list::SearchResult* result) { + return static_cast<ChromeSearchResult*>(result); +} + +std::vector<std::unique_ptr<app_list::SearchResult>> ConvertToSearchResults( + std::vector<std::unique_ptr<ChromeSearchResult>> results) { + std::vector<std::unique_ptr<app_list::SearchResult>> ash_results; + for (auto& result : results) { + ash_results.push_back( + base::WrapUnique<app_list::SearchResult>(result.release())); + } + return ash_results; +} + +} // namespace + ChromeAppListModelUpdater::ChromeAppListModelUpdater(Profile* profile) : profile_(profile), weak_ptr_factory_(this) { // TODO(hejq): remove this when search migration is done. @@ -139,9 +160,9 @@ } void ChromeAppListModelUpdater::PublishSearchResults( - std::vector<std::unique_ptr<app_list::SearchResult>> results) { + std::vector<std::unique_ptr<ChromeSearchResult>> results) { if (!ash_util::IsRunningInMash()) - search_model_->PublishResults(std::move(results)); + search_model_->PublishResults(ConvertToSearchResults(std::move(results))); } void ChromeAppListModelUpdater::ActivateChromeItem(const std::string& id, @@ -335,12 +356,14 @@ chrome_item->ContextMenuItemSelected(command_id, event_flags); } -app_list::SearchResult* ChromeAppListModelUpdater::FindSearchResult( +ChromeSearchResult* ChromeAppListModelUpdater::FindSearchResult( const std::string& result_id) { - return search_model_ ? search_model_->FindSearchResult(result_id) : nullptr; + return search_model_ ? ConvertToChromeSearchResult( + search_model_->FindSearchResult(result_id)) + : nullptr; } -app_list::SearchResult* ChromeAppListModelUpdater::GetResultByTitle( +ChromeSearchResult* ChromeAppListModelUpdater::GetResultByTitle( const std::string& title) { if (!search_model_) return nullptr; @@ -354,7 +377,7 @@ result->result_type() == ash::SearchResultType::kInstalledApp && result->display_type() != ash::SearchResultDisplayType::kRecommendation) { - return result.get(); + return ConvertToChromeSearchResult(result.get()); } } return nullptr;
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h index 93dc3b8..3b74609f 100644 --- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -50,7 +50,7 @@ void UpdateSearchBox(const base::string16& text, bool initiated_by_user) override; void PublishSearchResults( - std::vector<std::unique_ptr<app_list::SearchResult>> results) override; + std::vector<std::unique_ptr<ChromeSearchResult>> results) override; // Methods only used by ChromeAppListItem that talk to ash directly. void SetItemIcon(const std::string& id, const gfx::ImageSkia& icon) override; @@ -86,9 +86,8 @@ void ContextMenuItemSelected(const std::string& id, int command_id, int event_flags) override; - app_list::SearchResult* FindSearchResult( - const std::string& result_id) override; - app_list::SearchResult* GetResultByTitle(const std::string& title) override; + ChromeSearchResult* FindSearchResult(const std::string& result_id) override; + ChromeSearchResult* GetResultByTitle(const std::string& title) override; // Methods for AppListSyncableService: void AddItemToOemFolder(
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_result.cc b/chrome/browser/ui/app_list/search/answer_card/answer_card_result.cc index aa070fb..dcc97ed 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_result.cc +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_result.cc
@@ -42,7 +42,7 @@ contents_ = nullptr; } -std::unique_ptr<SearchResult> AnswerCardResult::Duplicate() const { +std::unique_ptr<ChromeSearchResult> AnswerCardResult::Duplicate() const { return std::make_unique<AnswerCardResult>( profile_, list_controller_, id(), comparable_id(), title(), contents_); }
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_result.h b/chrome/browser/ui/app_list/search/answer_card/answer_card_result.h index 7b309e7..70172a3 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_result.h +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_result.h
@@ -8,7 +8,7 @@ #include <memory> #include <string> -#include "ash/app_list/model/search/search_result.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" class AppListControllerDelegate; class Profile; @@ -18,7 +18,7 @@ class AnswerCardContents; // Result of AnswerCardSearchProvider. -class AnswerCardResult : public SearchResult { +class AnswerCardResult : public ChromeSearchResult { public: AnswerCardResult(Profile* profile, AppListControllerDelegate* list_controller, @@ -31,8 +31,8 @@ void OnContentsDestroying(); - // SearchResult overrides: - std::unique_ptr<SearchResult> Duplicate() const override; + // ChromeSearchResult overrides: + std::unique_ptr<ChromeSearchResult> Duplicate() const override; void Open(int event_flags) override;
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_result_unittest.cc b/chrome/browser/ui/app_list/search/answer_card/answer_card_result_unittest.cc index 67144e4..d5dbd820 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_result_unittest.cc +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_result_unittest.cc
@@ -93,7 +93,7 @@ result->Open(ui::EF_NONE); EXPECT_EQ(kResultUrl, GetLastOpenedUrl().spec()); - std::unique_ptr<SearchResult> result1 = result->Duplicate(); + std::unique_ptr<ChromeSearchResult> result1 = result->Duplicate(); EXPECT_EQ(kResultUrl, result1->id()); EXPECT_EQ(base::ASCIIToUTF16(kResultTitle), result1->title()); @@ -108,7 +108,7 @@ // Shouldn't crash with null contents. std::unique_ptr<AnswerCardResult> result = CreateResult( kResultUrl, kResultUrlStripped, base::ASCIIToUTF16(kResultTitle)); - std::unique_ptr<SearchResult> result1 = result->Duplicate(); + std::unique_ptr<ChromeSearchResult> result1 = result->Duplicate(); } TEST_F(AnswerCardResultTest, EarlyDeleteContents) {
diff --git a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc index a005206..5fd26df 100644 --- a/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider_unittest.cc
@@ -9,7 +9,6 @@ #include <string> #include <utility> -#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/metrics/field_trial.h" #include "base/metrics/field_trial_params.h" @@ -19,6 +18,7 @@ #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/ui/app_list/app_list_test_util.h" #include "chrome/browser/ui/app_list/search/answer_card/answer_card_search_provider.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h" #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" #include "chrome/test/base/testing_profile.h" @@ -108,7 +108,7 @@ SCOPED_TRACE(message); EXPECT_EQ(1UL, results().size()); - SearchResult* result = results()[0].get(); + ChromeSearchResult* result = results()[0].get(); EXPECT_EQ(ash::SearchResultDisplayType::kCard, result->display_type()); EXPECT_EQ(id, result->id()); EXPECT_EQ(1, result->relevance());
diff --git a/chrome/browser/ui/app_list/search/app_result.h b/chrome/browser/ui/app_list/search/app_result.h index a51a342..f49c97f 100644 --- a/chrome/browser/ui/app_list/search/app_result.h +++ b/chrome/browser/ui/app_list/search/app_result.h
@@ -8,9 +8,9 @@ #include <memory> #include <string> -#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "chrome/browser/ui/app_list/app_context_menu_delegate.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" class AppListControllerDelegate; class Profile; @@ -20,8 +20,7 @@ } namespace app_list { -class AppResult : public SearchResult, - public AppContextMenuDelegate { +class AppResult : public ChromeSearchResult, public AppContextMenuDelegate { public: ~AppResult() override;
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_data_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/arc/arc_app_data_search_provider_unittest.cc index bcb7742..c196c0e 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_app_data_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/arc/arc_app_data_search_provider_unittest.cc
@@ -7,12 +7,12 @@ #include <memory> #include <utility> -#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/app_list/app_list_test_util.h" #include "chrome/browser/ui/app_list/arc/arc_app_test.h" #include "chrome/browser/ui/app_list/search/arc/icon_decode_request.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" namespace app_list {
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_data_search_result.cc b/chrome/browser/ui/app_list/search/arc/arc_app_data_search_result.cc index 23dd323a..06f9499 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_app_data_search_result.cc +++ b/chrome/browser/ui/app_list/search/arc/arc_app_data_search_result.cc
@@ -99,7 +99,7 @@ ArcAppDataSearchResult::~ArcAppDataSearchResult() = default; -std::unique_ptr<SearchResult> ArcAppDataSearchResult::Duplicate() const { +std::unique_ptr<ChromeSearchResult> ArcAppDataSearchResult::Duplicate() const { std::unique_ptr<ArcAppDataSearchResult> result = std::make_unique<ArcAppDataSearchResult>(data_.Clone(), profile_, list_controller_);
diff --git a/chrome/browser/ui/app_list/search/arc/arc_app_data_search_result.h b/chrome/browser/ui/app_list/search/arc/arc_app_data_search_result.h index 7243d52..677a2899 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_app_data_search_result.h +++ b/chrome/browser/ui/app_list/search/arc/arc_app_data_search_result.h
@@ -9,9 +9,9 @@ #include <string> #include <vector> -#include "ash/app_list/model/search/search_result.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "components/arc/common/app.mojom.h" class AppListControllerDelegate; @@ -21,15 +21,15 @@ class IconDecodeRequest; -class ArcAppDataSearchResult : public SearchResult { +class ArcAppDataSearchResult : public ChromeSearchResult { public: ArcAppDataSearchResult(arc::mojom::AppDataResultPtr data, Profile* profile, AppListControllerDelegate* list_controller); ~ArcAppDataSearchResult() override; - // app_list::SearchResult: - std::unique_ptr<SearchResult> Duplicate() const override; + // ChromeSearchResult: + std::unique_ptr<ChromeSearchResult> Duplicate() const override; ui::MenuModel* GetContextMenuModel() override; void Open(int event_flags) override;
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc index 24cb73b..d967222 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_provider_unittest.cc
@@ -8,7 +8,6 @@ #include <string> #include <utility> -#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_service.h" @@ -16,6 +15,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_test.h" #include "chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h" #include "chrome/browser/ui/app_list/search/arc/icon_decode_request.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" #include "chrome/test/base/testing_profile.h" #include "components/arc/app/arc_playstore_search_request_state.h"
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.cc b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.cc index d4d8fdd..fc2fd46 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.cc +++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.cc
@@ -82,7 +82,8 @@ ArcPlayStoreSearchResult::~ArcPlayStoreSearchResult() = default; -std::unique_ptr<SearchResult> ArcPlayStoreSearchResult::Duplicate() const { +std::unique_ptr<ChromeSearchResult> ArcPlayStoreSearchResult::Duplicate() + const { std::unique_ptr<ArcPlayStoreSearchResult> result = std::make_unique<ArcPlayStoreSearchResult>(data_.Clone(), profile_, list_controller_);
diff --git a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h index 3846780..8e17247 100644 --- a/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h +++ b/chrome/browser/ui/app_list/search/arc/arc_playstore_search_result.h
@@ -9,10 +9,10 @@ #include <string> #include <vector> -#include "ash/app_list/model/search/search_result.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" #include "chrome/browser/ui/app_list/app_context_menu_delegate.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "components/arc/common/app.mojom.h" class AppListControllerDelegate; @@ -23,7 +23,7 @@ class IconDecodeRequest; -class ArcPlayStoreSearchResult : public SearchResult, +class ArcPlayStoreSearchResult : public ChromeSearchResult, public AppContextMenuDelegate { public: ArcPlayStoreSearchResult(arc::mojom::AppDiscoveryResultPtr data, @@ -31,8 +31,8 @@ AppListControllerDelegate* list_controller_); ~ArcPlayStoreSearchResult() override; - // app_list::SearchResult overrides: - std::unique_ptr<SearchResult> Duplicate() const override; + // ChromeSearchResult overrides: + std::unique_ptr<ChromeSearchResult> Duplicate() const override; ui::MenuModel* GetContextMenuModel() override; void Open(int event_flags) override;
diff --git a/chrome/browser/ui/app_list/search/arc/icon_decode_request.cc b/chrome/browser/ui/app_list/search/arc/icon_decode_request.cc index f0fc7970..3365b90 100644 --- a/chrome/browser/ui/app_list/search/arc/icon_decode_request.cc +++ b/chrome/browser/ui/app_list/search/arc/icon_decode_request.cc
@@ -8,6 +8,7 @@ #include <utility> #include <vector> +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/grit/component_extension_resources.h" #include "content/public/browser/browser_thread.h" #include "ui/app_list/app_list_constants.h"
diff --git a/chrome/browser/ui/app_list/search/arc_app_result.cc b/chrome/browser/ui/app_list/search/arc_app_result.cc index 8eccac2..443c999 100644 --- a/chrome/browser/ui/app_list/search/arc_app_result.cc +++ b/chrome/browser/ui/app_list/search/arc_app_result.cc
@@ -58,15 +58,15 @@ controller()->DismissView(); } -std::unique_ptr<SearchResult> ArcAppResult::Duplicate() const { - std::unique_ptr<SearchResult> copy = std::make_unique<ArcAppResult>( +std::unique_ptr<ChromeSearchResult> ArcAppResult::Duplicate() const { + ArcAppResult* copy = new ArcAppResult( profile(), app_id(), controller(), display_type() == ash::SearchResultDisplayType::kRecommendation); copy->set_title(title()); copy->set_title_tags(title_tags()); copy->set_relevance(relevance()); - return copy; + return base::WrapUnique(copy); } ui::MenuModel* ArcAppResult::GetContextMenuModel() {
diff --git a/chrome/browser/ui/app_list/search/arc_app_result.h b/chrome/browser/ui/app_list/search/arc_app_result.h index 60e7841..ee836fc 100644 --- a/chrome/browser/ui/app_list/search/arc_app_result.h +++ b/chrome/browser/ui/app_list/search/arc_app_result.h
@@ -28,9 +28,9 @@ bool is_recommendation); ~ArcAppResult() override; - // SearchResult overrides: + // ChromeSearchResult overrides: void Open(int event_flags) override; - std::unique_ptr<SearchResult> Duplicate() const override; + std::unique_ptr<ChromeSearchResult> Duplicate() const override; ui::MenuModel* GetContextMenuModel() override; // AppContextMenuDelegate overrides:
diff --git a/chrome/browser/ui/app_list/search/chrome_search_result.cc b/chrome/browser/ui/app_list/search/chrome_search_result.cc new file mode 100644 index 0000000..05aedcc --- /dev/null +++ b/chrome/browser/ui/app_list/search/chrome_search_result.cc
@@ -0,0 +1,7 @@ +// Copyright 2018 The Chromium Authors. 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/search/chrome_search_result.h" + +ChromeSearchResult::ChromeSearchResult() = default;
diff --git a/chrome/browser/ui/app_list/search/chrome_search_result.h b/chrome/browser/ui/app_list/search/chrome_search_result.h new file mode 100644 index 0000000..744a2007 --- /dev/null +++ b/chrome/browser/ui/app_list/search/chrome_search_result.h
@@ -0,0 +1,28 @@ +// Copyright 2018 The Chromium Authors. 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_SEARCH_CHROME_SEARCH_RESULT_H_ +#define CHROME_BROWSER_UI_APP_LIST_SEARCH_CHROME_SEARCH_RESULT_H_ + +#include <memory> + +#include "ash/app_list/model/search/search_result.h" +#include "base/macros.h" + +// ChromeSearchResult consists of an icon, title text and details text. Title +// and details text can have tagged ranges that are displayed differently from +// default style. +class ChromeSearchResult : public app_list::SearchResult { + public: + ChromeSearchResult(); + + // TODO(mukai): Remove this method and really simplify the ownership of + // SearchResult. Ideally, SearchResult will be copyable. + virtual std::unique_ptr<ChromeSearchResult> Duplicate() const = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(ChromeSearchResult); +}; + +#endif // CHROME_BROWSER_UI_APP_LIST_SEARCH_CHROME_SEARCH_RESULT_H_
diff --git a/chrome/browser/ui/app_list/search/extension_app_result.cc b/chrome/browser/ui/app_list/search/extension_app_result.cc index 1d254887..c662925 100644 --- a/chrome/browser/ui/app_list/search/extension_app_result.cc +++ b/chrome/browser/ui/app_list/search/extension_app_result.cc
@@ -65,7 +65,7 @@ if (RunExtensionEnableFlow()) return; - // Record the search metrics if the SearchResult is not a suggested app. + // Record the search metrics if the ChromeSearchResult is not a suggested app. if (display_type() != ash::SearchResultDisplayType::kRecommendation) { RecordHistogram(APP_SEARCH_RESULT); extensions::RecordAppListSearchLaunch(extension); @@ -78,10 +78,11 @@ event_flags); } -std::unique_ptr<SearchResult> ExtensionAppResult::Duplicate() const { - std::unique_ptr<SearchResult> copy = std::make_unique<ExtensionAppResult>( - profile(), app_id(), controller(), - display_type() == ash::SearchResultDisplayType::kRecommendation); +std::unique_ptr<ChromeSearchResult> ExtensionAppResult::Duplicate() const { + std::unique_ptr<ChromeSearchResult> copy = + std::make_unique<ExtensionAppResult>( + profile(), app_id(), controller(), + display_type() == ash::SearchResultDisplayType::kRecommendation); copy->set_title(title()); copy->set_title_tags(title_tags()); copy->set_relevance(relevance());
diff --git a/chrome/browser/ui/app_list/search/extension_app_result.h b/chrome/browser/ui/app_list/search/extension_app_result.h index 6bd16f0..9409019 100644 --- a/chrome/browser/ui/app_list/search/extension_app_result.h +++ b/chrome/browser/ui/app_list/search/extension_app_result.h
@@ -38,9 +38,9 @@ bool is_recommendation); ~ExtensionAppResult() override; - // SearchResult overrides: + // ChromeSearchResult overrides: void Open(int event_flags) override; - std::unique_ptr<SearchResult> Duplicate() const override; + std::unique_ptr<ChromeSearchResult> Duplicate() const override; ui::MenuModel* GetContextMenuModel() override; private:
diff --git a/chrome/browser/ui/app_list/search/internal_app_result.cc b/chrome/browser/ui/app_list/search/internal_app_result.cc index 4959b82..8f86ae6 100644 --- a/chrome/browser/ui/app_list/search/internal_app_result.cc +++ b/chrome/browser/ui/app_list/search/internal_app_result.cc
@@ -59,7 +59,7 @@ keyboard_shortcut_viewer_util::ShowKeyboardShortcutViewer(); } -std::unique_ptr<SearchResult> InternalAppResult::Duplicate() const { +std::unique_ptr<ChromeSearchResult> InternalAppResult::Duplicate() const { auto copy = std::make_unique<InternalAppResult>( profile(), app_id(), controller(), display_type() == DisplayType::kRecommendation);
diff --git a/chrome/browser/ui/app_list/search/internal_app_result.h b/chrome/browser/ui/app_list/search/internal_app_result.h index ee92edb..169832b06 100644 --- a/chrome/browser/ui/app_list/search/internal_app_result.h +++ b/chrome/browser/ui/app_list/search/internal_app_result.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_UI_APP_LIST_SEARCH_INTERNAL_APP_RESULT_H_ #include <memory> +#include <string> #include "base/macros.h" #include "chrome/browser/ui/app_list/search/app_result.h" @@ -25,7 +26,7 @@ // SearchResult overrides: void Open(int event_flags) override; - std::unique_ptr<SearchResult> Duplicate() const override; + std::unique_ptr<ChromeSearchResult> Duplicate() const override; ui::MenuModel* GetContextMenuModel() override; // AppContextMenuDelegate overrides:
diff --git a/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.cc b/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.cc index a4282c3..eb1815a 100644 --- a/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.cc +++ b/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.cc
@@ -52,7 +52,7 @@ icon_image_loader_->RemoveObserver(this); } -std::unique_ptr<SearchResult> LauncherSearchResult::Duplicate() const { +std::unique_ptr<ChromeSearchResult> LauncherSearchResult::Duplicate() const { LauncherSearchResult* duplicated_result = new LauncherSearchResult(item_id_, discrete_value_relevance_, profile_, extension_, icon_image_loader_);
diff --git a/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h b/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h index 7f8f181..0270e2e4 100644 --- a/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h +++ b/chrome/browser/ui/app_list/search/launcher_search/launcher_search_result.h
@@ -8,17 +8,17 @@ #include <memory> #include <string> -#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/memory/linked_ptr.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/launcher_search/launcher_search_icon_image_loader.h" #include "extensions/common/extension.h" #include "url/gurl.h" namespace app_list { -class LauncherSearchResult : public SearchResult, +class LauncherSearchResult : public ChromeSearchResult, public LauncherSearchIconImageLoader::Observer { public: LauncherSearchResult( @@ -30,7 +30,7 @@ std::unique_ptr<chromeos::launcher_search_provider::ErrorReporter> error_reporter); ~LauncherSearchResult() override; - std::unique_ptr<SearchResult> Duplicate() const override; + std::unique_ptr<ChromeSearchResult> Duplicate() const override; void Open(int event_flags) override; void OnIconImageChanged(LauncherSearchIconImageLoader* image_loader) override;
diff --git a/chrome/browser/ui/app_list/search/mixer.cc b/chrome/browser/ui/app_list/search/mixer.cc index b1297c6e..df1dd4f 100644 --- a/chrome/browser/ui/app_list/search/mixer.cc +++ b/chrome/browser/ui/app_list/search/mixer.cc
@@ -11,17 +11,17 @@ #include <utility> #include <vector> -#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/memory/ptr_util.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/search_provider.h" namespace app_list { namespace { -const std::string& GetComparableId(const SearchResult& result) { +const std::string& GetComparableId(const ChromeSearchResult& result) { return !result.comparable_id().empty() ? result.comparable_id() : result.id(); } @@ -29,7 +29,7 @@ Mixer::SortData::SortData() : result(nullptr), score(0.0) {} -Mixer::SortData::SortData(SearchResult* result, double score) +Mixer::SortData::SortData(ChromeSearchResult* result, double score) : result(result), score(score) {} bool Mixer::SortData::operator<(const SortData& other) const { @@ -137,9 +137,9 @@ std::sort(results.begin() + original_size, results.end()); } - std::vector<std::unique_ptr<app_list::SearchResult>> new_results; + std::vector<std::unique_ptr<ChromeSearchResult>> new_results; for (const SortData& sort_data : results) { - std::unique_ptr<app_list::SearchResult> new_result = + std::unique_ptr<ChromeSearchResult> new_result = sort_data.result->Duplicate(); new_result->set_relevance(sort_data.score); new_results.push_back(std::move(new_result));
diff --git a/chrome/browser/ui/app_list/search/mixer.h b/chrome/browser/ui/app_list/search/mixer.h index c3cc3ea..fe17c07d 100644 --- a/chrome/browser/ui/app_list/search/mixer.h +++ b/chrome/browser/ui/app_list/search/mixer.h
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/app_list/search/history_types.h" class AppListModelUpdater; +class ChromeSearchResult; namespace app_list { @@ -23,7 +24,6 @@ } class SearchProvider; -class SearchResult; // Mixer collects results from providers, sorts them and publishes them to the // SearchResults UI model. The targeted results have 6 slots to hold the @@ -54,11 +54,11 @@ // Used for sorting and mixing results. struct SortData { SortData(); - SortData(SearchResult* result, double score); + SortData(ChromeSearchResult* result, double score); bool operator<(const SortData& other) const; - SearchResult* result; // Not owned. + ChromeSearchResult* result; // Not owned. double score; }; typedef std::vector<Mixer::SortData> SortedResults;
diff --git a/chrome/browser/ui/app_list/search/omnibox_result.cc b/chrome/browser/ui/app_list/search/omnibox_result.cc index 4bfd596e..a39e073 100644 --- a/chrome/browser/ui/app_list/search/omnibox_result.cc +++ b/chrome/browser/ui/app_list/search/omnibox_result.cc
@@ -35,30 +35,30 @@ int ACMatchStyleToTagStyle(int styles) { int tag_styles = 0; if (styles & ACMatchClassification::URL) - tag_styles |= SearchResult::Tag::URL; + tag_styles |= ash::SearchResultTag::URL; if (styles & ACMatchClassification::MATCH) - tag_styles |= SearchResult::Tag::MATCH; + tag_styles |= ash::SearchResultTag::MATCH; if (styles & ACMatchClassification::DIM) - tag_styles |= SearchResult::Tag::DIM; + tag_styles |= ash::SearchResultTag::DIM; return tag_styles; } -// Translates ACMatchClassifications into SearchResult tags. +// Translates ACMatchClassifications into ChromeSearchResult tags. void ACMatchClassificationsToTags(const base::string16& text, const ACMatchClassifications& text_classes, - SearchResult::Tags* tags) { - int tag_styles = SearchResult::Tag::NONE; + ChromeSearchResult::Tags* tags) { + int tag_styles = ash::SearchResultTag::NONE; size_t tag_start = 0; for (size_t i = 0; i < text_classes.size(); ++i) { const ACMatchClassification& text_class = text_classes[i]; // Closes current tag. - if (tag_styles != SearchResult::Tag::NONE) { + if (tag_styles != ash::SearchResultTag::NONE) { tags->push_back( - SearchResult::Tag(tag_styles, tag_start, text_class.offset)); - tag_styles = SearchResult::Tag::NONE; + ash::SearchResultTag(tag_styles, tag_start, text_class.offset)); + tag_styles = ash::SearchResultTag::NONE; } if (text_class.style == ACMatchClassification::NONE) @@ -68,8 +68,8 @@ tag_styles = ACMatchStyleToTagStyle(text_class.style); } - if (tag_styles != SearchResult::Tag::NONE) { - tags->push_back(SearchResult::Tag(tag_styles, tag_start, text.length())); + if (tag_styles != ash::SearchResultTag::NONE) { + tags->push_back(ash::SearchResultTag(tag_styles, tag_start, text.length())); } } @@ -154,9 +154,9 @@ ui::DispositionFromEventFlags(event_flags)); } -std::unique_ptr<SearchResult> OmniboxResult::Duplicate() const { - return std::unique_ptr<SearchResult>(new OmniboxResult( - profile_, list_controller_, autocomplete_controller_, match_)); +std::unique_ptr<ChromeSearchResult> OmniboxResult::Duplicate() const { + return std::make_unique<OmniboxResult>(profile_, list_controller_, + autocomplete_controller_, match_); } void OmniboxResult::UpdateIcon() { @@ -175,7 +175,7 @@ // the url description is presented as title, and url itself is presented as // details. const bool use_directly = !IsUrlResultWithDescription(); - SearchResult::Tags title_tags; + ChromeSearchResult::Tags title_tags; if (use_directly) { set_title(match_.contents); ACMatchClassificationsToTags(match_.contents, match_.contents_class, @@ -187,7 +187,7 @@ } set_title_tags(title_tags); - SearchResult::Tags details_tags; + ChromeSearchResult::Tags details_tags; if (use_directly) { set_details(match_.description); ACMatchClassificationsToTags(match_.description, match_.description_class,
diff --git a/chrome/browser/ui/app_list/search/omnibox_result.h b/chrome/browser/ui/app_list/search/omnibox_result.h index f1578fb1..7827e57e 100644 --- a/chrome/browser/ui/app_list/search/omnibox_result.h +++ b/chrome/browser/ui/app_list/search/omnibox_result.h
@@ -7,8 +7,8 @@ #include <memory> -#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "components/omnibox/browser/autocomplete_match.h" class AppListControllerDelegate; @@ -17,7 +17,7 @@ namespace app_list { -class OmniboxResult : public SearchResult { +class OmniboxResult : public ChromeSearchResult { public: OmniboxResult(Profile* profile, AppListControllerDelegate* list_controller, @@ -25,10 +25,10 @@ const AutocompleteMatch& match); ~OmniboxResult() override; - // SearchResult overrides: + // ChromeSearchResult overrides: void Open(int event_flags) override; - std::unique_ptr<SearchResult> Duplicate() const override; + std::unique_ptr<ChromeSearchResult> Duplicate() const override; private: void UpdateIcon();
diff --git a/chrome/browser/ui/app_list/search/search_controller.cc b/chrome/browser/ui/app_list/search/search_controller.cc index 96c9114..237346d4 100644 --- a/chrome/browser/ui/app_list/search/search_controller.cc +++ b/chrome/browser/ui/app_list/search/search_controller.cc
@@ -9,11 +9,11 @@ #include <utility> #include <vector> -#include "ash/app_list/model/search/search_result.h" #include "base/bind.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/history.h" #include "chrome/browser/ui/app_list/search/search_provider.h" #include "ui/app_list/app_list_constants.h" @@ -42,7 +42,7 @@ OnResultsChanged(); } -void SearchController::OpenResult(SearchResult* result, int event_flags) { +void SearchController::OpenResult(ChromeSearchResult* result, int event_flags) { // This can happen in certain circumstances due to races. See // https://crbug.com/534772 if (!result) @@ -54,7 +54,7 @@ history_->AddLaunchEvent(base::UTF16ToUTF8(last_raw_query_), result->id()); } -void SearchController::InvokeResultAction(SearchResult* result, +void SearchController::InvokeResultAction(ChromeSearchResult* result, int action_index, int event_flags) { // TODO(xiyuan): Hook up with user learning.
diff --git a/chrome/browser/ui/app_list/search/search_controller.h b/chrome/browser/ui/app_list/search/search_controller.h index edf9626..e6c8f6f 100644 --- a/chrome/browser/ui/app_list/search/search_controller.h +++ b/chrome/browser/ui/app_list/search/search_controller.h
@@ -15,12 +15,12 @@ #include "chrome/browser/ui/app_list/search/mixer.h" class AppListModelUpdater; +class ChromeSearchResult; namespace app_list { class History; class SearchProvider; -class SearchResult; // Controller that collects query from given SearchBoxModel, dispatches it // to all search providers, then invokes the mixer to mix and to publish the @@ -33,8 +33,8 @@ // TODO(hejq): can we accept a trimmed query here? void Start(const base::string16& raw_query); - void OpenResult(SearchResult* result, int event_flags); - void InvokeResultAction(SearchResult* result, + void OpenResult(ChromeSearchResult* result, int event_flags); + void InvokeResultAction(ChromeSearchResult* result, int action_index, int event_flags);
diff --git a/chrome/browser/ui/app_list/search/search_provider.cc b/chrome/browser/ui/app_list/search/search_provider.cc index 1180e82..3d7afea3 100644 --- a/chrome/browser/ui/app_list/search/search_provider.cc +++ b/chrome/browser/ui/app_list/search/search_provider.cc
@@ -6,14 +6,14 @@ #include <utility> -#include "ash/app_list/model/search/search_result.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" namespace app_list { SearchProvider::SearchProvider() {} SearchProvider::~SearchProvider() {} -void SearchProvider::Add(std::unique_ptr<SearchResult> result) { +void SearchProvider::Add(std::unique_ptr<ChromeSearchResult> result) { results_.emplace_back(std::move(result)); FireResultChanged(); }
diff --git a/chrome/browser/ui/app_list/search/search_provider.h b/chrome/browser/ui/app_list/search/search_provider.h index 0a6d520..72bf24ef 100644 --- a/chrome/browser/ui/app_list/search/search_provider.h +++ b/chrome/browser/ui/app_list/search/search_provider.h
@@ -12,13 +12,13 @@ #include "base/macros.h" #include "base/strings/string16.h" -namespace app_list { +class ChromeSearchResult; -class SearchResult; +namespace app_list { class SearchProvider { public: - using Results = std::vector<std::unique_ptr<SearchResult>>; + using Results = std::vector<std::unique_ptr<ChromeSearchResult>>; using ResultChangedCallback = base::Closure; SearchProvider(); @@ -35,7 +35,7 @@ protected: // Interface for the derived class to generate search results. - void Add(std::unique_ptr<SearchResult> result); + void Add(std::unique_ptr<ChromeSearchResult> result); // Swaps the internal results with |new_results|. // This is useful when multiple results will be added, and the notification is
diff --git a/chrome/browser/ui/app_list/search/search_webstore_result.cc b/chrome/browser/ui/app_list/search/search_webstore_result.cc index c3d03b8..fa5185a 100644 --- a/chrome/browser/ui/app_list/search/search_webstore_result.cc +++ b/chrome/browser/ui/app_list/search/search_webstore_result.cc
@@ -34,7 +34,7 @@ const base::string16 details = l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE); Tags details_tags; - details_tags.push_back(Tag(SearchResult::Tag::DIM, 0, details.length())); + details_tags.push_back(Tag(ash::SearchResultTag::DIM, 0, details.length())); set_details(details); set_details_tags(details_tags); @@ -58,9 +58,8 @@ ui::DispositionFromEventFlags(event_flags)); } -std::unique_ptr<SearchResult> SearchWebstoreResult::Duplicate() const { - return std::unique_ptr<SearchResult>( - new SearchWebstoreResult(profile_, controller_, query_)); +std::unique_ptr<ChromeSearchResult> SearchWebstoreResult::Duplicate() const { + return std::make_unique<SearchWebstoreResult>(profile_, controller_, query_); } } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/search_webstore_result.h b/chrome/browser/ui/app_list/search/search_webstore_result.h index a8a41579..78fabb8 100644 --- a/chrome/browser/ui/app_list/search/search_webstore_result.h +++ b/chrome/browser/ui/app_list/search/search_webstore_result.h
@@ -8,8 +8,8 @@ #include <memory> #include <string> -#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "url/gurl.h" class AppListControllerDelegate; @@ -18,16 +18,16 @@ namespace app_list { // A "search in webstore" result. -class SearchWebstoreResult : public SearchResult { +class SearchWebstoreResult : public ChromeSearchResult { public: SearchWebstoreResult(Profile* profile, AppListControllerDelegate* controller, const std::string& query); ~SearchWebstoreResult() override; - // SearchResult overrides: + // ChromeSearchResult overrides: void Open(int event_flags) override; - std::unique_ptr<SearchResult> Duplicate() const override; + std::unique_ptr<ChromeSearchResult> Duplicate() const override; private: Profile* profile_;
diff --git a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc index d6a17f6..2c605b0c 100644 --- a/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc +++ b/chrome/browser/ui/app_list/search/tests/app_search_provider_unittest.cc
@@ -11,7 +11,6 @@ #include <string> #include <utility> -#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" @@ -22,6 +21,7 @@ #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h" #include "chrome/browser/ui/app_list/arc/arc_app_test.h" #include "chrome/browser/ui/app_list/extension_app_model_builder.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h" #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" #include "chrome/common/chrome_constants.h" @@ -52,7 +52,8 @@ const base::Time kTestCurrentTime = base::Time::FromInternalValue(100000); -bool MoreRelevant(const SearchResult* result1, const SearchResult* result2) { +bool MoreRelevant(const ChromeSearchResult* result1, + const ChromeSearchResult* result2) { return result1->relevance() > result2->relevance(); } @@ -79,7 +80,7 @@ app_search_->Start(base::UTF8ToUTF16(query)); // Sort results by relevance. - std::vector<SearchResult*> sorted_results; + std::vector<ChromeSearchResult*> sorted_results; for (const auto& result : app_search_->results()) sorted_results.emplace_back(result.get()); std::sort(sorted_results.begin(), sorted_results.end(), &MoreRelevant);
diff --git a/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc b/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc index aa155b97..9b42359 100644 --- a/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc +++ b/chrome/browser/ui/app_list/search/tests/mixer_unittest.cc
@@ -32,7 +32,7 @@ const size_t kMaxOmniboxResults = 4; const size_t kMaxWebstoreResults = 2; -class TestSearchResult : public SearchResult { +class TestSearchResult : public ChromeSearchResult { public: TestSearchResult(const std::string& id, double relevance) : instance_id_(instantiation_count++) { @@ -42,17 +42,17 @@ } ~TestSearchResult() override {} - // SearchResult overrides: + // ChromeSearchResult overrides: void Open(int event_flags) override {} void InvokeAction(int action_index, int event_flags) override {} - std::unique_ptr<SearchResult> Duplicate() const override { + std::unique_ptr<ChromeSearchResult> Duplicate() const override { return std::make_unique<TestSearchResult>(id(), relevance()); } // For reference equality testing. (Addresses cannot be used to test reference // equality because it is possible that an object will be allocated at the // same address as a previously deleted one.) - static int GetInstanceId(SearchResult* result) { + static int GetInstanceId(ChromeSearchResult* result) { return static_cast<const TestSearchResult*>(result)->instance_id_; } @@ -87,12 +87,12 @@ relevance = 10.0 - i * 10; TestSearchResult* result = new TestSearchResult(id, relevance); result->set_display_type(display_type_); - Add(std::unique_ptr<SearchResult>(result)); + Add(std::unique_ptr<ChromeSearchResult>(result)); } } void set_prefix(const std::string& prefix) { prefix_ = prefix; } - void set_display_type(SearchResult::DisplayType display_type) { + void set_display_type(ChromeSearchResult::DisplayType display_type) { display_type_ = display_type; } void set_count(size_t count) { count_ = count; } @@ -102,7 +102,7 @@ std::string prefix_; size_t count_; bool bad_relevance_range_; - SearchResult::DisplayType display_type_; + ChromeSearchResult::DisplayType display_type_; DISALLOW_COPY_AND_ASSIGN(TestSearchProvider); };
diff --git a/chrome/browser/ui/app_list/search/webstore/webstore_provider.cc b/chrome/browser/ui/app_list/search/webstore/webstore_provider.cc index a5868211..8aa8a97 100644 --- a/chrome/browser/ui/app_list/search/webstore/webstore_provider.cc +++ b/chrome/browser/ui/app_list/search/webstore/webstore_provider.cc
@@ -139,7 +139,7 @@ if (!it->GetAsDictionary(&dict)) continue; - std::unique_ptr<SearchResult> result(CreateResult(query, *dict)); + std::unique_ptr<ChromeSearchResult> result(CreateResult(query, *dict)); if (!result) continue; @@ -153,7 +153,7 @@ } } -std::unique_ptr<SearchResult> WebstoreProvider::CreateResult( +std::unique_ptr<ChromeSearchResult> WebstoreProvider::CreateResult( const TokenizedString& query, const base::DictionaryValue& dict) { std::string app_id; @@ -164,16 +164,16 @@ !dict.GetString(kKeyLocalizedName, &localized_name) || !dict.GetString(kKeyIconUrl, &icon_url_string) || !dict.GetBoolean(kKeyIsPaid, &is_paid)) { - return std::unique_ptr<SearchResult>(); + return nullptr; } // If an app is already installed, don't show it in results. if (controller_->IsExtensionInstalled(profile_, app_id)) - return std::unique_ptr<SearchResult>(); + return nullptr; GURL icon_url(icon_url_string); if (!icon_url.is_valid()) - return std::unique_ptr<SearchResult>(); + return nullptr; std::string item_type_string; dict.GetString(kKeyItemType, &item_type_string); @@ -186,12 +186,12 @@ TokenizedString title(base::UTF8ToUTF16(localized_name)); TokenizedStringMatch match; if (!match.Calculate(query, title)) - return std::unique_ptr<SearchResult>(); + return nullptr; - std::unique_ptr<SearchResult> result = std::make_unique<WebstoreResult>( - profile_, app_id, icon_url, is_paid, item_type, controller_); + WebstoreResult* result = new WebstoreResult(profile_, app_id, icon_url, + is_paid, item_type, controller_); result->UpdateFromMatch(title, match); - return result; + return base::WrapUnique(result); } } // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/webstore/webstore_provider.h b/chrome/browser/ui/app_list/search/webstore/webstore_provider.h index 978afb946..87ed1bc 100644 --- a/chrome/browser/ui/app_list/search/webstore/webstore_provider.h +++ b/chrome/browser/ui/app_list/search/webstore/webstore_provider.h
@@ -6,12 +6,14 @@ #define CHROME_BROWSER_UI_APP_LIST_SEARCH_WEBSTORE_WEBSTORE_PROVIDER_H_ #include <memory> +#include <string> #include "base/callback_forward.h" #include "base/macros.h" #include "chrome/browser/ui/app_list/search/common/webservice_search_provider.h" class AppListControllerDelegate; +class ChromeSearchResult; namespace base { class DictionaryValue; @@ -24,7 +26,6 @@ } class JSONResponseFetcher; -class SearchResult; class TokenizedString; // WebstoreProvider fetches search results from the web store server. @@ -46,8 +47,9 @@ void OnWebstoreSearchFetched(std::unique_ptr<base::DictionaryValue> json); void ProcessWebstoreSearchResults(const base::DictionaryValue* json); - std::unique_ptr<SearchResult> CreateResult(const TokenizedString& query, - const base::DictionaryValue& dict); + std::unique_ptr<ChromeSearchResult> CreateResult( + const TokenizedString& query, + const base::DictionaryValue& dict); void set_webstore_search_fetched_callback(const base::Closure& callback) { webstore_search_fetched_callback_ = callback;
diff --git a/chrome/browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc b/chrome/browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc index 6d90261..0e73ccb 100644 --- a/chrome/browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc +++ b/chrome/browser/ui/app_list/search/webstore/webstore_provider_browsertest.cc
@@ -11,13 +11,13 @@ #include <string> #include <utility> -#include "ash/app_list/model/search/search_result.h" #include "base/bind.h" #include "base/command_line.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/browser/ui/app_list/search/webstore/webstore_result.h" #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h" #include "chrome/common/chrome_switches.h" @@ -217,7 +217,8 @@ size_t expected_result_size) { ASSERT_EQ(expected_result_size, webstore_provider_->results().size()); for (size_t i = 0; i < expected_result_size; ++i) { - const SearchResult* result = (webstore_provider_->results()[i]).get(); + const ChromeSearchResult* result = + (webstore_provider_->results()[i]).get(); // A search for an installed app will return a general webstore search // instead of an app in the webstore. if (!strcmp(expected_results[i].id, kWebstoreUrlPlaceholder)) { @@ -240,7 +241,7 @@ } EXPECT_EQ(std::string(expected_results[i].title), - app_list::SearchResult::TagsDebugString( + ChromeSearchResult::TagsDebugString( base::UTF16ToUTF8(result->title()), result->title_tags())); // Ensure the number of action buttons is appropriate for the item type.
diff --git a/chrome/browser/ui/app_list/search/webstore/webstore_result.cc b/chrome/browser/ui/app_list/search/webstore/webstore_result.cc index a9b983f..c78f333b 100644 --- a/chrome/browser/ui/app_list/search/webstore/webstore_result.cc +++ b/chrome/browser/ui/app_list/search/webstore/webstore_result.cc
@@ -102,8 +102,8 @@ StartInstall(); } -std::unique_ptr<SearchResult> WebstoreResult::Duplicate() const { - std::unique_ptr<SearchResult> copy(new WebstoreResult( +std::unique_ptr<ChromeSearchResult> WebstoreResult::Duplicate() const { + std::unique_ptr<ChromeSearchResult> copy(new WebstoreResult( profile_, app_id_, icon_url_, is_paid_, item_type_, controller_)); copy->set_title(title()); copy->set_title_tags(title_tags()); @@ -150,7 +150,7 @@ const base::string16 details = l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE); Tags details_tags; - details_tags.push_back(Tag(SearchResult::Tag::DIM, 0, details.length())); + details_tags.push_back(Tag(ash::SearchResultTag::DIM, 0, details.length())); set_details(details); set_details_tags(details_tags);
diff --git a/chrome/browser/ui/app_list/search/webstore/webstore_result.h b/chrome/browser/ui/app_list/search/webstore/webstore_result.h index f60c91c..4e833749 100644 --- a/chrome/browser/ui/app_list/search/webstore/webstore_result.h +++ b/chrome/browser/ui/app_list/search/webstore/webstore_result.h
@@ -8,10 +8,10 @@ #include <memory> #include <string> -#include "ash/app_list/model/search/search_result.h" #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/extensions/install_observer.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" #include "chrome/common/extensions/webstore_install_result.h" #include "extensions/browser/extension_registry_observer.h" #include "extensions/common/manifest.h" @@ -27,7 +27,7 @@ namespace app_list { -class WebstoreResult : public SearchResult, +class WebstoreResult : public ChromeSearchResult, public extensions::InstallObserver, public extensions::ExtensionRegistryObserver { public: @@ -47,10 +47,10 @@ extensions::Manifest::Type item_type() const { return item_type_; } bool is_paid() const { return is_paid_; } - // SearchResult overrides: + // ChromeSearchResult overrides: void Open(int event_flags) override; void InvokeAction(int action_index, int event_flags) override; - std::unique_ptr<SearchResult> Duplicate() const override; + std::unique_ptr<ChromeSearchResult> Duplicate() const override; private: // Set the initial state and start observing both InstallObserver and
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc index c5fb8df7..acd33a7 100644 --- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc +++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
@@ -123,7 +123,7 @@ return search_engine_is_google_; } -app_list::SearchResult* FakeAppListModelUpdater::FindSearchResult( +ChromeSearchResult* FakeAppListModelUpdater::FindSearchResult( const std::string& result_id) { for (auto& result : search_results_) { if (result->id() == result_id) @@ -132,13 +132,13 @@ return nullptr; } -app_list::SearchResult* FakeAppListModelUpdater::GetResultByTitle( +ChromeSearchResult* FakeAppListModelUpdater::GetResultByTitle( const std::string& title) { return nullptr; } void FakeAppListModelUpdater::PublishSearchResults( - std::vector<std::unique_ptr<app_list::SearchResult>> results) { + std::vector<std::unique_ptr<ChromeSearchResult>> results) { search_results_ = std::move(results); }
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h index dd9df728..41b54a8a 100644 --- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h +++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
@@ -10,8 +10,8 @@ #include <unordered_map> #include <vector> -#include "ash/app_list/model/search/search_result.h" #include "chrome/browser/ui/app_list/app_list_model_updater.h" +#include "chrome/browser/ui/app_list/search/chrome_search_result.h" class ChromeAppListItem; @@ -41,7 +41,7 @@ // For SearchModel: void SetSearchEngineIsGoogle(bool is_google) override; void PublishSearchResults( - std::vector<std::unique_ptr<app_list::SearchResult>> results) override; + std::vector<std::unique_ptr<ChromeSearchResult>> results) override; void ActivateChromeItem(const std::string& id, int event_flags) override; @@ -56,10 +56,9 @@ size_t BadgedItemCount() override; // For SearchModel: bool SearchEngineIsGoogle() override; - app_list::SearchResult* FindSearchResult( - const std::string& result_id) override; - app_list::SearchResult* GetResultByTitle(const std::string& title) override; - const std::vector<std::unique_ptr<app_list::SearchResult>>& search_results() + ChromeSearchResult* FindSearchResult(const std::string& result_id) override; + ChromeSearchResult* GetResultByTitle(const std::string& title) override; + const std::vector<std::unique_ptr<ChromeSearchResult>>& search_results() const { return search_results_; } @@ -73,7 +72,7 @@ private: bool search_engine_is_google_ = false; std::vector<std::unique_ptr<ChromeAppListItem>> items_; - std::vector<std::unique_ptr<app_list::SearchResult>> search_results_; + std::vector<std::unique_ptr<ChromeSearchResult>> search_results_; AppListModelUpdaterDelegate* delegate_ = nullptr; ash::mojom::AppListItemMetadataPtr FindOrCreateOemFolder(
diff --git a/chrome/browser/ui/browser_finder.cc b/chrome/browser/ui/browser_finder.cc index b7cc33f..ed48d48e 100644 --- a/chrome/browser/ui/browser_finder.cc +++ b/chrome/browser/ui/browser_finder.cc
@@ -184,9 +184,9 @@ return FindBrowserWithTabbedOrAnyType(profile, false, false); } -Browser* FindBrowserWithID(SessionID::id_type desired_id) { +Browser* FindBrowserWithID(SessionID desired_id) { for (auto* browser : *BrowserList::GetInstance()) { - if (browser->session_id().id() == desired_id) + if (browser->session_id() == desired_id) return browser; } return NULL;
diff --git a/chrome/browser/ui/browser_finder.h b/chrome/browser/ui/browser_finder.h index 19a335f..7b9ca16 100644 --- a/chrome/browser/ui/browser_finder.h +++ b/chrome/browser/ui/browser_finder.h
@@ -47,7 +47,7 @@ // Find an existing browser with the provided ID. Returns NULL if no such // browser currently exists. -Browser* FindBrowserWithID(SessionID::id_type desired_id); +Browser* FindBrowserWithID(SessionID desired_id); // Find the browser represented by |window| or NULL if not found. Browser* FindBrowserWithWindow(gfx::NativeWindow window);
diff --git a/chrome/browser/ui/browser_live_tab_context.cc b/chrome/browser/ui/browser_live_tab_context.cc index 6268760e..0bca9d7 100644 --- a/chrome/browser/ui/browser_live_tab_context.cc +++ b/chrome/browser/ui/browser_live_tab_context.cc
@@ -174,7 +174,7 @@ // static sessions::LiveTabContext* BrowserLiveTabContext::FindContextWithID( - SessionID::id_type desired_id) { + SessionID desired_id) { Browser* browser = chrome::FindBrowserWithID(desired_id); return browser ? browser->live_tab_context() : nullptr; }
diff --git a/chrome/browser/ui/browser_live_tab_context.h b/chrome/browser/ui/browser_live_tab_context.h index 6d5b5ec..f49729a 100644 --- a/chrome/browser/ui/browser_live_tab_context.h +++ b/chrome/browser/ui/browser_live_tab_context.h
@@ -77,8 +77,7 @@ // see chrome::FindBrowserWithID // Returns the LiveTabContext of the Browser with |desired_id| if // such a Browser exists. - static sessions::LiveTabContext* FindContextWithID( - SessionID::id_type desired_id); + static sessions::LiveTabContext* FindContextWithID(SessionID desired_id); private: Browser* const browser_;
diff --git a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm index e5ac419b..33216fe 100644 --- a/chrome/browser/ui/cocoa/applescript/tab_applescript.mm +++ b/chrome/browser/ui/cocoa/applescript/tab_applescript.mm
@@ -62,8 +62,7 @@ - (instancetype)init { if ((self = [super init])) { - SessionID session; - SessionID::id_type futureSessionIDOfTab = session.id() + 1; + SessionID::id_type futureSessionIDOfTab = SessionID::NewUnique().id() + 1; // Holds the SessionID that the new tab is going to get. base::scoped_nsobject<NSNumber> numID( [[NSNumber alloc] initWithInt:futureSessionIDOfTab]);
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h b/chrome/browser/ui/cocoa/infobars/infobar_background_view.h similarity index 64% rename from chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h rename to chrome/browser/ui/cocoa/infobars/infobar_background_view.h index be72e4a5..062bd49 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h +++ b/chrome/browser/ui/cocoa/infobars/infobar_background_view.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_UI_COCOA_INFOBARS_INFOBAR_GRADIENT_VIEW_H_ -#define CHROME_BROWSER_UI_COCOA_INFOBARS_INFOBAR_GRADIENT_VIEW_H_ +#ifndef CHROME_BROWSER_UI_COCOA_INFOBARS_INFOBAR_BACKGROUND_VIEW_H_ +#define CHROME_BROWSER_UI_COCOA_INFOBARS_INFOBAR_BACKGROUND_VIEW_H_ #import "chrome/browser/ui/cocoa/vertical_gradient_view.h" #include "third_party/skia/include/core/SkColor.h" @@ -11,11 +11,11 @@ #import <Cocoa/Cocoa.h> // A custom view that draws the background gradient for an infobar. -@interface InfoBarGradientView : VerticalGradientView +@interface InfoBarBackgroundView : VerticalGradientView // Sets the infobar background color. - (void)setInfobarBackgroundColor:(SkColor)color; @end -#endif // CHROME_BROWSER_UI_COCOA_INFOBARS_INFOBAR_GRADIENT_VIEW_H_ +#endif // CHROME_BROWSER_UI_COCOA_INFOBARS_INFOBAR_BACKGROUND_VIEW_H_
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_gradient_view.mm b/chrome/browser/ui/cocoa/infobars/infobar_background_view.mm similarity index 96% rename from chrome/browser/ui/cocoa/infobars/infobar_gradient_view.mm rename to chrome/browser/ui/cocoa/infobars/infobar_background_view.mm index 148ecdf..1d905be 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_gradient_view.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_background_view.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h" +#include "chrome/browser/ui/cocoa/infobars/infobar_background_view.h" #include "base/mac/scoped_nsobject.h" #import "chrome/browser/themes/theme_properties.h" @@ -14,7 +14,7 @@ #include "ui/base/material_design/material_design_controller.h" #include "ui/base/theme_provider.h" -@implementation InfoBarGradientView +@implementation InfoBarBackgroundView - (id)initWithFrame:(NSRect)frame { self = [super initWithFrame:frame];
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_background_view_unittest.mm b/chrome/browser/ui/cocoa/infobars/infobar_background_view_unittest.mm new file mode 100644 index 0000000..b04a1a72 --- /dev/null +++ b/chrome/browser/ui/cocoa/infobars/infobar_background_view_unittest.mm
@@ -0,0 +1,33 @@ +// 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. + +#import "chrome/browser/ui/cocoa/infobars/infobar_background_view.h" + +#include "base/mac/scoped_nsobject.h" +#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" + +namespace { + +class InfoBarBackgroundViewTest : public CocoaTest { + public: + InfoBarBackgroundViewTest() { + NSRect frame = NSMakeRect(0, 0, 100, 30); + base::scoped_nsobject<InfoBarBackgroundView> view( + [[InfoBarBackgroundView alloc] initWithFrame:frame]); + view_ = view.get(); + [[test_window() contentView] addSubview:view_]; + } + + InfoBarBackgroundView* view_; // Weak. Retained by view hierarchy. +}; + +TEST_VIEW(InfoBarBackgroundViewTest, view_); + +// Assert that the view is non-opaque, because otherwise we will end +// up with findbar painting issues. +TEST_F(InfoBarBackgroundViewTest, AssertViewNonOpaque) { + EXPECT_FALSE([view_ isOpaque]); +} + +} // namespace
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_controller.h b/chrome/browser/ui/cocoa/infobars/infobar_controller.h index 1668aad6..56b2bfe 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_controller.h +++ b/chrome/browser/ui/cocoa/infobars/infobar_controller.h
@@ -11,7 +11,7 @@ #include "base/memory/weak_ptr.h" class InfoBarCocoa; -@class InfoBarGradientView; +@class InfoBarBackgroundView; namespace infobars { class InfoBarDelegate; @@ -26,7 +26,7 @@ base::WeakPtr<InfoBarCocoa> infobar_; @protected - IBOutlet InfoBarGradientView* infoBarView_; + IBOutlet InfoBarBackgroundView* infoBarView_; IBOutlet NSImageView* image_; IBOutlet NSTextField* labelPlaceholder_; IBOutlet NSButton* okButton_;
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_controller.mm b/chrome/browser/ui/cocoa/infobars/infobar_controller.mm index 90f026eb..5e8b895 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_controller.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_controller.mm
@@ -11,10 +11,10 @@ #import "chrome/browser/ui/cocoa/animatable_view.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/image_button_cell.h" +#import "chrome/browser/ui/cocoa/infobars/infobar_background_view.h" #include "chrome/browser/ui/cocoa/infobars/infobar_cocoa.h" #import "chrome/browser/ui/cocoa/infobars/infobar_container_cocoa.h" #import "chrome/browser/ui/cocoa/infobars/infobar_container_controller.h" -#import "chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h" #include "chrome/browser/ui/cocoa/l10n_util.h" #import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" #include "chrome/grit/theme_resources.h"
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_gradient_view_unittest.mm b/chrome/browser/ui/cocoa/infobars/infobar_gradient_view_unittest.mm deleted file mode 100644 index 9017aa1e8..0000000 --- a/chrome/browser/ui/cocoa/infobars/infobar_gradient_view_unittest.mm +++ /dev/null
@@ -1,32 +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 "base/mac/scoped_nsobject.h" -#import "chrome/browser/ui/cocoa/infobars/infobar_gradient_view.h" -#import "chrome/browser/ui/cocoa/test/cocoa_test_helper.h" - -namespace { - -class InfoBarGradientViewTest : public CocoaTest { - public: - InfoBarGradientViewTest() { - NSRect frame = NSMakeRect(0, 0, 100, 30); - base::scoped_nsobject<InfoBarGradientView> view( - [[InfoBarGradientView alloc] initWithFrame:frame]); - view_ = view.get(); - [[test_window() contentView] addSubview:view_]; - } - - InfoBarGradientView* view_; // Weak. Retained by view hierarchy. -}; - -TEST_VIEW(InfoBarGradientViewTest, view_); - -// Assert that the view is non-opaque, because otherwise we will end -// up with findbar painting issues. -TEST_F(InfoBarGradientViewTest, AssertViewNonOpaque) { - EXPECT_FALSE([view_ isOpaque]); -} - -} // namespace
diff --git a/chrome/browser/ui/cocoa/infobars/infobar_utilities.mm b/chrome/browser/ui/cocoa/infobars/infobar_utilities.mm index 00279c2..1669eaad 100644 --- a/chrome/browser/ui/cocoa/infobars/infobar_utilities.mm +++ b/chrome/browser/ui/cocoa/infobars/infobar_utilities.mm
@@ -15,8 +15,8 @@ @implementation InfobarLabelTextField - (void)drawRect:(NSRect)rect { - NSView* infobarGradientView = [self superview]; - [self cr_drawUsingAncestor:infobarGradientView inRect:rect]; + NSView* infobarBackgroundView = [self superview]; + [self cr_drawUsingAncestor:infobarBackgroundView inRect:rect]; [super drawRect:rect]; }
diff --git a/chrome/browser/ui/cocoa/task_manager_mac_browsertest.mm b/chrome/browser/ui/cocoa/task_manager_mac_browsertest.mm index 393cb848..8b313cf 100644 --- a/chrome/browser/ui/cocoa/task_manager_mac_browsertest.mm +++ b/chrome/browser/ui/cocoa/task_manager_mac_browsertest.mm
@@ -89,7 +89,7 @@ } // Looks up a tab based on its tab ID. - content::WebContents* FindWebContentsByTabId(SessionID::id_type tab_id) { + content::WebContents* FindWebContentsByTabId(SessionID tab_id) { auto& all_tabs = AllTabContentses(); auto tab_id_matches = [tab_id](content::WebContents* web_contents) { return SessionTabHelper::IdForTab(web_contents) == tab_id;
diff --git a/chrome/browser/ui/extensions/extension_action_view_controller.cc b/chrome/browser/ui/extensions/extension_action_view_controller.cc index 3b4a6f1..71359114 100644 --- a/chrome/browser/ui/extensions/extension_action_view_controller.cc +++ b/chrome/browser/ui/extensions/extension_action_view_controller.cc
@@ -102,8 +102,8 @@ if (!ExtensionIsValid()) return base::string16(); - std::string title = - extension_action()->GetTitle(SessionTabHelper::IdForTab(web_contents)); + std::string title = extension_action()->GetTitle( + SessionTabHelper::IdForTab(web_contents).id()); return base::UTF8ToUTF16(title.empty() ? extension()->name() : title); } @@ -118,7 +118,7 @@ return false; return extension_action_->GetIsVisible( - SessionTabHelper::IdForTab(web_contents)) || + SessionTabHelper::IdForTab(web_contents).id()) || HasBeenBlocked(web_contents); } @@ -133,8 +133,8 @@ if (!ExtensionIsValid()) return false; - int tab_id = SessionTabHelper::IdForTab(web_contents); - return (tab_id < 0) ? false : extension_action_->HasPopup(tab_id); + SessionID tab_id = SessionTabHelper::IdForTab(web_contents); + return tab_id.is_valid() ? extension_action_->HasPopup(tab_id.id()) : false; } void ExtensionActionViewController::HidePopup() { @@ -214,7 +214,7 @@ if (action_runner->RunAction(extension(), grant_tab_permissions) == ExtensionAction::ACTION_SHOW_POPUP) { GURL popup_url = extension_action_->GetPopupUrl( - SessionTabHelper::IdForTab(web_contents)); + SessionTabHelper::IdForTab(web_contents).id()); return GetPreferredPopupViewController() ->TriggerPopupWithUrl(show_action, popup_url, grant_tab_permissions); } @@ -370,7 +370,7 @@ ExtensionActionViewController::GetIconImageSource( content::WebContents* web_contents, const gfx::Size& size) { - int tab_id = SessionTabHelper::IdForTab(web_contents); + int tab_id = SessionTabHelper::IdForTab(web_contents).id(); std::unique_ptr<IconWithBadgeImageSource> image_source( new IconWithBadgeImageSource(size)); @@ -410,7 +410,7 @@ return extension_action_->action_type() == extensions::ActionInfo::TYPE_PAGE && extension_action_->GetIsVisible( - SessionTabHelper::IdForTab(web_contents)); + SessionTabHelper::IdForTab(web_contents).id()); } bool ExtensionActionViewController::HasBeenBlocked(
diff --git a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc index 1f09733..8e38609 100644 --- a/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc +++ b/chrome/browser/ui/omnibox/omnibox_view_browsertest.cc
@@ -354,7 +354,7 @@ browser()->swap_toolbar_models(&toolbar_model); } - test_toolbar_model_->set_text(text); + test_toolbar_model_->set_formatted_full_url(text); omnibox_view->Update(); }
diff --git a/chrome/browser/ui/settings_window_manager_chromeos.cc b/chrome/browser/ui/settings_window_manager_chromeos.cc index f6b69e56..ce64fa8 100644 --- a/chrome/browser/ui/settings_window_manager_chromeos.cc +++ b/chrome/browser/ui/settings_window_manager_chromeos.cc
@@ -64,7 +64,7 @@ params.user_gesture = true; params.path_behavior = NavigateParams::IGNORE_AND_NAVIGATE; Navigate(¶ms); - settings_session_map_[profile] = params.browser->session_id().id(); + settings_session_map_[profile] = params.browser->session_id(); DCHECK(params.browser->is_trusted_source()); for (SettingsWindowManagerObserver& observer : observers_) @@ -82,7 +82,7 @@ ProfileSessionMap::const_iterator iter = settings_session_map_.find(browser->profile()); return (iter != settings_session_map_.end() && - iter->second == browser->session_id().id()); + iter->second == browser->session_id()); } SettingsWindowManager::SettingsWindowManager() {}
diff --git a/chrome/browser/ui/settings_window_manager_chromeos.h b/chrome/browser/ui/settings_window_manager_chromeos.h index 3f6882c..37eddfe 100644 --- a/chrome/browser/ui/settings_window_manager_chromeos.h +++ b/chrome/browser/ui/settings_window_manager_chromeos.h
@@ -45,7 +45,7 @@ private: friend struct base::DefaultSingletonTraits<SettingsWindowManager>; - typedef std::map<Profile*, SessionID::id_type> ProfileSessionMap; + typedef std::map<Profile*, SessionID> ProfileSessionMap; SettingsWindowManager(); ~SettingsWindowManager();
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc index 6b44ad7..db0825383 100644 --- a/chrome/browser/ui/startup/bad_flags_prompt.cc +++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -103,7 +103,16 @@ // This flag allows sites to access protected media identifiers without // getting the user's permission. - switches::kUnsafelyAllowProtectedMediaIdentifierForDomain}; + switches::kUnsafelyAllowProtectedMediaIdentifierForDomain, + + // This flag delays execution of base::TaskPriority::BACKGROUND tasks until + // shutdown. The queue of base::TaskPriority::BACKGROUND tasks can increase + // memory usage. Also, while it should be possible to use Chrome almost + // normally with this flag, it is expected that some non-visible operations + // such as writing user data to disk, cleaning caches, reporting metrics or + // updating components won't be performed until shutdown. + switches::kDisableBackgroundTasks, +}; #endif // OS_ANDROID // Dangerous feature flags in about:flags for which to display a warning that
diff --git a/chrome/browser/ui/sync/browser_synced_window_delegates_getter.cc b/chrome/browser/ui/sync/browser_synced_window_delegates_getter.cc index 0963c3b..132bca6 100644 --- a/chrome/browser/ui/sync/browser_synced_window_delegates_getter.cc +++ b/chrome/browser/ui/sync/browser_synced_window_delegates_getter.cc
@@ -31,7 +31,7 @@ const sync_sessions::SyncedWindowDelegate* BrowserSyncedWindowDelegatesGetter::FindById(SessionID id) { - Browser* browser = chrome::FindBrowserWithID(id.id()); + Browser* browser = chrome::FindBrowserWithID(id); return (browser != nullptr) ? browser->synced_window_delegate() : nullptr; }
diff --git a/chrome/browser/ui/tabs/window_activity_watcher.cc b/chrome/browser/ui/tabs/window_activity_watcher.cc index 2571fb0..ea3a39e 100644 --- a/chrome/browser/ui/tabs/window_activity_watcher.cc +++ b/chrome/browser/ui/tabs/window_activity_watcher.cc
@@ -34,7 +34,7 @@ bool operator!=(const WindowMetrics& other) { return !operator==(other); } // ID for the window, unique within the Chrome session. - SessionID::id_type window_id; + SessionID window_id; WindowMetricsEvent::Type type; // TODO(michaelpg): Observe the show state and log when it changes. WindowMetricsEvent::ShowState show_state; @@ -68,7 +68,7 @@ // Returns a populated WindowMetrics for the browser. WindowMetrics CreateMetrics(const Browser* browser, bool is_active) { WindowMetrics window_metrics; - window_metrics.window_id = browser->session_id().id(); + window_metrics.window_id = browser->session_id(); switch (browser->type()) { case Browser::TYPE_TABBED: @@ -90,7 +90,7 @@ return; ukm::builders::TabManager_WindowMetrics entry(ukm::AssignNewSourceId()); - entry.SetWindowId(window_metrics.window_id) + entry.SetWindowId(window_metrics.window_id.id()) .SetIsActive(window_metrics.is_active) .SetShowState(window_metrics.show_state) .SetType(window_metrics.type);
diff --git a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc index 56c95c8f..fb51e99a 100644 --- a/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc +++ b/chrome/browser/ui/toolbar/browser_actions_bar_browsertest.cc
@@ -281,7 +281,7 @@ ASSERT_TRUE(action); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - int tab_id = SessionTabHelper::IdForTab(web_contents); + int tab_id = SessionTabHelper::IdForTab(web_contents).id(); action->SetIsVisible(tab_id, true); extensions::ExtensionActionAPI* extension_action_api = extensions::ExtensionActionAPI::Get(profile());
diff --git a/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc b/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc index d4d740a..a8cad741 100644 --- a/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc +++ b/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.cc
@@ -33,50 +33,45 @@ return t1.timestamp > t2.timestamp; } -int CreateUniqueID() { - static int s_id = 0; - ++s_id; - return s_id; +std::string ToSessionTag(SessionID session_id) { + return std::string(kBaseSessionTag + base::IntToString(session_id.id())); } -std::string ToSessionTag(SessionID::id_type session_id) { - return std::string(kBaseSessionTag + base::IntToString(session_id)); +std::string ToSessionName(SessionID session_id) { + return std::string(kBaseSessionName + base::IntToString(session_id.id())); } -std::string ToSessionName(SessionID::id_type session_id) { - return std::string(kBaseSessionName + base::IntToString(session_id)); +std::string ToTabTitle(SessionID session_id, + SessionID window_id, + SessionID tab_id) { + return base::StringPrintf(kTabTitleFormat, session_id.id(), window_id.id(), + tab_id.id()); } -std::string ToTabTitle(SessionID::id_type session_id, - SessionID::id_type window_id, - SessionID::id_type tab_id) { - return base::StringPrintf(kTabTitleFormat, session_id, window_id, tab_id); -} - -std::string ToTabUrl(SessionID::id_type session_id, - SessionID::id_type window_id, - SessionID::id_type tab_id) { +std::string ToTabUrl(SessionID session_id, + SessionID window_id, + SessionID tab_id) { return std::string(kBaseTabUrl + ToTabTitle(session_id, window_id, tab_id)); } } // namespace struct RecentTabsBuilderTestHelper::TabInfo { - TabInfo() : id(0) {} - SessionID::id_type id; + TabInfo() : id(SessionID::InvalidValue()) {} + SessionID id; base::Time timestamp; base::string16 title; }; struct RecentTabsBuilderTestHelper::WindowInfo { - WindowInfo() : id(0) {} + WindowInfo() : id(SessionID::InvalidValue()) {} ~WindowInfo() {} - SessionID::id_type id; + SessionID id; std::vector<TabInfo> tabs; }; struct RecentTabsBuilderTestHelper::SessionInfo { - SessionInfo() : id(0) {} + SessionInfo() : id(SessionID::InvalidValue()) {} ~SessionInfo() {} - SessionID::id_type id; + SessionID id; std::vector<WindowInfo> windows; }; @@ -90,7 +85,7 @@ void RecentTabsBuilderTestHelper::AddSession() { SessionInfo info; - info.id = CreateUniqueID(); + info.id = SessionID::NewUnique(); sessions_.push_back(info); } @@ -98,8 +93,7 @@ return sessions_.size(); } -SessionID::id_type RecentTabsBuilderTestHelper::GetSessionID( - int session_index) { +SessionID RecentTabsBuilderTestHelper::GetSessionID(int session_index) { return sessions_[session_index].id; } @@ -119,7 +113,7 @@ void RecentTabsBuilderTestHelper::AddWindow(int session_index) { WindowInfo window_info; - window_info.id = CreateUniqueID(); + window_info.id = SessionID::NewUnique(); sessions_[session_index].windows.push_back(window_info); } @@ -127,8 +121,8 @@ return sessions_[session_index].windows.size(); } -SessionID::id_type RecentTabsBuilderTestHelper::GetWindowID(int session_index, - int window_index) { +SessionID RecentTabsBuilderTestHelper::GetWindowID(int session_index, + int window_index) { return sessions_[session_index].windows[window_index].id; } @@ -144,7 +138,7 @@ base::Time timestamp, const base::string16& title) { TabInfo tab_info; - tab_info.id = CreateUniqueID(); + tab_info.id = SessionID::NewUnique(); tab_info.timestamp = timestamp; tab_info.title = title; sessions_[session_index].windows[window_index].tabs.push_back(tab_info); @@ -155,9 +149,9 @@ return sessions_[session_index].windows[window_index].tabs.size(); } -SessionID::id_type RecentTabsBuilderTestHelper::GetTabID(int session_index, - int window_index, - int tab_index) { +SessionID RecentTabsBuilderTestHelper::GetTabID(int session_index, + int window_index, + int tab_index) { return sessions_[session_index].windows[window_index].tabs[tab_index].id; } @@ -250,7 +244,7 @@ void RecentTabsBuilderTestHelper::BuildSessionSpecifics( int session_index, sync_pb::SessionSpecifics* meta) { - SessionID::id_type session_id = GetSessionID(session_index); + SessionID session_id = GetSessionID(session_index); meta->set_session_tag(ToSessionTag(session_id)); sync_pb::SessionHeader* header = meta->mutable_header(); header->set_device_type(sync_pb::SyncEnums_DeviceType_TYPE_CROS); @@ -263,12 +257,12 @@ sync_pb::SessionSpecifics* meta) { sync_pb::SessionHeader* header = meta->mutable_header(); sync_pb::SessionWindow* window = header->add_window(); - SessionID::id_type window_id = GetWindowID(session_index, window_index); - window->set_window_id(window_id); + SessionID window_id = GetWindowID(session_index, window_index); + window->set_window_id(window_id.id()); window->set_selected_tab_index(0); window->set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED); for (int i = 0; i < GetTabCount(session_index, window_index); ++i) - window->add_tab(GetTabID(session_index, window_index, i)); + window->add_tab(GetTabID(session_index, window_index, i).id()); } void RecentTabsBuilderTestHelper::BuildTabSpecifics( @@ -276,15 +270,15 @@ int window_index, int tab_index, sync_pb::SessionSpecifics* tab_base) { - SessionID::id_type session_id = GetSessionID(session_index); - SessionID::id_type window_id = GetWindowID(session_index, window_index); - SessionID::id_type tab_id = GetTabID(session_index, window_index, tab_index); + SessionID session_id = GetSessionID(session_index); + SessionID window_id = GetWindowID(session_index, window_index); + SessionID tab_id = GetTabID(session_index, window_index, tab_index); tab_base->set_session_tag(ToSessionTag(session_id)); tab_base->set_tab_node_id(++max_tab_node_id_); sync_pb::SessionTab* tab = tab_base->mutable_tab(); - tab->set_window_id(window_id); - tab->set_tab_id(tab_id); + tab->set_window_id(window_id.id()); + tab->set_tab_id(tab_id.id()); tab->set_tab_visual_index(1); tab->set_current_navigation_index(0); tab->set_pinned(true);
diff --git a/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h b/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h index b7a020f8..d834326 100644 --- a/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h +++ b/chrome/browser/ui/toolbar/recent_tabs_builder_test_helper.h
@@ -29,12 +29,12 @@ void AddSession(); int GetSessionCount(); - SessionID::id_type GetSessionID(int session_index); + SessionID GetSessionID(int session_index); base::Time GetSessionTimestamp(int session_index); void AddWindow(int session_index); int GetWindowCount(int session_index); - SessionID::id_type GetWindowID(int session_index, int window_index); + SessionID GetWindowID(int session_index, int window_index); void AddTab(int session_index, int window_index); void AddTabWithInfo(int session_index, @@ -42,9 +42,7 @@ base::Time timestamp, const base::string16& title); int GetTabCount(int session_index, int window_index); - SessionID::id_type GetTabID(int session_index, - int window_index, - int tab_index); + SessionID GetTabID(int session_index, int window_index, int tab_index); base::Time GetTabTimestamp(int session_index, int window_index, int tab_index);
diff --git a/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc b/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc index d3ff9d6..0da68927 100644 --- a/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc +++ b/chrome/browser/ui/toolbar/toolbar_actions_bar_unittest.cc
@@ -205,7 +205,8 @@ ExtensionAction* action, content::WebContents* web_contents, bool wants_to_run) { - action->SetIsVisible(SessionTabHelper::IdForTab(web_contents), wants_to_run); + action->SetIsVisible(SessionTabHelper::IdForTab(web_contents).id(), + wants_to_run); extensions::ExtensionActionAPI::Get(profile())->NotifyChange( action, web_contents, profile()); }
diff --git a/chrome/browser/ui/views/harmony/chrome_layout_provider.cc b/chrome/browser/ui/views/harmony/chrome_layout_provider.cc index acbf8b2..3dba5720 100644 --- a/chrome/browser/ui/views/harmony/chrome_layout_provider.cc +++ b/chrome/browser/ui/views/harmony/chrome_layout_provider.cc
@@ -9,6 +9,7 @@ #include "base/logging.h" #include "chrome/browser/ui/views/harmony/chrome_typography.h" #include "chrome/browser/ui/views/harmony/harmony_layout_provider.h" +#include "chrome/browser/ui/views/harmony/material_refresh_layout_provider.h" #include "ui/base/material_design/material_design_controller.h" namespace { @@ -37,6 +38,9 @@ // static std::unique_ptr<views::LayoutProvider> ChromeLayoutProvider::CreateLayoutProvider() { + if (ui::MaterialDesignController::GetMode() == + ui::MaterialDesignController::MATERIAL_REFRESH) + return std::make_unique<MaterialRefreshLayoutProvider>(); return ui::MaterialDesignController::IsSecondaryUiMaterial() ? std::make_unique<HarmonyLayoutProvider>() : std::make_unique<ChromeLayoutProvider>();
diff --git a/chrome/browser/ui/views/harmony/material_refresh_layout_provider.cc b/chrome/browser/ui/views/harmony/material_refresh_layout_provider.cc new file mode 100644 index 0000000..77d5d78 --- /dev/null +++ b/chrome/browser/ui/views/harmony/material_refresh_layout_provider.cc
@@ -0,0 +1,21 @@ +// Copyright 2018 The Chromium Authors. 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/views/harmony/material_refresh_layout_provider.h" + +int MaterialRefreshLayoutProvider::GetCornerRadiusMetric( + ChromeEmphasisMetric emphasis_metric, + const gfx::Rect& bounds) const { + switch (emphasis_metric) { + case EMPHASIS_LOW: + return 4; + case EMPHASIS_MEDIUM: + return 8; + case EMPHASIS_HIGH: + return std::min(bounds.width(), bounds.height()) / 2; + default: + NOTREACHED(); + return 0; + } +}
diff --git a/chrome/browser/ui/views/harmony/material_refresh_layout_provider.h b/chrome/browser/ui/views/harmony/material_refresh_layout_provider.h new file mode 100644 index 0000000..47ef6cf --- /dev/null +++ b/chrome/browser/ui/views/harmony/material_refresh_layout_provider.h
@@ -0,0 +1,21 @@ +// Copyright 2018 The Chromium Authors. 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_VIEWS_HARMONY_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_ +#define CHROME_BROWSER_UI_VIEWS_HARMONY_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_ + +#include "base/macros.h" +#include "chrome/browser/ui/views/harmony/harmony_layout_provider.h" + +class MaterialRefreshLayoutProvider : public HarmonyLayoutProvider { + public: + MaterialRefreshLayoutProvider() = default; + ~MaterialRefreshLayoutProvider() override = default; + + int GetCornerRadiusMetric( + ChromeEmphasisMetric emphasis_metric, + const gfx::Rect& bounds = gfx::Rect()) const override; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_HARMONY_MATERIAL_REFRESH_LAYOUT_PROVIDER_H_
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc index 6f27b6a..d89c4404b 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -518,7 +518,7 @@ // destroyed by the time we get this call. Also note parent_window() (if set) // may also be destroyed: the call to WindowClosing() may be triggered by // parent window destruction tearing down its child windows. - Browser* browser = chrome::FindBrowserWithID(session_id_.id()); + Browser* browser = chrome::FindBrowserWithID(session_id_); if (browser && browser->window() && browser->window()->GetLocationBar()) browser->window()->GetLocationBar()->UpdateZoomViewVisibility(); }
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views.h b/chrome/browser/ui/views/omnibox/omnibox_view_views.h index ab4c220..45867e9 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views.h +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views.h
@@ -121,6 +121,8 @@ FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, MaintainCursorAfterFocusCycle); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, OnBlur); FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsTest, DoNotNavigateOnDrop); + FRIEND_TEST_ALL_PREFIXES(OmniboxViewViewsSteadyStateElisionsTest, + UnelideOnArrowKey); // Update the field with |text| and set the selection. void SetTextAndSelectedRange(const base::string16& text,
diff --git a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc index ca5771d..1e3ee02c 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_view_views_unittest.cc
@@ -9,6 +9,7 @@ #include <memory> #include "base/macros.h" +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/autocomplete/autocomplete_classifier_factory.h" #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" @@ -20,6 +21,7 @@ #include "chrome/test/base/testing_profile.h" #include "chrome/test/views/chrome_views_test_base.h" #include "components/omnibox/browser/omnibox_edit_model.h" +#include "components/omnibox/browser/omnibox_field_trial.h" #include "components/toolbar/test_toolbar_model.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" @@ -197,11 +199,12 @@ return test_api_->GetRenderText()->cursor_enabled(); } - private: + protected: // testing::Test: void SetUp() override; void TearDown() override; + private: content::TestBrowserThreadBundle thread_bundle_; TestingProfile profile_; TemplateURLServiceFactoryTestUtil util_; @@ -390,7 +393,7 @@ } TEST_F(OmniboxViewViewsTest, RevertOnBlur) { - toolbar_model()->set_text(base::ASCIIToUTF16("permanent text")); + toolbar_model()->set_formatted_full_url(base::ASCIIToUTF16("permanent text")); omnibox_view()->model()->ResetDisplayUrls(); omnibox_view()->RevertAll(); @@ -415,3 +418,79 @@ EXPECT_EQ(base::ASCIIToUTF16("permanent text"), omnibox_view()->text()); EXPECT_FALSE(omnibox_view()->model()->user_input_in_progress()); } + +class OmniboxViewViewsSteadyStateElisionsTest : public OmniboxViewViewsTest { + protected: + void SetUp() override { + scoped_feature_list_.InitAndEnableFeature( + omnibox::kUIExperimentHideSteadyStateUrlSchemeAndSubdomains); + + OmniboxViewViewsTest::SetUp(); + + toolbar_model()->set_formatted_full_url( + base::ASCIIToUTF16("https://example.com")); + toolbar_model()->set_url_for_display(base::ASCIIToUTF16("example.com")); + omnibox_view()->model()->ResetDisplayUrls(); + omnibox_view()->RevertAll(); + + ExpectElidedUrlDisplayed(); + } + + void ExpectFullUrlDisplayed() { + EXPECT_EQ(base::ASCIIToUTF16("https://example.com"), + omnibox_view()->text()); + EXPECT_TRUE(omnibox_view()->model()->user_input_in_progress()); + } + + void ExpectElidedUrlDisplayed() { + EXPECT_EQ(base::ASCIIToUTF16("example.com"), omnibox_view()->text()); + EXPECT_FALSE(omnibox_view()->model()->user_input_in_progress()); + } + + // Used to access members that are marked private in views::TextField. + views::View* omnibox_textfield_view() { return omnibox_view(); } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(OmniboxViewViewsSteadyStateElisionsTest, StayElidedOnFocus) { + // We should not unelide on focus. + omnibox_textfield()->OnFocus(); + + EXPECT_EQ(OMNIBOX_FOCUS_VISIBLE, omnibox_view()->model()->focus_state()); + ExpectElidedUrlDisplayed(); +} + +TEST_F(OmniboxViewViewsSteadyStateElisionsTest, UnelideOnArrowKey) { + omnibox_textfield()->OnFocus(); + EXPECT_EQ(OMNIBOX_FOCUS_VISIBLE, omnibox_view()->model()->focus_state()); + + omnibox_view()->SelectAll(true); + EXPECT_TRUE(omnibox_view()->IsSelectAll()); + ExpectElidedUrlDisplayed(); + + // Right key should unelide and move the cursor to the end. + omnibox_textfield_view()->OnKeyPressed( + ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_RIGHT, 0)); + ExpectFullUrlDisplayed(); + size_t start, end; + omnibox_view()->GetSelectionBounds(&start, &end); + EXPECT_EQ(19U, start); + EXPECT_EQ(19U, end); + + // Blur and restore the elided URL. + omnibox_textfield()->OnBlur(); + omnibox_textfield()->OnFocus(); + omnibox_view()->SelectAll(true); + ExpectElidedUrlDisplayed(); + + // Left key should unelide and move the cursor to the beginning of the elided + // part. + omnibox_textfield_view()->OnKeyPressed( + ui::KeyEvent(ui::ET_KEY_PRESSED, ui::VKEY_LEFT, 0)); + ExpectFullUrlDisplayed(); + omnibox_view()->GetSelectionBounds(&start, &end); + EXPECT_EQ(8U, start); + EXPECT_EQ(8U, end); +}
diff --git a/chrome/browser/ui/views/payments/payment_request_data_url_browsertest.cc b/chrome/browser/ui/views/payments/payment_request_data_url_browsertest.cc index 9851dbd0..8fee346 100644 --- a/chrome/browser/ui/views/payments/payment_request_data_url_browsertest.cc +++ b/chrome/browser/ui/views/payments/payment_request_data_url_browsertest.cc
@@ -24,12 +24,19 @@ "'1.00'}}})).show(); } catch(e) { " "document.getElementById('result').innerHTML = e; }\">Data URL " "Test</button><div id='result'></div></body></html>"); + + // PaymentRequest should not be defined in non-secure context. + bool result = true; + ASSERT_TRUE(content::ExecuteScriptAndExtractBool( + GetActiveWebContents(), + "window.domAutomationController.send('PaymentRequest' in window);", + &result)); + ASSERT_FALSE(result); + ASSERT_TRUE(content::ExecuteScript( GetActiveWebContents(), "(function() { document.getElementById('buy').click(); })();")); - ExpectBodyContains( - {"SecurityError: Failed to construct 'PaymentRequest': Must be in a " - "secure context"}); + ExpectBodyContains({"PaymentRequest is not defined"}); } } // namespace payments
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index c2a42693..68dd931 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -1151,7 +1151,7 @@ // If all 3 icons are visible, we add an extra left padding for favicon. // See comment for |extra_padding_before_content_|. - if (!showing_close_button_ || !showing_alert_indicator_) + if (!showing_alert_indicator_) extra_padding = 0; showing_icon_ = @@ -1169,9 +1169,17 @@ if (!showing_icon_ || !showing_alert_indicator_) extra_padding = 0; - showing_close_button_ = - !force_hide_close_button && - close_button_width + extra_padding <= available_width; + // For an inactive tab, the close button will be visible only when + // it is not forced to hide and the total width can accomodate all 3 + // icons. When favicon or alert button is not visible, its space + // will be occupied by the title of this tab. + int title_width = + (!showing_icon_ + !showing_alert_indicator_) * favicon_width; + if (!force_hide_close_button && + (title_width + close_button_width + extra_padding <= + available_width)) { + showing_close_button_ = true; + } // If no other controls are visible, show favicon even though we // don't have enough space. We'll clip the favicon in PaintChildren().
diff --git a/chrome/browser/ui/views/tabs/tab.h b/chrome/browser/ui/views/tabs/tab.h index 3dee833..0955298 100644 --- a/chrome/browser/ui/views/tabs/tab.h +++ b/chrome/browser/ui/views/tabs/tab.h
@@ -170,6 +170,8 @@ friend class TabTest; friend class TabStripTest; FRIEND_TEST_ALL_PREFIXES(TabStripTest, TabCloseButtonVisibilityWhenStacked); + FRIEND_TEST_ALL_PREFIXES(TabStripTest, + TabCloseButtonVisibilityWhenNotStacked); // gfx::AnimationDelegate: void AnimationProgressed(const gfx::Animation* animation) override;
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h index 5447d0a..75e8ead 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.h +++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -284,6 +284,8 @@ FRIEND_TEST_ALL_PREFIXES(TabDragControllerTest, GestureEndShouldEndDragTest); FRIEND_TEST_ALL_PREFIXES(TabStripTest, TabForEventWhenStacked); FRIEND_TEST_ALL_PREFIXES(TabStripTest, TabCloseButtonVisibilityWhenStacked); + FRIEND_TEST_ALL_PREFIXES(TabStripTest, + TabCloseButtonVisibilityWhenNotStacked); FRIEND_TEST_ALL_PREFIXES(TabStripTest, ActiveTabWidthWhenTabsAreTiny); // Used during a drop session of a url. Tracks the position of the drop as
diff --git a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc index 8a546ff..260b684 100644 --- a/chrome/browser/ui/views/tabs/tab_strip_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_strip_unittest.cc
@@ -399,6 +399,91 @@ EXPECT_TRUE(tab3->showing_close_button_); } +// Tests that the tab close buttons of non-active tabs are hidden when +// the tabstrip is not in stacked tab mode and the tab sizes are shrunk +// into small sizes. +TEST_P(TabStripTest, TabCloseButtonVisibilityWhenNotStacked) { + if (GetParam()) { + // TODO(malaykeshav): Fix test failure in touch-optimized UI mode. + // https://crbug.com/814847. + return; + } + + // Set the tab strip width to be wide enough for three tabs to show all + // three icons, but not enough for five tabs to show all three icons. + tab_strip_->SetBounds(0, 0, 240, 20); + controller_->AddTab(0, false); + controller_->AddTab(1, true); + controller_->AddTab(2, false); + ASSERT_EQ(3, tab_strip_->tab_count()); + + Tab* tab0 = tab_strip_->tab_at(0); + ASSERT_FALSE(tab0->IsActive()); + Tab* tab1 = tab_strip_->tab_at(1); + ASSERT_TRUE(tab1->IsActive()); + Tab* tab2 = tab_strip_->tab_at(2); + ASSERT_FALSE(tab2->IsActive()); + + // Ensure this is not in stacked layout mode. + ASSERT_FALSE(tab_strip_->touch_layout_.get()); + + // Ensure that all tab close buttons are initially visible. + EXPECT_TRUE(tab0->showing_close_button_); + EXPECT_TRUE(tab1->showing_close_button_); + EXPECT_TRUE(tab2->showing_close_button_); + + // Shrink the tab sizes by adding more tabs. + // An inactive tab added to the tabstrip, now each tab size is not + // big enough to accomodate 3 icons, so it should not show its + // tab close button. + controller_->AddTab(3, false); + Tab* tab3 = tab_strip_->tab_at(3); + EXPECT_FALSE(tab3->showing_close_button_); + + // This inactive tab doesn't have alert button, but its favicon and + // title would be shown. + EXPECT_TRUE(tab3->showing_icon_); + EXPECT_FALSE(tab3->showing_alert_indicator_); + EXPECT_TRUE(tab3->title_->visible()); + + // The active tab's close button still shows. + EXPECT_TRUE(tab1->showing_close_button_); + + // An active tab added to the tabstrip should show its tab close + // button. + controller_->AddTab(4, true); + Tab* tab4 = tab_strip_->tab_at(4); + ASSERT_TRUE(tab4->IsActive()); + EXPECT_TRUE(tab4->showing_close_button_); + + // The previous active button is now inactive so its close + // button should not show. + EXPECT_FALSE(tab1->showing_close_button_); + + // After switching tabs, the previously-active tab should have its + // tab close button hidden and the newly-active tab should show + // its tab close button. + tab_strip_->SelectTab(tab2); + ASSERT_FALSE(tab4->IsActive()); + ASSERT_TRUE(tab2->IsActive()); + EXPECT_FALSE(tab0->showing_close_button_); + EXPECT_FALSE(tab1->showing_close_button_); + EXPECT_TRUE(tab2->showing_close_button_); + EXPECT_FALSE(tab3->showing_close_button_); + EXPECT_FALSE(tab4->showing_close_button_); + + // After closing the active tab, the tab which becomes active should + // show its tab close button. + tab_strip_->CloseTab(tab2, CLOSE_TAB_FROM_TOUCH); + tab2 = nullptr; + ASSERT_TRUE(tab3->IsActive()); + tab_strip_->DoLayout(); + EXPECT_FALSE(tab0->showing_close_button_); + EXPECT_FALSE(tab1->showing_close_button_); + EXPECT_TRUE(tab3->showing_close_button_); + EXPECT_FALSE(tab4->showing_close_button_); +} + TEST_P(TabStripTest, GetEventHandlerForOverlappingArea) { tab_strip_->SetBounds(0, 0, 1000, 20);
diff --git a/chrome/browser/ui/views/task_manager_view_browsertest.cc b/chrome/browser/ui/views/task_manager_view_browsertest.cc index 393ce73..b463e10 100644 --- a/chrome/browser/ui/views/task_manager_view_browsertest.cc +++ b/chrome/browser/ui/views/task_manager_view_browsertest.cc
@@ -87,7 +87,7 @@ } // Looks up a tab based on its tab ID. - content::WebContents* FindWebContentsByTabId(SessionID::id_type tab_id) { + content::WebContents* FindWebContentsByTabId(SessionID tab_id) { auto& all_tabs = AllTabContentses(); auto tab_id_matches = [tab_id](content::WebContents* web_contents) { return SessionTabHelper::IdForTab(web_contents) == tab_id; @@ -100,7 +100,7 @@ // Returns the current TaskManagerTableModel index for a particular tab. Don't // cache this value, since it can change whenever the message loop runs. int FindRowForTab(content::WebContents* tab) { - int32_t tab_id = SessionTabHelper::IdForTab(tab); + SessionID tab_id = SessionTabHelper::IdForTab(tab); std::unique_ptr<TaskManagerTester> tester = TaskManagerTester::Create(base::Closure()); for (int i = 0; i < tester->GetRowCount(); ++i) {
diff --git a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc index b8d2e856..df5a69d 100644 --- a/chrome/browser/ui/views/toolbar/toolbar_action_view.cc +++ b/chrome/browser/ui/views/toolbar/toolbar_action_view.cc
@@ -153,7 +153,7 @@ void ToolbarActionView::UpdateState() { content::WebContents* web_contents = GetCurrentWebContents(); SetAccessibleName(view_controller_->GetAccessibleName(web_contents)); - if (SessionTabHelper::IdForTab(web_contents) < 0) + if (!SessionTabHelper::IdForTab(web_contents).is_valid()) return; if (!view_controller_->IsEnabled(web_contents) &&
diff --git a/chrome/browser/ui/webui/foreign_session_handler.cc b/chrome/browser/ui/webui/foreign_session_handler.cc index f42df1d..aa938b1 100644 --- a/chrome/browser/ui/webui/foreign_session_handler.cc +++ b/chrome/browser/ui/webui/foreign_session_handler.cc
@@ -103,7 +103,7 @@ // Helper for initializing a boilerplate SessionWindow JSON compatible object. std::unique_ptr<base::DictionaryValue> BuildWindowData( base::Time modification_time, - SessionID::id_type window_id) { + SessionID window_id) { std::unique_ptr<base::DictionaryValue> dictionary( new base::DictionaryValue()); // The items which are to be written into |dictionary| are also described in @@ -121,7 +121,7 @@ : ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_ELAPSED, ui::TimeFormat::LENGTH_SHORT, last_synced)); - dictionary->SetInteger("sessionId", window_id); + dictionary->SetInteger("sessionId", window_id.id()); return dictionary; } @@ -145,7 +145,7 @@ if (tab_values->GetSize() == 0) return nullptr; std::unique_ptr<base::DictionaryValue> dictionary( - BuildWindowData(window.timestamp, window.window_id.id())); + BuildWindowData(window.timestamp, window.window_id)); dictionary->Set("tabs", std::move(tab_values)); return dictionary; } @@ -168,18 +168,17 @@ void ForeignSessionHandler::OpenForeignSessionTab( content::WebUI* web_ui, const std::string& session_string_value, - SessionID::id_type window_num, - SessionID::id_type tab_id, + int window_num, + SessionID tab_id, const WindowOpenDisposition& disposition) { sync_sessions::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(web_ui); if (!open_tabs) return; // We don't actually care about |window_num|, this is just a sanity check. - DCHECK_LT(kInvalidId, window_num); + DCHECK_LE(0, window_num); const ::sessions::SessionTab* tab; - if (!open_tabs->GetForeignTab(session_string_value, - SessionID::FromSerializedValue(tab_id), &tab)) { + if (!open_tabs->GetForeignTab(session_string_value, tab_id, &tab)) { LOG(ERROR) << "Failed to load foreign tab."; return; } @@ -195,7 +194,7 @@ void ForeignSessionHandler::OpenForeignSessionWindows( content::WebUI* web_ui, const std::string& session_string_value, - SessionID::id_type window_num) { + int window_num) { sync_sessions::OpenTabsUIDelegate* open_tabs = GetOpenTabsUIDelegate(web_ui); if (!open_tabs) return; @@ -208,11 +207,12 @@ return; } std::vector<const ::sessions::SessionWindow*>::const_iterator iter_begin = - windows.begin() + (window_num == kInvalidId ? 0 : window_num); + windows.begin() + (window_num < 0 ? 0 : window_num); std::vector<const ::sessions::SessionWindow*>::const_iterator iter_end = - window_num == kInvalidId ? - std::vector<const ::sessions::SessionWindow*>::const_iterator( - windows.end()) : iter_begin + 1; + window_num < 0 + ? std::vector<const ::sessions::SessionWindow*>::const_iterator( + windows.end()) + : iter_begin + 1; SessionRestore::RestoreForeignSessionWindows(Profile::FromWebUI(web_ui), iter_begin, iter_end); } @@ -327,37 +327,13 @@ current_collapsed_sessions->SetBoolean(session_tag, true); std::unique_ptr<base::ListValue> window_list(new base::ListValue()); - const std::string group_name = - base::FieldTrialList::FindFullName("TabSyncByRecency"); - if (group_name != "Enabled") { - // Order tabs by visual order within window. - for (const auto& window_pair : session->windows) { - std::unique_ptr<base::DictionaryValue> window_data( - SessionWindowToValue(window_pair.second->wrapped_window)); - if (window_data.get()) - window_list->Append(std::move(window_data)); - } - } else { - // Order tabs by recency. This involves creating a synthetic singleton - // window that contains all the tabs of the session. - base::Time modification_time; - std::vector<const ::sessions::SessionTab*> tabs; - open_tabs->GetForeignSessionTabs(session_tag, &tabs); - std::unique_ptr<base::ListValue> tab_values(new base::ListValue()); - for (const ::sessions::SessionTab* tab : tabs) { - std::unique_ptr<base::DictionaryValue> tab_value( - SessionTabToValue(*tab)); - if (tab_value.get()) { - modification_time = std::max(modification_time, tab->timestamp); - tab_values->Append(std::move(tab_value)); - } - } - if (tab_values->GetSize() != 0) { - std::unique_ptr<base::DictionaryValue> window_data( - BuildWindowData(modification_time, 1)); - window_data->Set("tabs", std::move(tab_values)); + + // Order tabs by visual order within window. + for (const auto& window_pair : session->windows) { + std::unique_ptr<base::DictionaryValue> window_data( + SessionWindowToValue(window_pair.second->wrapped_window)); + if (window_data) window_list->Append(std::move(window_data)); - } } session_data->Set("windows", std::move(window_list)); @@ -390,7 +366,7 @@ // Extract window number. std::string window_num_str; - int window_num = kInvalidId; + int window_num = -1; if (num_args >= 2 && (!args->GetString(1, &window_num_str) || !base::StringToInt(window_num_str, &window_num))) { LOG(ERROR) << "Failed to extract window number."; @@ -399,14 +375,15 @@ // Extract tab id. std::string tab_id_str; - SessionID::id_type tab_id = kInvalidId; + SessionID::id_type tab_id_value = 0; if (num_args >= 3 && (!args->GetString(2, &tab_id_str) || - !base::StringToInt(tab_id_str, &tab_id))) { + !base::StringToInt(tab_id_str, &tab_id_value))) { LOG(ERROR) << "Failed to extract tab SessionID."; return; } - if (tab_id != kInvalidId) { + SessionID tab_id = SessionID::FromSerializedValue(tab_id_value); + if (tab_id.is_valid()) { WindowOpenDisposition disposition = webui::GetDispositionFromClick(args, 3); OpenForeignSessionTab( web_ui(), session_string_value, window_num, tab_id, disposition);
diff --git a/chrome/browser/ui/webui/foreign_session_handler.h b/chrome/browser/ui/webui/foreign_session_handler.h index d0cb245..81712db1 100644 --- a/chrome/browser/ui/webui/foreign_session_handler.h +++ b/chrome/browser/ui/webui/foreign_session_handler.h
@@ -30,9 +30,6 @@ class ForeignSessionHandler : public content::WebUIMessageHandler, public syncer::SyncServiceObserver { public: - // Invalid value, used to note that we don't have a tab or window number. - static const int kInvalidId = -1; - // WebUIMessageHandler implementation. void RegisterMessages() override; @@ -43,13 +40,13 @@ static void OpenForeignSessionTab(content::WebUI* web_ui, const std::string& session_string_value, - SessionID::id_type window_num, - SessionID::id_type tab_id, + int window_num, + SessionID tab_id, const WindowOpenDisposition& disposition); static void OpenForeignSessionWindows(content::WebUI* web_ui, const std::string& session_string_value, - SessionID::id_type window_num); + int window_num); // Returns a pointer to the current session model associator or NULL. static sync_sessions::OpenTabsUIDelegate* GetOpenTabsUIDelegate(
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 6be6429..270006388 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui.cc +++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -467,9 +467,9 @@ } initiator_ = initiator; - SessionID::id_type tab_id = SessionTabHelper::IdForTab(initiator); - if (tab_id != -1) { - MediaSource mirroring_source(MediaSourceForTab(tab_id)); + SessionID tab_id = SessionTabHelper::IdForTab(initiator); + if (tab_id.is_valid()) { + MediaSource mirroring_source(MediaSourceForTab(tab_id.id())); query_result_manager_->SetSourcesForCastMode(MediaCastMode::TAB_MIRROR, {mirroring_source}, origin); } @@ -618,8 +618,8 @@ GURL url = media_router_file_dialog_->GetLastSelectedFileUrl(); tab_contents = OpenTabWithUrl(url); - SessionID::id_type tab_id = SessionTabHelper::IdForTab(tab_contents); - source_id = MediaSourceForTab(tab_id).id(); + SessionID tab_id = SessionTabHelper::IdForTab(tab_contents); + source_id = MediaSourceForTab(tab_id.id()).id(); SetLocalFileRouteParameters(sink_id, &origin, url, tab_contents, &route_response_callbacks, &timeout,
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc b/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc index 6a6e17ef..b6a7d62 100644 --- a/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc +++ b/chrome/browser/ui/webui/media_router/media_router_ui_unittest.cc
@@ -462,8 +462,8 @@ TEST_F(MediaRouterUITest, UIMediaRoutesObserverAssignsCurrentCastModes) { CreateMediaRouterUI(profile()); - SessionID::id_type tab_id = SessionTabHelper::IdForTab(web_contents()); - MediaSource media_source_1(MediaSourceForTab(tab_id)); + SessionID tab_id = SessionTabHelper::IdForTab(web_contents()); + MediaSource media_source_1(MediaSourceForTab(tab_id.id())); MediaSource media_source_2("mediaSource"); MediaSource media_source_3(MediaSourceForDesktop()); std::unique_ptr<MediaRouterUI::UIMediaRoutesObserver> observer(
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index cf0c0afa0..c5e55c53 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -105,7 +105,6 @@ "elements/transient_element.h", "elements/ui_element.cc", "elements/ui_element.h", - "elements/ui_element_iterator.h", "elements/ui_element_name.cc", "elements/ui_element_name.h", "elements/ui_element_type.cc", @@ -278,7 +277,6 @@ "elements/text_unittest.cc", "elements/throbber_unittest.cc", "elements/transient_element_unittest.cc", - "elements/ui_element_iterator_unittest.cc", "elements/ui_element_unittest.cc", "elements/url_text_unittest.cc", "elements/vector_icon_button_unittest.cc",
diff --git a/chrome/browser/vr/elements/ui_element.cc b/chrome/browser/vr/elements/ui_element.cc index 455c2c9..c39a374 100644 --- a/chrome/browser/vr/elements/ui_element.cc +++ b/chrome/browser/vr/elements/ui_element.cc
@@ -113,9 +113,13 @@ } UiElement* UiElement::GetDescendantByType(UiElementType type) { - for (auto& descendant : *this) { - if (descendant.type() == type) - return &descendant; + if (type_ == type) + return this; + + for (auto& child : children_) { + auto* result = child->GetDescendantByType(type); + if (result) + return result; } return nullptr; } @@ -596,11 +600,15 @@ } void UiElement::AddChild(std::unique_ptr<UiElement> child) { + for (UiElement* current = this; current; current = current->parent()) + current->set_descendants_updated(true); child->parent_ = this; children_.push_back(std::move(child)); } std::unique_ptr<UiElement> UiElement::RemoveChild(UiElement* to_remove) { + for (UiElement* current = this; current; current = current->parent()) + current->set_descendants_updated(true); DCHECK_EQ(this, to_remove->parent_); to_remove->parent_ = nullptr; size_t old_size = children_.size(); @@ -621,12 +629,16 @@ bindings_.push_back(std::move(binding)); } -void UiElement::UpdateBindings() { +void UiElement::UpdateBindingsRecursive() { updated_bindings_this_frame_ = false; for (auto& binding : bindings_) { if (binding->Update()) updated_bindings_this_frame_ = true; } + set_update_phase(UiElement::kUpdatedBindings); + for (auto& child : children_) { + child->UpdateBindingsRecursive(); + } } gfx::Point3F UiElement::GetCenter() const {
diff --git a/chrome/browser/vr/elements/ui_element.h b/chrome/browser/vr/elements/ui_element.h index fcaccee..93d86a3 100644 --- a/chrome/browser/vr/elements/ui_element.h +++ b/chrome/browser/vr/elements/ui_element.h
@@ -19,7 +19,6 @@ #include "chrome/browser/vr/databinding/binding_base.h" #include "chrome/browser/vr/elements/corner_radii.h" #include "chrome/browser/vr/elements/draw_phase.h" -#include "chrome/browser/vr/elements/ui_element_iterator.h" #include "chrome/browser/vr/elements/ui_element_name.h" #include "chrome/browser/vr/elements/ui_element_type.h" #include "chrome/browser/vr/model/camera_model.h" @@ -355,7 +354,7 @@ return bindings_; } - void UpdateBindings(); + void UpdateBindingsRecursive(); gfx::Point3F GetCenter() const; gfx::Vector3dF GetNormal() const; @@ -421,23 +420,6 @@ return children_; } - typedef ForwardUiElementIterator iterator; - typedef ConstForwardUiElementIterator const_iterator; - typedef ReverseUiElementIterator reverse_iterator; - typedef ConstReverseUiElementIterator const_reverse_iterator; - - iterator begin() { return iterator(this); } - iterator end() { return iterator(nullptr); } - const_iterator begin() const { return const_iterator(this); } - const_iterator end() const { return const_iterator(nullptr); } - - reverse_iterator rbegin() { return reverse_iterator(this); } - reverse_iterator rend() { return reverse_iterator(nullptr); } - const_reverse_iterator rbegin() const { return const_reverse_iterator(this); } - const_reverse_iterator rend() const { - return const_reverse_iterator(nullptr); - } - void set_update_phase(UpdatePhase phase) { phase_ = phase; } // This is true for all elements that respect the given view model matrix. If @@ -486,6 +468,9 @@ resizable_by_layout_ = resizable; } + bool descendants_updated() const { return descendants_updated_; } + void set_descendants_updated(bool updated) { descendants_updated_ = updated; } + protected: Animation& animation() { return animation_; } @@ -623,6 +608,10 @@ UiElement* parent_ = nullptr; std::vector<std::unique_ptr<UiElement>> children_; + // This is true if a descendant has been added and the total list has not yet + // been collected by the scene. + bool descendants_updated_ = false; + std::vector<std::unique_ptr<BindingBase>> bindings_; UpdatePhase phase_ = kClean;
diff --git a/chrome/browser/vr/elements/ui_element_iterator.h b/chrome/browser/vr/elements/ui_element_iterator.h deleted file mode 100644 index f92b1da..0000000 --- a/chrome/browser/vr/elements/ui_element_iterator.h +++ /dev/null
@@ -1,107 +0,0 @@ -// Copyright 2017 The Chromium Authors. 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_VR_ELEMENTS_UI_ELEMENT_ITERATOR_H_ -#define CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_ITERATOR_H_ - -#include <vector> - -namespace vr { - -class UiElement; - -// The UiElementIterator traverses a UiElement subtree. Do not use this class -// directly. You should, instead, use UiElement::end/begin/rend/rbegin. NB: you -// may find base::Reversed handy if you're doing reverse iteration. -template <typename T, typename U> -class UiElementIterator { - public: - explicit UiElementIterator(T* root) { - current_ = U::Increment(&index_stack_, root, true); - } - ~UiElementIterator() {} - - void operator++() { current_ = U::Increment(&index_stack_, current_, false); } - void operator++(int) { - current_ = U::Increment(&index_stack_, current_, false); - } - T& operator*() { return *current_; } - bool operator!=(const UiElementIterator& rhs) { - return current_ != rhs.current_ || - index_stack_.empty() != rhs.index_stack_.empty(); - } - - private: - T* current_ = nullptr; - - // The iterator maintains a stack of indices which represent the current index - // in each list of children along the ancestor path. - std::vector<size_t> index_stack_; -}; - -template <typename T> -struct ForwardIncrementer { - static T* Increment(std::vector<size_t>* index_stack, T* e, bool init) { - if (!e || init) - return e; - - if (!e->children().empty()) { - index_stack->push_back(0lu); - return e->children().front().get(); - } - - while (e->parent() && !index_stack->empty() && - index_stack->back() + 1lu >= e->parent()->children().size()) { - index_stack->pop_back(); - e = e->parent(); - } - - if (!e->parent() || index_stack->empty()) - return nullptr; - - index_stack->back()++; - return e->parent()->children()[index_stack->back()].get(); - } -}; - -template <typename T> -struct ReverseIncrementer { - static T* Increment(std::vector<size_t>* index_stack, T* e, bool init) { - if (!e || (index_stack->empty() && !init)) - return nullptr; - - bool should_descend = false; - if (index_stack->empty()) { - should_descend = true; - } else if (e->parent() && index_stack->back() > 0lu) { - index_stack->back()--; - e = e->parent()->children()[index_stack->back()].get(); - should_descend = true; - } - - if (should_descend) { - while (!e->children().empty()) { - index_stack->push_back(e->children().size() - 1lu); - e = e->children().back().get(); - } - return e; - } - - index_stack->pop_back(); - return e->parent(); - } -}; - -typedef UiElementIterator<UiElement, ForwardIncrementer<UiElement>> - ForwardUiElementIterator; -typedef UiElementIterator<const UiElement, ForwardIncrementer<const UiElement>> - ConstForwardUiElementIterator; -typedef UiElementIterator<UiElement, ReverseIncrementer<UiElement>> - ReverseUiElementIterator; -typedef UiElementIterator<const UiElement, ReverseIncrementer<const UiElement>> - ConstReverseUiElementIterator; - -} // namespace vr - -#endif // CHROME_BROWSER_VR_ELEMENTS_UI_ELEMENT_ITERATOR_H_
diff --git a/chrome/browser/vr/elements/ui_element_iterator_unittest.cc b/chrome/browser/vr/elements/ui_element_iterator_unittest.cc deleted file mode 100644 index 59887ee..0000000 --- a/chrome/browser/vr/elements/ui_element_iterator_unittest.cc +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2017 The Chromium Authors. 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/vr/elements/ui_element.h" - -#include "base/containers/adapters.h" -#include "base/test/gtest_util.h" -#include "chrome/browser/vr/ui_scene.h" - -namespace vr { - -namespace { - -// Constructs a tree of the following form -// 1 kRoot -// 2 k2dBrowsingRoot -// 3 kFloor -// 4 k2dBrowsingContentGroup -// 5 kBackplane -// 6 kContentQuad -// 7 kUrlBar -// 8 kCeiling -void MakeTree(UiScene* scene) { - auto element = std::make_unique<UiElement>(); - element->SetName(k2dBrowsingRoot); - scene->AddUiElement(kRoot, std::move(element)); - - element = std::make_unique<UiElement>(); - element->SetName(kFloor); - scene->AddUiElement(k2dBrowsingRoot, std::move(element)); - - element = std::make_unique<UiElement>(); - element->SetName(k2dBrowsingContentGroup); - scene->AddUiElement(k2dBrowsingRoot, std::move(element)); - - element = std::make_unique<UiElement>(); - element->SetName(kBackplane); - scene->AddUiElement(k2dBrowsingContentGroup, std::move(element)); - - element = std::make_unique<UiElement>(); - element->SetName(kContentQuad); - scene->AddUiElement(k2dBrowsingContentGroup, std::move(element)); - - element = std::make_unique<UiElement>(); - element->SetName(kUrlBar); - scene->AddUiElement(k2dBrowsingContentGroup, std::move(element)); - - element = std::make_unique<UiElement>(); - element->SetName(kCeiling); - scene->AddUiElement(k2dBrowsingRoot, std::move(element)); -} - -template <typename T> -void CollectElements(T* e, std::vector<T*>* elements) { - elements->push_back(e); - for (auto& child : e->children()) { - CollectElements(child.get(), elements); - } -} - -} // namespace - -struct UiElementIteratorTestCase { - UiElementName root; - size_t num_elements_in_subtree; -}; - -class UiElementIteratorTest - : public ::testing::TestWithParam<UiElementIteratorTestCase> {}; - -TEST_P(UiElementIteratorTest, VerifyTraversal) { - UiScene scene; - MakeTree(&scene); - std::vector<UiElement*> elements; - CollectElements(scene.GetUiElementByName(GetParam().root), &elements); - - size_t i = 0; - for (auto& e : *(scene.GetUiElementByName(GetParam().root))) { - EXPECT_GT(elements.size(), i); - EXPECT_EQ(elements[i++]->id(), e.id()); - } - EXPECT_EQ(elements.size(), i); - EXPECT_EQ(GetParam().num_elements_in_subtree, i); - - i = 0; - for (auto& e : *const_cast<const UiElement*>( - scene.GetUiElementByName(GetParam().root))) { - EXPECT_GT(elements.size(), i); - EXPECT_EQ(elements[i++]->id(), e.id()); - } - EXPECT_EQ(elements.size(), i); - EXPECT_EQ(GetParam().num_elements_in_subtree, i); - - i = 0; - for (auto& e : base::Reversed(*scene.GetUiElementByName(GetParam().root))) { - EXPECT_GT(elements.size(), i); - EXPECT_EQ(elements[elements.size() - i++ - 1lu]->id(), e.id()); - } - EXPECT_EQ(elements.size(), i); - EXPECT_EQ(GetParam().num_elements_in_subtree, i); - - i = 0; - for (auto& e : base::Reversed(*const_cast<const UiElement*>( - scene.GetUiElementByName(GetParam().root)))) { - EXPECT_GT(elements.size(), i); - EXPECT_EQ(elements[elements.size() - i++ - 1lu]->id(), e.id()); - } - EXPECT_EQ(elements.size(), i); - EXPECT_EQ(GetParam().num_elements_in_subtree, i); -} - -const std::vector<UiElementIteratorTestCase> iterator_test_cases = { - {kRoot, 8}, - {k2dBrowsingContentGroup, 4}, - {kCeiling, 1}, -}; - -INSTANTIATE_TEST_CASE_P(UiElementIteratorTestCases, - UiElementIteratorTest, - ::testing::ValuesIn(iterator_test_cases)); - -} // namespace vr
diff --git a/chrome/browser/vr/elements/ui_element_name.cc b/chrome/browser/vr/elements/ui_element_name.cc index 5bded7a..26cbaa15 100644 --- a/chrome/browser/vr/elements/ui_element_name.cc +++ b/chrome/browser/vr/elements/ui_element_name.cc
@@ -110,8 +110,6 @@ "kPermissionDialogBackplane", "kWebVrUrlToastTransientParent", "kWebVrUrlToast", - "kExclusiveScreenToastTransientParent", - "kExclusiveScreenToast", "kWebVrExclusiveScreenToast", "kPlatformToastTransientParent", "kPlatformToast",
diff --git a/chrome/browser/vr/elements/ui_element_name.h b/chrome/browser/vr/elements/ui_element_name.h index b862f74..eff40db 100644 --- a/chrome/browser/vr/elements/ui_element_name.h +++ b/chrome/browser/vr/elements/ui_element_name.h
@@ -109,8 +109,6 @@ kPermissionDialogBackplane, kWebVrUrlToastTransientParent, kWebVrUrlToast, - kExclusiveScreenToastTransientParent, - kExclusiveScreenToast, kWebVrExclusiveScreenToast, kPlatformToastTransientParent, kPlatformToast,
diff --git a/chrome/browser/vr/metrics/session_metrics_helper.cc b/chrome/browser/vr/metrics/session_metrics_helper.cc index f9494060..4e8092d 100644 --- a/chrome/browser/vr/metrics/session_metrics_helper.cc +++ b/chrome/browser/vr/metrics/session_metrics_helper.cc
@@ -290,13 +290,26 @@ } } +void SessionMetricsHelper::RecordPresentationStartAction( + PresentationStartAction action) { + if (!presentation_session_tracker_ || mode_ != Mode::kWebXrVrPresentation) { + pending_presentation_start_action_ = action; + } else { + presentation_session_tracker_->ukm_entry()->SetStartAction(action); + pending_presentation_start_action_ = base::nullopt; + } +} + void SessionMetricsHelper::ReportRequestPresent() { // If we're not in VR, log this as an entry into VR from 2D. if (mode_ == Mode::kNoVr) { RecordVrStartAction(VrStartAction::kPresentationRequest); - // TODO(offenwanger): Record entered presentation from 2D. + RecordPresentationStartAction( + PresentationStartAction::kRequestFrom2dBrowsing); + } else { + RecordPresentationStartAction( + PresentationStartAction::kRequestFromVrBrowsing); } - // TODO(offenwanger): Else record entered presentation from VR. } void SessionMetricsHelper::MaybeSetVrStartAction(VrStartAction action) { @@ -471,6 +484,14 @@ SessionTracker<ukm::builders::XR_WebXR_PresentationSession>>( std::make_unique<ukm::builders::XR_WebXR_PresentationSession>( ukm::GetSourceIdForWebContentsDocument(web_contents()))); + + if (!pending_presentation_start_action_) { + pending_presentation_start_action_ = PresentationStartAction::kOther; + } + + presentation_session_tracker_->ukm_entry()->SetStartAction( + *pending_presentation_start_action_); + pending_presentation_start_action_ = base::nullopt; } void SessionMetricsHelper::OnExitPresentation() { @@ -617,6 +638,11 @@ SessionTracker<ukm::builders::XR_WebXR_PresentationSession>>( std::make_unique<ukm::builders::XR_WebXR_PresentationSession>( ukm::GetSourceIdForWebContentsDocument(web_contents()))); + if (pending_presentation_start_action_) { + presentation_session_tracker_->ukm_entry()->SetStartAction( + *pending_presentation_start_action_); + pending_presentation_start_action_ = base::nullopt; + } } num_session_navigation_++;
diff --git a/chrome/browser/vr/metrics/session_metrics_helper.h b/chrome/browser/vr/metrics/session_metrics_helper.h index 90864cfc9..6701613 100644 --- a/chrome/browser/vr/metrics/session_metrics_helper.h +++ b/chrome/browser/vr/metrics/session_metrics_helper.h
@@ -37,6 +37,24 @@ kVrStartActionLast = kIntentLaunch, }; +// The source of a request to enter XR Presentation. +enum PresentationStartAction { + // A catch all for methods of Presentation entry that are not otherwise + // logged. + kOther = 0, + // The user triggered a presentation request on a page in 2D, probably by + // clicking an enter VR button. + kRequestFrom2dBrowsing = 1, + // The user triggered a presentation request on a page in VR browsing, + // probably by clicking an enter VR button. + kRequestFromVrBrowsing = 2, + // The user activated a headset on a page that listens for headset activations + // and requests presentation. + kHeadsetActivation = 3, + // The user opened a deep linked app, probably from the Daydream homescreen. + kDeepLinkedApp = 4, +}; + // SessionTimer will monitor the time between calls to StartSession and // StopSession. It will combine multiple segments into a single session if they // are sufficiently close in time. It will also only include segments if they @@ -142,6 +160,7 @@ void RecordUrlRequested(GURL url, NavigationMethod method); void RecordVrStartAction(VrStartAction action); + void RecordPresentationStartAction(PresentationStartAction action); void ReportRequestPresent(); private: @@ -195,6 +214,7 @@ NavigationMethod last_url_request_method_; base::Optional<VrStartAction> pending_page_session_start_action_; + base::Optional<PresentationStartAction> pending_presentation_start_action_; int num_videos_playing_ = 0; int num_session_navigation_ = 0;
diff --git a/chrome/browser/vr/test/ui_test.cc b/chrome/browser/vr/test/ui_test.cc index 0fb58867..30773ad 100644 --- a/chrome/browser/vr/test/ui_test.cc +++ b/chrome/browser/vr/test/ui_test.cc
@@ -61,6 +61,13 @@ return WillElementFaceCamera(element); } +int NumVisibleInTreeRecursive(const UiElement* element) { + int visible = WillElementBeVisible(element) ? 1 : 0; + for (auto& child : element->children()) + visible += NumVisibleInTreeRecursive(child.get()); + return visible; +} + } // namespace UiTest::UiTest() {} @@ -133,18 +140,18 @@ const std::set<UiElementName>& names) const { OnBeginFrame(); SCOPED_TRACE(trace_context); - for (const auto& element : scene_->root_element()) { - SCOPED_TRACE(element.DebugName()); - UiElementName name = element.name(); - UiElementName owner_name = element.owner_name_for_test(); - if (element.draw_phase() == kPhaseNone && owner_name == kNone) { + for (auto* element : scene_->GetAllElements()) { + SCOPED_TRACE(element->DebugName()); + UiElementName name = element->name(); + UiElementName owner_name = element->owner_name_for_test(); + if (element->draw_phase() == kPhaseNone && owner_name == kNone) { EXPECT_TRUE(names.find(name) == names.end()); continue; } if (name == kNone) name = owner_name; bool should_be_visible = (names.find(name) != names.end()); - EXPECT_EQ(WillElementBeVisible(&element), should_be_visible); + EXPECT_EQ(WillElementBeVisible(element), should_be_visible); } } @@ -155,12 +162,7 @@ if (!root) { return 0; } - int visible = 0; - for (const auto& element : *root) { - if (WillElementBeVisible(&element)) - visible++; - } - return visible; + return NumVisibleInTreeRecursive(root); } bool UiTest::VerifyIsAnimating(const std::set<UiElementName>& names,
diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc index 4dc7a73f..5e73d6a7 100644 --- a/chrome/browser/vr/ui.cc +++ b/chrome/browser/vr/ui.cc
@@ -155,6 +155,9 @@ case UiUnsupportedMode::kNeedsKeyboardUpdate: model_->active_modal_prompt_type = kModalPromptTypeUpdateKeyboard; return; + // kSearchEnginePromo should DOFF directly. It should never try to change + // the state of UI. + case UiUnsupportedMode::kSearchEnginePromo: case UiUnsupportedMode::kCount: NOTREACHED(); // Should never be used as a mode (when |enabled| is true). return;
diff --git a/chrome/browser/vr/ui_input_manager.cc b/chrome/browser/vr/ui_input_manager.cc index bf72bcff..ddadcbb 100644 --- a/chrome/browser/vr/ui_input_manager.cc +++ b/chrome/browser/vr/ui_input_manager.cc
@@ -57,13 +57,15 @@ return false; } -void HitTestElements(UiElement* root_element, +void HitTestElements(UiScene* scene, ReticleModel* reticle_model, HitTestRequest* request) { + auto& all_elements = scene->GetAllElements(); + std::vector<const UiElement*> elements; - for (auto& element : *root_element) { - if (element.IsVisible()) { - elements.push_back(&element); + for (auto* element : all_elements) { + if (element->IsVisible()) { + elements.push_back(element); } } @@ -374,7 +376,7 @@ request.ray_origin = ray_origin; request.ray_target = reticle_model->target_point; request.max_distance_to_plane = distance_limit; - HitTestElements(&scene_->root_element(), reticle_model, &request); + HitTestElements(scene_, reticle_model, &request); } void UiInputManager::UpdateQuiescenceState(
diff --git a/chrome/browser/vr/ui_scene.cc b/chrome/browser/vr/ui_scene.cc index ddc21d8..e83b7ba 100644 --- a/chrome/browser/vr/ui_scene.cc +++ b/chrome/browser/vr/ui_scene.cc
@@ -24,16 +24,42 @@ namespace { template <typename P> -UiScene::Elements GetVisibleElements(UiElement* root, - P predicate) { +UiScene::Elements GetVisibleElements( + const std::vector<UiElement*>& all_elements, + P predicate) { UiScene::Elements elements; - for (auto& element : *root) { - if (element.IsVisible() && predicate(&element)) - elements.push_back(&element); + for (auto* element : all_elements) { + if (element->IsVisible() && predicate(element)) + elements.push_back(element); } return elements; } +void GetAllElementsRecursive(std::vector<UiElement*>* elements, UiElement* e) { + e->set_descendants_updated(false); + elements->push_back(e); + for (auto& child : e->children()) + GetAllElementsRecursive(elements, child.get()); +} + +template <typename P> +UiElement* FindElement(UiElement* e, P predicate) { + if (predicate.Run(e)) + return e; + for (auto& child : e->children()) { + if (UiElement* result = FindElement(child.get(), predicate)) { + return result; + } + } + return nullptr; +} + +void InitializeElementRecursive(UiElement* e, SkiaSurfaceProvider* provider) { + e->Initialize(provider); + for (auto& child : e->children()) + InitializeElementRecursive(child.get(), provider); +} + } // namespace void UiScene::AddUiElement(UiElementName parent, @@ -73,22 +99,20 @@ TRACE_EVENT0("gpu", "UiScene::OnBeginFrame.UpdateBindings"); // Propagate updates across bindings. - for (auto& element : *root_element_) { - element.UpdateBindings(); - element.set_update_phase(UiElement::kUpdatedBindings); - } + root_element_->UpdateBindingsRecursive(); } + auto& elements = GetAllElements(); { TRACE_EVENT0("gpu", "UiScene::OnBeginFrame.UpdateAnimationsAndOpacity"); // Process all animations and pre-binding work. I.e., induce any // time-related "dirtiness" on the scene graph. - for (auto& element : *root_element_) { - element.set_update_phase(UiElement::kDirty); - if ((element.DoBeginFrame(current_time, head_pose) || - element.updated_bindings_this_frame()) && - (element.IsVisible() || element.updated_visiblity_this_frame())) { + for (auto* element : elements) { + element->set_update_phase(UiElement::kDirty); + if ((element->DoBeginFrame(current_time, head_pose) || + element->updated_bindings_this_frame()) && + (element->IsVisible() || element->updated_visiblity_this_frame())) { scene_dirty = true; } } @@ -104,21 +128,21 @@ // Textures will have to know what their size would be, if they were to draw // with their current state, and changing anything other than texture // synchronously in response to input should be prohibited. - for (auto& element : *root_element_) { - element.set_update_phase(UiElement::kUpdatedTexturesAndSizes); + for (auto* element : elements) { + element->set_update_phase(UiElement::kUpdatedTexturesAndSizes); } if (root_element_->SizeAndLayOut()) scene_dirty = true; - for (auto& element : *root_element_) { - element.set_update_phase(UiElement::kUpdatedLayout); + for (auto* element : elements) { + element->set_update_phase(UiElement::kUpdatedLayout); } } if (!scene_dirty) { // Nothing to update, so set all elements to the final update phase and // return early. - for (auto& element : *root_element_) { - element.set_update_phase(UiElement::kUpdatedWorldSpaceTransform); + for (auto* element : elements) { + element->set_update_phase(UiElement::kUpdatedWorldSpaceTransform); } return false; } @@ -139,8 +163,8 @@ TRACE_EVENT0("gpu", "UiScene::UpdateTextures"); bool needs_redraw = false; // Update textures and sizes. - for (auto& element : *root_element_) { - if (element.PrepareToDraw()) + for (auto* element : GetAllElements()) { + if (element->PrepareToDraw()) needs_redraw = true; } return needs_redraw; @@ -151,43 +175,40 @@ } UiElement* UiScene::GetUiElementById(int element_id) const { - for (auto& element : *root_element_) { - if (element.id() == element_id) - return &element; - } - return nullptr; + return FindElement( + root_element_.get(), + base::BindRepeating([](int id, UiElement* e) { return e->id() == id; }, + element_id)); } UiElement* UiScene::GetUiElementByName(UiElementName name) const { - for (auto& element : *root_element_) { - if (element.name() == name) - return &element; - } - return nullptr; + return FindElement( + root_element_.get(), + base::BindRepeating( + [](UiElementName name, UiElement* e) { return e->name() == name; }, + name)); } -UiScene::Elements UiScene::GetVisibleElementsToDraw() const { - return GetVisibleElements(GetUiElementByName(kRoot), [](UiElement* element) { +std::vector<UiElement*>& UiScene::GetAllElements() { + if (root_element_->descendants_updated()) { + all_elements_.clear(); + GetAllElementsRecursive(&all_elements_, root_element_.get()); + } + return all_elements_; +} + +UiScene::Elements UiScene::GetVisibleElementsToDraw() { + return GetVisibleElements(GetAllElements(), [](UiElement* element) { return element->draw_phase() == kPhaseForeground || element->draw_phase() == kPhaseBackplanes || element->draw_phase() == kPhaseBackground; }); } -UiScene::Elements UiScene::GetVisibleWebVrOverlayElementsToDraw() const { - return GetVisibleElements( - GetUiElementByName(kWebVrRoot), [](UiElement* element) { - return element->draw_phase() == kPhaseOverlayForeground; - }); -} - -UiScene::Elements UiScene::GetPotentiallyVisibleElements() const { - UiScene::Elements elements; - for (auto& element : *root_element_) { - if (element.draw_phase() != kPhaseNone) - elements.push_back(&element); - } - return elements; +UiScene::Elements UiScene::GetVisibleWebVrOverlayElementsToDraw() { + return GetVisibleElements(GetAllElements(), [](UiElement* element) { + return element->draw_phase() == kPhaseOverlayForeground; + }); } UiScene::UiScene() { @@ -200,19 +221,15 @@ void UiScene::OnGlInitialized(SkiaSurfaceProvider* provider) { gl_initialized_ = true; provider_ = provider; - for (auto& element : *root_element_) - element.Initialize(provider_); + InitializeElementRecursive(root_element_.get(), provider_); } void UiScene::InitializeElement(UiElement* element) { CHECK_GE(element->id(), 0); CHECK_EQ(GetUiElementById(element->id()), nullptr); CHECK_GE(element->draw_phase(), 0); - if (gl_initialized_) { - for (auto& child : *element) { - child.Initialize(provider_); - } - } + if (gl_initialized_) + InitializeElementRecursive(element, provider_); } } // namespace vr
diff --git a/chrome/browser/vr/ui_scene.h b/chrome/browser/vr/ui_scene.h index 4282d71..4526c05 100644 --- a/chrome/browser/vr/ui_scene.h +++ b/chrome/browser/vr/ui_scene.h
@@ -11,7 +11,6 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "chrome/browser/vr/elements/ui_element.h" -#include "chrome/browser/vr/elements/ui_element_iterator.h" #include "chrome/browser/vr/elements/ui_element_name.h" #include "chrome/browser/vr/keyboard_delegate.h" #include "third_party/skia/include/core/SkColor.h" @@ -56,9 +55,9 @@ typedef std::vector<const UiElement*> Elements; - Elements GetVisibleElementsToDraw() const; - Elements GetVisibleWebVrOverlayElementsToDraw() const; - Elements GetPotentiallyVisibleElements() const; + std::vector<UiElement*>& GetAllElements(); + Elements GetVisibleElementsToDraw(); + Elements GetVisibleWebVrOverlayElementsToDraw(); float background_distance() const { return background_distance_; } void set_background_distance(float d) { background_distance_ = d; } @@ -84,6 +83,8 @@ // easily compute dirtiness. bool is_dirty_ = false; + std::vector<UiElement*> all_elements_; + SkiaSurfaceProvider* provider_ = nullptr; DISALLOW_COPY_AND_ASSIGN(UiScene);
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index cc46ef7..4f0796d3 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -2958,14 +2958,6 @@ layout->SetTranslate(0, kIndicatorVerticalOffset, kIndicatorDistanceOffset); layout->set_margin(kWebVrPermissionMargin); - auto fullscreen_toast = CreateTextToast( - kExclusiveScreenToastTransientParent, kExclusiveScreenToast, model_, - l10n_util::GetStringUTF16(IDS_PRESS_APP_TO_EXIT_FULLSCREEN)); - fullscreen_toast->AddBinding( - VR_BIND(bool, Model, model_, model->fullscreen_enabled(), UiElement, - fullscreen_toast.get(), SetVisibleInLayout(view, value))); - layout->AddChild(std::move(fullscreen_toast)); - auto platform_toast = CreateTextToast( kPlatformToastTransientParent, kPlatformToast, model_, base::string16()); platform_toast->AddBinding(std::make_unique<Binding<const PlatformToast*>>(
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc index e9a045b6..9f6123a 100644 --- a/chrome/browser/vr/ui_unittest.cc +++ b/chrome/browser/vr/ui_unittest.cc
@@ -116,57 +116,40 @@ EXPECT_EQ(button->background()->center_color(), background_color); } +void VerifyNoHitTestableElementInSubtree(UiElement* element) { + EXPECT_FALSE(element->IsHitTestable()); + for (auto& child : element->children()) + VerifyNoHitTestableElementInSubtree(child.get()); +} + } // namespace -TEST_F(UiTest, ToastStateTransitions) { +TEST_F(UiTest, WebVrToastStateTransitions) { // Tests toast not showing when directly entering VR though WebVR // presentation. CreateScene(kNotInCct, kInWebVr); - EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); EXPECT_FALSE(IsVisible(kWebVrExclusiveScreenToast)); CreateScene(kNotInCct, kNotInWebVr); - EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); - EXPECT_FALSE(IsVisible(kWebVrExclusiveScreenToast)); - - ui_->SetFullscreen(true); - EXPECT_TRUE(IsVisible(kExclusiveScreenToast)); EXPECT_FALSE(IsVisible(kWebVrExclusiveScreenToast)); ui_->SetWebVrMode(true); ui_->OnWebVrFrameAvailable(); ui_->SetCapturingState(CapturingStateModel()); - EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); EXPECT_TRUE(IsVisible(kWebVrExclusiveScreenToast)); ui_->SetWebVrMode(false); - // TODO(crbug.com/787582): we should not show the fullscreen toast again when - // returning to fullscreen mode after presenting webvr. - EXPECT_TRUE(IsVisible(kExclusiveScreenToast)); - EXPECT_FALSE(IsVisible(kWebVrExclusiveScreenToast)); - - ui_->SetFullscreen(false); - EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); EXPECT_FALSE(IsVisible(kWebVrExclusiveScreenToast)); ui_->SetWebVrMode(true); - EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); EXPECT_FALSE(IsVisible(kWebVrExclusiveScreenToast)); ui_->SetWebVrMode(false); - EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); EXPECT_FALSE(IsVisible(kWebVrExclusiveScreenToast)); } -TEST_F(UiTest, ToastTransience) { +TEST_F(UiTest, WebVrToastTransience) { CreateScene(kNotInCct, kNotInWebVr); - EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); - - ui_->SetFullscreen(true); - EXPECT_TRUE(IsVisible(kExclusiveScreenToast)); - EXPECT_TRUE(RunFor(base::TimeDelta::FromSecondsD(kToastTimeoutSeconds + - kSmallDelaySeconds))); - EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); ui_->SetWebVrMode(true); ui_->OnWebVrFrameAvailable(); @@ -211,7 +194,6 @@ TEST_F(UiTest, CaptureToasts) { CreateScene(kNotInCct, kNotInWebVr); - EXPECT_FALSE(IsVisible(kExclusiveScreenToast)); for (auto& spec : GetIndicatorSpecs()) { for (int i = 0; i < 3; ++i) { @@ -529,7 +511,6 @@ visible_in_fullscreen.insert(kContentQuadShadow); visible_in_fullscreen.insert(kBackplane); visible_in_fullscreen.insert(kCloseButton); - visible_in_fullscreen.insert(kExclusiveScreenToast); visible_in_fullscreen.insert(kController); visible_in_fullscreen.insert(kControllerTouchpadButton); visible_in_fullscreen.insert(kControllerAppButton); @@ -1305,8 +1286,7 @@ TEST_F(UiTest, ControllerHitTest) { CreateScene(kNotInCct, kNotInWebVr); auto* controller = scene_->GetUiElementByName(kControllerRoot); - for (auto& child : *controller) - EXPECT_FALSE(child.IsHitTestable()); + VerifyNoHitTestableElementInSubtree(controller); } TEST_F(UiTest, BrowsingRootBounds) {
diff --git a/chrome/browser/vr/ui_unsupported_mode.h b/chrome/browser/vr/ui_unsupported_mode.h index e850e0f..3d7c3a7 100644 --- a/chrome/browser/vr/ui_unsupported_mode.h +++ b/chrome/browser/vr/ui_unsupported_mode.h
@@ -19,6 +19,7 @@ kVoiceSearchNeedsRecordAudioOsPermission = 4, // TODO(ddorwin): Android only. kGenericUnsupportedFeature = 5, kNeedsKeyboardUpdate = 6, + kSearchEnginePromo = 7, // This must be last. kCount, };
diff --git a/chrome/profiling/BUILD.gn b/chrome/profiling/BUILD.gn deleted file mode 100644 index 5c1d7c45..0000000 --- a/chrome/profiling/BUILD.gn +++ /dev/null
@@ -1,76 +0,0 @@ -# Copyright 2017 The Chromium 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("//chrome/common/features.gni") -import("//services/service_manager/public/cpp/service.gni") -import("//services/service_manager/public/service_manifest.gni") - -static_library("profiling") { - sources = [ - "address.h", - "allocation_event.cc", - "allocation_event.h", - "allocation_tracker.cc", - "allocation_tracker.h", - "backtrace.cc", - "backtrace.h", - "backtrace_storage.cc", - "backtrace_storage.h", - "json_exporter.cc", - "json_exporter.h", - "memlog_connection_manager.cc", - "memlog_connection_manager.h", - "memlog_receiver.h", - "memlog_receiver_pipe.cc", - "memlog_receiver_pipe.h", - "memlog_receiver_pipe_posix.cc", - "memlog_receiver_pipe_posix.h", - "memlog_receiver_pipe_win.cc", - "memlog_receiver_pipe_win.h", - "memlog_stream_parser.cc", - "memlog_stream_parser.h", - "memlog_stream_receiver.h", - "profiling_service.cc", - "profiling_service.h", - ] - - deps = [ - "//base", - "//chrome/common", - "//content/public/child", - "//mojo/edk", - "//services/resource_coordinator/public/cpp:resource_coordinator_cpp", - "//third_party/zlib", - ] -} - -source_set("unit_tests") { - testonly = true - sources = [ - "backtrace_storage_unittest.cc", - "json_exporter_unittest.cc", - "memlog_stream_parser_unittest.cc", - ] - deps = [ - ":profiling", - "//base", - "//testing/gtest", - ] -} - -service_manifest("manifest") { - name = "profiling" - source = "profiling_manifest.json" -} - -fuzzer_test("profiling_fuzzer") { - sources = [ - "memlog_stream_fuzzer.cc", - ] - deps = [ - ":profiling", - ] - libfuzzer_options = [ "max_len = 64000" ] - dict = "memlog_stream_fuzzer.dict" -}
diff --git a/chrome/profiling/OWNERS b/chrome/profiling/OWNERS deleted file mode 100644 index b7a89e5..0000000 --- a/chrome/profiling/OWNERS +++ /dev/null
@@ -1,5 +0,0 @@ -ajwong@chromium.org -erikchen@chromium.org - -per-file profiling_manifest.json=set noparent -per-file profiling_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chrome/profiling/README.md b/chrome/profiling/README.md deleted file mode 100644 index 7ce8ba4..0000000 --- a/chrome/profiling/README.md +++ /dev/null
@@ -1,58 +0,0 @@ -# chrome/profiling - -This document describes the architecture for the profiling process, which -tracks memory allocations in other processes. See [design doc] for more details. - -[design doc]: https://docs.google.com/document/d/1eRAgOFgHwYEPge8G1_5UEvu8TJs5VkYCxd6aFU8AIKY - -There is some additional information in //chrome/common/profiling/README.md - -How To Enable Out of Process Heap Profiling -------------------------------------------- -Navigate to `chrome://flags/#memlog` and set the flag to -"Profile only the browser process." It's possible to profile all processes, but -that has a higher performance impact, and heap dumps of renderer processes are -less actionable. - -How To Use Out of Process Heap Profiling -------------------------------------------- -By default, you don't need to do anything. The heap profiler will detect when -the browser's memory usage has exceeded a certain threshold and upload a trace. - -To force an upload, or to create a heap dump manually, see -`chrome://memory-internals`. The resulting heap dump is intended to be used with -[symbolize_trace][1] and [diff_heap_profiler.py][2]. - -It's also possible to view the heap dump within a [memory-infra][3] trace, -although the results will still need to be symbolized with [symbolize_trace][1]. - -Due to size constraints, most allocations are pruned from the heap dump. Only -allocations of sufficient size and/or frequency are kept. After pruning, the -result is ~100x smaller, but still accounts for about half of all allocations. -More importantly, it still accounts for all obvious memory leaks. - -[1]: https://cs.chromium.org/chromium/src/third_party/catapult/tracing/bin/symbolize_trace -[2]: https://cs.chromium.org/chromium/src/third_party/catapult/experimental/tracing/bin/diff_heap_profiler.py -[3]: /docs/memory-infra/README.md - -Communication Model -------------------- -When profiling is enabled, the browser process will spawn the profiling service. -The services lives in a sandboxed, utility process, and its interface is at -`chrome/common/profiling/memlog_service.mojom`. - -All other processes, including the browser process, are ProfilingClients. See -`profiling_client.mojom`. Depending on the profiling mode, the browser process -will start profiling for just itself and the GPU process [`--memlog=minimal`], -or itself and all child processes [`--memlog=all`]. - -The browser process creates a pipe for each ProfilingClient that allows the -client processes to communicate memory events to the profiling process. - -Code Locations --------------- -`//chrome/common/profiling` - Logic for ProfilingClient. -`//chrome/browser/profiling_host` - Logic in browser process for starting -profiling service, and connecting ProfilingClients to the profiling service. -`//chrome/profiling` - Profiling service. -
diff --git a/chrome/profiling/memlog_receiver_pipe.cc b/chrome/profiling/memlog_receiver_pipe.cc deleted file mode 100644 index 12c3406..0000000 --- a/chrome/profiling/memlog_receiver_pipe.cc +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2017 The Chromium Authors. 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/profiling/memlog_receiver_pipe.h" - -#include "base/bind.h" -#include "base/task_runner.h" -#include "chrome/profiling/memlog_stream_receiver.h" - -namespace profiling { - -MemlogReceiverPipeBase::MemlogReceiverPipeBase( - mojo::edk::ScopedPlatformHandle handle) - : handle_(std::move(handle)) {} - -MemlogReceiverPipeBase::~MemlogReceiverPipeBase() = default; - -void MemlogReceiverPipeBase::SetReceiver( - scoped_refptr<base::TaskRunner> task_runner, - scoped_refptr<MemlogStreamReceiver> receiver) { - receiver_task_runner_ = std::move(task_runner); - receiver_ = receiver; -} - -void MemlogReceiverPipeBase::ReportError() { - handle_.reset(); -} - -void MemlogReceiverPipeBase::OnStreamDataThunk( - scoped_refptr<base::TaskRunner> pipe_task_runner, - std::unique_ptr<char[]> data, - size_t size) { - if (!receiver_->OnStreamData(std::move(data), size)) { - pipe_task_runner->PostTask( - FROM_HERE, base::BindOnce(&MemlogReceiverPipeBase::ReportError, this)); - } -} - -} // namespace profiling
diff --git a/chrome/profiling/memlog_receiver_pipe_posix.h b/chrome/profiling/memlog_receiver_pipe_posix.h deleted file mode 100644 index ede0790..0000000 --- a/chrome/profiling/memlog_receiver_pipe_posix.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright 2017 The Chromium Authors. 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_PROFILING_MEMLOG_RECEIVER_PIPE_POSIX_H_ -#define CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_POSIX_H_ - -#include <string> - -#include "base/files/platform_file.h" -#include "base/macros.h" -#include "base/message_loop/message_loop.h" -#include "build/build_config.h" -#include "chrome/profiling/memlog_receiver_pipe.h" - -namespace profiling { - -class MemlogReceiverPipe : public MemlogReceiverPipeBase, - public base::MessageLoopForIO::Watcher { - public: - explicit MemlogReceiverPipe(mojo::edk::ScopedPlatformHandle handle); - - // Must be called on the IO thread. - void StartReadingOnIOThread(); - - private: - ~MemlogReceiverPipe() override; - - // MessageLoopForIO::Watcher implementation. - void OnFileCanReadWithoutBlocking(int fd) override; - void OnFileCanWriteWithoutBlocking(int fd) override; - - base::MessageLoopForIO::FileDescriptorWatcher controller_; - std::unique_ptr<char[]> read_buffer_; - - DISALLOW_COPY_AND_ASSIGN(MemlogReceiverPipe); -}; - -} // namespace profiling - -#endif // CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_POSIX_H_
diff --git a/chrome/profiling/profiling_browsertest.cc b/chrome/profiling/profiling_browsertest.cc deleted file mode 100644 index ea42f04..0000000 --- a/chrome/profiling/profiling_browsertest.cc +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/command_line.h" -#include "base/process/launch.h" -#include "chrome/common/chrome_switches.h" -#include "chrome/test/base/in_process_browser_test.h" -#include "chrome/test/base/ui_test_utils.h" - -namespace profiling { - -#if !defined(OS_MACOSX) -class ProfilingBrowserTest : public InProcessBrowserTest { - protected: - void RelaunchWithMemlog() { - // TODO(ajwong): Remove this once Brett lands is process model change so the - // browser process actually launches the profiling process. Until then, it's - // okay to have this skip on Mac (which has a different launch setup such - // that this sort of relaunch doesn't work). See GetCommandLineForRelaunch() - // function for details. - // TODO(awong): Can we do this with just SetUpCommandLine() and no Relaunch? - base::CommandLine new_command_line(GetCommandLineForRelaunch()); - new_command_line.AppendSwitchASCII(switches::kMemlog, - switches::kMemlogModeAll); - - ui_test_utils::BrowserAddedObserver observer; - base::LaunchProcess(new_command_line, base::LaunchOptionsForTest()); - - observer.WaitForSingleNewBrowser(); - } -}; - -IN_PROC_BROWSER_TEST_F(ProfilingBrowserTest, InterceptsNew) { - RelaunchWithMemlog(); -} -#endif - -} // namespace profiling
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 1e21fe4..a8772a3 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -880,7 +880,6 @@ "../common/mac/mock_launchd.cc", "../common/mac/mock_launchd.h", "../common/time_format_browsertest.cc", - "../profiling/profiling_browsertest.cc", "../renderer/autofill/autofill_renderer_browsertest.cc", "../renderer/autofill/fake_content_password_manager_driver.cc", "../renderer/autofill/fake_content_password_manager_driver.h", @@ -1662,6 +1661,7 @@ "../browser/extensions/api/screenlock_private/screenlock_private_apitest.cc", "../browser/extensions/api/vpn_provider/vpn_provider_apitest.cc", "../browser/mash_service_registry_browsertest.cc", + "../browser/notifications/chrome_ash_message_center_client_browsertest.cc", "../browser/resources/chromeos/zip_archiver/test/zip_archiver_jstest.cc", "../browser/signin/chromeos_mirror_account_consistency_browsertest.cc", "../browser/ui/app_list/app_list_browsertest.cc", @@ -2136,13 +2136,8 @@ "//tools/perf/:perf_experimental", ] - data = [ - # Needed for isolate script to execute. - "//testing/scripts/common.py", - "//testing/xvfb.py", - "//testing/scripts/run_gtest_perf_test.py", - "//testing/scripts/run_performance_tests.py", - "//testing/scripts/run_telemetry_benchmark_as_googletest.py", + data_deps = [ + "//testing:run_perf_test", ] } @@ -2154,10 +2149,8 @@ "//chrome/test:telemetry_perf_tests", ] - data = [ - "//testing/scripts/run_performance_tests.py", - "//testing/scripts/run_gtest_perf_test.py", - "//testing/scripts/run_telemetry_benchmark_as_googletest.py", + data_deps = [ + "//testing:run_perf_test", ] } @@ -2173,19 +2166,12 @@ group("angle_perftests") { testonly = true - if (is_win || is_linux || is_android) { - data_deps = [ - "//third_party/angle/src/tests:angle_perftests", - ] - } - - data = [ - # Needed for isolate script to execute. - "//testing/scripts/common.py", - "//testing/xvfb.py", - "//testing/scripts/run_gtest_perf_test.py", - "//tools/perf/generate_legacy_perf_dashboard_json.py", + data_deps = [ + "//testing:run_perf_test", ] + if (is_win || is_linux || is_android) { + data_deps += [ "//third_party/angle/src/tests:angle_perftests" ] + } } if (is_mac) { @@ -2727,7 +2713,6 @@ "//chrome:strings", "//chrome/browser/media/router:test_support", "//chrome/common:test_support", - "//chrome/profiling:unit_tests", "//components/autofill/content/renderer:test_support", "//components/browser_sync:test_support", "//components/component_updater:test_support", @@ -3999,8 +3984,8 @@ "../browser/ui/cocoa/info_bubble_view_unittest.mm", "../browser/ui/cocoa/info_bubble_window_unittest.mm", "../browser/ui/cocoa/infobars/confirm_infobar_controller_unittest.mm", + "../browser/ui/cocoa/infobars/infobar_background_view_unittest.mm", "../browser/ui/cocoa/infobars/infobar_container_controller_unittest.mm", - "../browser/ui/cocoa/infobars/infobar_gradient_view_unittest.mm", "../browser/ui/cocoa/infobars/mock_confirm_infobar_delegate.cc", "../browser/ui/cocoa/infobars/mock_confirm_infobar_delegate.h", "../browser/ui/cocoa/infobars/translate_infobar_unittest.mm", @@ -5070,12 +5055,10 @@ data = [ "//chrome/test/data/extensions/api_test/", + ] - # Needed for isolate script to execute. - "//testing/scripts/common.py", - "//testing/xvfb.py", - "//testing/scripts/run_gtest_perf_test.py", - "//tools/perf/generate_legacy_perf_dashboard_json.py", + data_deps = [ + "//testing:run_perf_test", ] if (is_win) { @@ -5454,47 +5437,6 @@ } # Executable to measure time to load libraries. - test("load_library_perf_tests_v2") { - sources = [ - "../browser/load_library_perf_test.cc", - ] - - # This test deliberately does not depend in chrome's test support targets. - # This is a small test and Chrome's test support targets bring in the - # world, causing link time to explode. Please don't add more dependencies - # here without understanding how it affects link time (and factor them - # differently if possible). - deps = [ - "//base/test:test_support_perf", - "//media:media_buildflags", - "//testing/gtest", - "//testing/perf", - "//third_party/widevine/cdm:headers", - ] - - if (enable_library_cdms) { - deps += [ "//media/cdm:cdm_paths" ] - data_deps = [ - "//media/cdm/library_cdm/clear_key_cdm", - "//third_party/widevine/cdm", - ] - } - - data = [ - # Needed for isolate script to execute. - "//testing/scripts/common.py", - "//testing/xvfb.py", - "//testing/scripts/run_gtest_perf_test.py", - "//testing/scripts/run_performance_tests.py", - "//testing/scripts/run_telemetry_benchmark_as_googletest.py", - "//tools/perf/generate_legacy_perf_dashboard_json.py", - ] - - # This target should not require the Chrome executable to run. - assert_no_deps = [ "//chrome" ] - } - - # Executable to measure time to load libraries. test("load_library_perf_tests") { sources = [ "../browser/load_library_perf_test.cc", @@ -5513,24 +5455,18 @@ "//third_party/widevine/cdm:headers", ] + data_deps = [ + "//testing:run_perf_test", + ] + if (enable_library_cdms) { deps += [ "//media/cdm:cdm_paths" ] - data_deps = [ + data_deps += [ "//media/cdm/library_cdm/clear_key_cdm", "//third_party/widevine/cdm", ] } - data = [ - # Needed for isolate script to execute. - "//testing/scripts/common.py", - "//testing/xvfb.py", - "//testing/scripts/run_gtest_perf_test.py", - "//testing/scripts/run_performance_tests.py", - "//testing/scripts/run_telemetry_benchmark_as_googletest.py", - "//tools/perf/generate_legacy_perf_dashboard_json.py", - ] - # This target should not require the Chrome executable to run. assert_no_deps = [ "//chrome" ] }
diff --git a/chrome/test/data/extensions/api_test/webrequest_clients_google_com/background.js b/chrome/test/data/extensions/api_test/webrequest_clients_google_com/background.js index bafc3fd0..9419edd 100644 --- a/chrome/test/data/extensions/api_test/webrequest_clients_google_com/background.js +++ b/chrome/test/data/extensions/api_test/webrequest_clients_google_com/background.js
@@ -6,6 +6,6 @@ chrome.webRequest.onBeforeRequest.addListener(function(details) { ++window.webRequestCount; -}, {urls: ['http://clients1.google.com/']}); +}, {urls: ['https://clients1.google.com/']}); chrome.test.sendMessage('ready');
diff --git a/chrome/test/media_router/media_router_e2e_browsertest.cc b/chrome/test/media_router/media_router_e2e_browsertest.cc index fc3ba441..b40c275 100644 --- a/chrome/test/media_router/media_router_e2e_browsertest.cc +++ b/chrome/test/media_router/media_router_e2e_browsertest.cc
@@ -142,10 +142,10 @@ browser(), GURL("about:blank"), 1); content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - int tab_id = SessionTabHelper::IdForTab(web_contents); + SessionID tab_id = SessionTabHelper::IdForTab(web_contents); // Wait for 30 seconds to make sure the route is stable. - CreateMediaRoute(MediaSourceForTab(tab_id), + CreateMediaRoute(MediaSourceForTab(tab_id.id()), url::Origin::Create(GURL(kOrigin)), web_contents); Wait(base::TimeDelta::FromSeconds(30));
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn index a778b94..64561b3 100644 --- a/chrome/utility/BUILD.gn +++ b/chrome/utility/BUILD.gn
@@ -29,8 +29,8 @@ "//chrome:strings", "//chrome/common", "//chrome/common:mojo_bindings", - "//chrome/profiling", "//components/search_engines", + "//components/services/heap_profiling", "//components/services/heap_profiling/public/cpp", "//components/services/patch:lib", "//components/services/unzip:lib",
diff --git a/chrome/utility/DEPS b/chrome/utility/DEPS index 7305d09a..1d9b056 100644 --- a/chrome/utility/DEPS +++ b/chrome/utility/DEPS
@@ -1,7 +1,6 @@ include_rules = [ "+chrome/grit", "+chrome/installer/util", - "+chrome/profiling", "+chrome/services/file_util/file_util_service.h", "+chrome/services/file_util/public/mojom", "+chrome/services/media_gallery_util/media_gallery_util_service.h", @@ -18,6 +17,7 @@ "+chrome/services/wifi_util_win/wifi_util_win_service.h", "+chrome/services/wifi_util_win/public/mojom", "+components/crash/core/common/crash_keys.h", + "+components/services/heap_profiling/heap_profiling_service.h", "+components/services/heap_profiling/public", "+components/services/font/font_service_app.h", "+components/services/patch",
diff --git a/chrome/utility/chrome_content_utility_client.cc b/chrome/utility/chrome_content_utility_client.cc index 6d30f87..7fef4b4 100644 --- a/chrome/utility/chrome_content_utility_client.cc +++ b/chrome/utility/chrome_content_utility_client.cc
@@ -15,7 +15,7 @@ #include "base/memory/ref_counted.h" #include "base/time/time.h" #include "chrome/common/buildflags.h" -#include "chrome/profiling/profiling_service.h" +#include "components/services/heap_profiling/heap_profiling_service.h" #include "components/services/heap_profiling/public/mojom/constants.mojom.h" #include "components/services/patch/patch_service.h" #include "components/services/patch/public/interfaces/constants.mojom.h" @@ -193,7 +193,7 @@ service_manager::EmbeddedServiceInfo profiling_info; profiling_info.task_runner = content::ChildThread::Get()->GetIOTaskRunner(); profiling_info.factory = - base::Bind(&profiling::ProfilingService::CreateService); + base::Bind(&profiling::HeapProfilingService::CreateService); services->emplace(profiling::mojom::kServiceName, profiling_info); #if !defined(OS_ANDROID)
diff --git a/chromecast/media/cma/backend/android/volume_control_android.cc b/chromecast/media/cma/backend/android/volume_control_android.cc index d850157..ed033016 100644 --- a/chromecast/media/cma/backend/android/volume_control_android.cc +++ b/chromecast/media/cma/backend/android/volume_control_android.cc
@@ -23,7 +23,9 @@ #include "chromecast/base/serializers.h" #include "chromecast/chromecast_buildflags.h" #include "jni/VolumeControl_jni.h" +#if BUILDFLAG(ENABLE_VOLUME_TABLES_ACCESS) #include "jni/VolumeMap_jni.h" +#endif namespace chromecast { namespace media { @@ -166,8 +168,10 @@ for (auto type : {AudioContentType::kMedia, AudioContentType::kAlarm, AudioContentType::kCommunication}) { +#if BUILDFLAG(ENABLE_VOLUME_TABLES_ACCESS) Java_VolumeMap_dumpVolumeTables(base::android::AttachCurrentThread(), static_cast<int>(type)); +#endif volumes_[type] = Java_VolumeControl_getVolume(base::android::AttachCurrentThread(), j_volume_control_, static_cast<int>(type));
diff --git a/chromeos/services/assistant/BUILD.gn b/chromeos/services/assistant/BUILD.gn index e46e802..a155b6e 100644 --- a/chromeos/services/assistant/BUILD.gn +++ b/chromeos/services/assistant/BUILD.gn
@@ -21,6 +21,7 @@ deps = [ "//base", + "//build/util:webkit_version", "//chromeos", "//chromeos/assistant:buildflags", "//chromeos/services/assistant/public/mojom",
diff --git a/chromeos/services/assistant/assistant_manager_service_impl.cc b/chromeos/services/assistant/assistant_manager_service_impl.cc index a088f36..20a4d20 100644 --- a/chromeos/services/assistant/assistant_manager_service_impl.cc +++ b/chromeos/services/assistant/assistant_manager_service_impl.cc
@@ -11,6 +11,7 @@ #include "base/strings/stringprintf.h" #include "base/sys_info.h" #include "base/task_scheduler/post_task.h" +#include "build/util/webkit_version.h" #include "chromeos/assistant/internal/internal_constants.h" #include "chromeos/assistant/internal/internal_util.h" #include "chromeos/services/assistant/service.h" @@ -154,9 +155,13 @@ &os_major_version, &os_minor_version, &os_bugfix_version); std::string user_agent; - base::StringAppendF(&user_agent, "Mozilla/5.0 (X11; CrOS %s %d.%d.%d)", + base::StringAppendF(&user_agent, + "Mozilla/5.0 (X11; CrOS %s %d.%d.%d; %s) " + "AppleWebKit/%d.%d (KHTML, like Gecko)", base::SysInfo::OperatingSystemArchitecture().c_str(), - os_major_version, os_minor_version, os_bugfix_version); + os_major_version, os_minor_version, os_bugfix_version, + base::SysInfo::GetLsbReleaseBoard().c_str(), + WEBKIT_VERSION_MAJOR, WEBKIT_VERSION_MINOR); if (!arc_version.empty()) { base::StringAppendF(&user_agent, " ARC/%s", arc_version.c_str());
diff --git a/components/BUILD.gn b/components/BUILD.gn index 94a848b5..bd18adc5 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -224,6 +224,7 @@ "//components/safe_browsing/password_protection:password_protection_unittest", "//components/safe_browsing/triggers:unit_tests", "//components/security_state/content:unit_tests", + "//components/services/heap_profiling:unit_tests", "//components/spellcheck/browser:unit_tests", "//components/spellcheck/renderer:unit_tests", "//components/subresource_filter/content/browser:unit_tests",
diff --git a/components/arc/common/bluetooth.mojom b/components/arc/common/bluetooth.mojom index f22585f..0371ccf7 100644 --- a/components/arc/common/bluetooth.mojom +++ b/components/arc/common/bluetooth.mojom
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// Next MinVersion: 8 +// Next MinVersion: 9 module arc.mojom; @@ -292,7 +292,7 @@ uint32 service_handle; }; -// Next Method ID: 43 +// Next Method ID: 44 interface BluetoothHost { EnableAdapter@0() => (BluetoothAdapterState state); DisableAdapter@1() => (BluetoothAdapterState state); @@ -396,11 +396,13 @@ // Multi-advertisement functions [MinVersion=6] ReserveAdvertisementHandle@40() => (BluetoothGattStatus status, int32 adv_handle); - [MinVersion=6] BroadcastAdvertisement@41(int32 adv_handle, - BluetoothAdvertisement adv) + [MinVersion=6] EnableAdvertisement@41(int32 adv_handle, + BluetoothAdvertisement adv) => (BluetoothGattStatus status); [MinVersion=6] ReleaseAdvertisementHandle@42(int32 adv_handle) => (BluetoothGattStatus status); + [MinVersion=8] DisableAdvertisement@43(int32 adv_handle) + => (BluetoothGattStatus status); }; // Next Method ID: 19
diff --git a/components/browser_sync/BUILD.gn b/components/browser_sync/BUILD.gn index d8c3092..716f676 100644 --- a/components/browser_sync/BUILD.gn +++ b/components/browser_sync/BUILD.gn
@@ -43,6 +43,7 @@ "//components/version_info:generate_version_info", "//google_apis", "//net", + "//services/identity/public/cpp", ] } @@ -126,6 +127,7 @@ "//components/sync_sessions:test_support", "//google_apis", "//net:test_support", + "//services/identity/public/cpp", "//testing/gmock", ] }
diff --git a/components/browser_sync/DEPS b/components/browser_sync/DEPS index 6b9d9d2d..3bbcc3d 100644 --- a/components/browser_sync/DEPS +++ b/components/browser_sync/DEPS
@@ -23,4 +23,5 @@ "+components/webdata_services", "+google_apis", "+net", + "+services/identity/public/cpp", ]
diff --git a/components/browser_sync/profile_sync_service.cc b/components/browser_sync/profile_sync_service.cc index e75266b..ba9c0ed 100644 --- a/components/browser_sync/profile_sync_service.cc +++ b/components/browser_sync/profile_sync_service.cc
@@ -338,13 +338,13 @@ DCHECK(thread_checker_.CalledOnValidThread()); oauth2_token_service_->AddObserver(this); if (signin_) - signin_->GetOriginal()->AddObserver(this); + signin_->GetSigninManager()->AddObserver(this); } void ProfileSyncService::UnregisterAuthNotifications() { DCHECK(thread_checker_.CalledOnValidThread()); if (signin_) - signin_->GetOriginal()->RemoveObserver(this); + signin_->GetSigninManager()->RemoveObserver(this); if (oauth2_token_service_) oauth2_token_service_->RemoveObserver(this); } @@ -1116,7 +1116,7 @@ // On every platform except ChromeOS, sign out the user after a dashboard // clear. if (!IsLocalSyncEnabled()) { - SigninManager::FromSigninManagerBase(signin_->GetOriginal()) + SigninManager::FromSigninManagerBase(signin_->GetSigninManager()) ->SignOut(signin_metrics::SERVER_FORCED_DISABLE, signin_metrics::SignoutDelete::IGNORE_METRIC); }
diff --git a/components/browser_sync/profile_sync_service_unittest.cc b/components/browser_sync/profile_sync_service_unittest.cc index 47bfd14..16eddb0 100644 --- a/components/browser_sync/profile_sync_service_unittest.cc +++ b/components/browser_sync/profile_sync_service_unittest.cc
@@ -191,10 +191,14 @@ std::string account_id = account_tracker()->SeedAccountInfo(kGaiaId, kEmail); auth_service()->UpdateCredentials(account_id, "oauth2_login_token"); +#if defined(OS_CHROMEOS) + signin_manager()->SignIn(account_id); +#else + signin_manager()->SignIn(kGaiaId, kEmail, "password"); +#endif } void CreateService(ProfileSyncService::StartBehavior behavior) { - signin_manager()->SetAuthenticatedAccountInfo(kGaiaId, kEmail); component_factory_ = profile_sync_service_bundle_.component_factory(); ProfileSyncServiceBundle::SyncClientBuilder builder( &profile_sync_service_bundle_); @@ -318,9 +322,9 @@ } #if defined(OS_CHROMEOS) - SigninManagerBase* signin_manager() + FakeSigninManagerBase* signin_manager() #else - SigninManager* signin_manager() + FakeSigninManager* signin_manager() #endif // Opening brace is outside of macro to avoid confusing lint. {
diff --git a/components/browser_sync/profile_sync_test_util.cc b/components/browser_sync/profile_sync_test_util.cc index b4515c2d..b2b6123 100644 --- a/components/browser_sync/profile_sync_test_util.cc +++ b/components/browser_sync/profile_sync_test_util.cc
@@ -233,6 +233,7 @@ &account_tracker_, nullptr), #endif + identity_manager_(&signin_manager_, &auth_service_), url_request_context_(new net::TestURLRequestContextGetter( base::ThreadTaskRunnerHandle::Get())) { RegisterPrefsForProfileSyncService(pref_service_.registry()); @@ -250,8 +251,8 @@ init_params.start_behavior = start_behavior; init_params.sync_client = std::move(sync_client); - init_params.signin_wrapper = - std::make_unique<SigninManagerWrapper>(signin_manager()); + init_params.signin_wrapper = std::make_unique<SigninManagerWrapper>( + identity_manager(), signin_manager()); init_params.signin_scoped_device_id_callback = base::BindRepeating([]() { return std::string(); }); init_params.oauth2_token_service = auth_service();
diff --git a/components/browser_sync/profile_sync_test_util.h b/components/browser_sync/profile_sync_test_util.h index 44eccf00..a576c343 100644 --- a/components/browser_sync/profile_sync_test_util.h +++ b/components/browser_sync/profile_sync_test_util.h
@@ -21,6 +21,7 @@ #include "components/sync/driver/sync_api_component_factory_mock.h" #include "components/sync_preferences/testing_pref_service_syncable.h" #include "components/sync_sessions/mock_sync_sessions_client.h" +#include "services/identity/public/cpp/identity_manager.h" namespace history { class HistoryService; @@ -132,6 +133,8 @@ FakeSigninManagerType* signin_manager() { return &signin_manager_; } + identity::IdentityManager* identity_manager() { return &identity_manager_; } + AccountTrackerService* account_tracker() { return &account_tracker_; } syncer::SyncApiComponentFactoryMock* component_factory() { @@ -160,6 +163,7 @@ AccountTrackerService account_tracker_; FakeSigninManagerType signin_manager_; FakeProfileOAuth2TokenService auth_service_; + identity::IdentityManager identity_manager_; syncer::SyncApiComponentFactoryMock component_factory_; testing::NiceMock<sync_sessions::MockSyncSessionsClient> sync_sessions_client_;
diff --git a/components/cbor/cbor_reader.cc b/components/cbor/cbor_reader.cc index 4f4ebb3c..c08bbd6a 100644 --- a/components/cbor/cbor_reader.cc +++ b/components/cbor/cbor_reader.cc
@@ -225,13 +225,19 @@ base::Optional<CBORValue> CBORReader::DecodeToSimpleValue( const DataItemHeader& header) { + // ReadVariadicLengthInteger provides this bound. + CHECK_LE(header.additional_info, 27); // Floating point numbers are not supported. - if (header.additional_info > 24 && header.additional_info < 28) { + if (header.additional_info > 24) { error_code_ = DecoderError::UNSUPPORTED_FLOATING_POINT_VALUE; return base::nullopt; } + // Since |header.additional_info| <= 24, ReadVariadicLengthInteger also + // provides this bound for |header.value|. CHECK_LE(header.value, 255u); + // |SimpleValue| is an enum class and so the underlying type is specified to + // be |int|. So this cast is safe. CBORValue::SimpleValue possibly_unsupported_simple_value = static_cast<CBORValue::SimpleValue>(static_cast<int>(header.value)); switch (possibly_unsupported_simple_value) {
diff --git a/components/content_view/java/src/org/chromium/components/content_view/ContentView.java b/components/content_view/java/src/org/chromium/components/content_view/ContentView.java index 7c5c713..ea638ed9 100644 --- a/components/content_view/java/src/org/chromium/components/content_view/ContentView.java +++ b/components/content_view/java/src/org/chromium/components/content_view/ContentView.java
@@ -153,7 +153,10 @@ TraceEvent.begin("ContentView.onFocusChanged"); super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); ContentViewCore cvc = getContentViewCore(); - if (cvc != null) cvc.onFocusChanged(gainFocus, true /* hideKeyboardOnBlur */); + if (cvc != null) { + cvc.setHideKeyboardOnBlur(true); + cvc.onViewFocusChanged(gainFocus); + } } finally { TraceEvent.end("ContentView.onFocusChanged"); }
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 a1251925..80bf0a4 100644 --- a/components/cronet/android/api/src/org/chromium/net/CronetEngine.java +++ b/components/cronet/android/api/src/org/chromium/net/CronetEngine.java
@@ -7,6 +7,7 @@ import android.content.Context; import android.net.http.HttpResponseCache; import android.support.annotation.VisibleForTesting; +import android.util.Log; import java.io.IOException; import java.net.URL; @@ -27,6 +28,8 @@ * using {@link Builder}. */ public abstract class CronetEngine { + private static final String TAG = CronetEngine.class.getSimpleName(); + /** * A builder for {@link CronetEngine}s, which allows runtime configuration of * {@code CronetEngine}. Configuration options are set on the builder and @@ -320,7 +323,13 @@ private static ICronetEngineBuilder createBuilderDelegate(Context context) { List<CronetProvider> providerList = getEnabledCronetProviders(context, CronetProvider.getAllProviders(context)); - return providerList.get(0).createBuilder().mBuilderDelegate; + CronetProvider provider = providerList.get(0); + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, + String.format("Using '%s' provider for creating CronetEngine.Builder.", + provider)); + } + return provider.createBuilder().mBuilderDelegate; } /**
diff --git a/components/data_usage/android/traffic_stats_amortizer.cc b/components/data_usage/android/traffic_stats_amortizer.cc index 3a0acfc..51a3094 100644 --- a/components/data_usage/android/traffic_stats_amortizer.cc +++ b/components/data_usage/android/traffic_stats_amortizer.cc
@@ -165,7 +165,7 @@ } void RecordConcurrentTabsHistogram(const DataUseBuffer& data_use_buffer) { - std::set<int32_t> unique_tabs; + std::set<SessionID> unique_tabs; for (const auto& data_use_buffer_pair : data_use_buffer) unique_tabs.insert(data_use_buffer_pair.first->tab_id); UMA_HISTOGRAM_COUNTS_100("TrafficStatsAmortizer.ConcurrentTabs",
diff --git a/components/data_usage/android/traffic_stats_amortizer_unittest.cc b/components/data_usage/android/traffic_stats_amortizer_unittest.cc index 462400c8..a91d9642 100644 --- a/components/data_usage/android/traffic_stats_amortizer_unittest.cc +++ b/components/data_usage/android/traffic_stats_amortizer_unittest.cc
@@ -73,7 +73,7 @@ // Synthesizes a fake std::unique_ptr<DataUse> with the given |url|, |tab_id|, // |tx_bytes| and |rx_bytes|, using arbitrary values for all other fields. std::unique_ptr<DataUse> CreateDataUseWithURLAndTab(const GURL& url, - int32_t tab_id, + SessionID tab_id, int64_t tx_bytes, int64_t rx_bytes) { return std::unique_ptr<DataUse>( @@ -89,13 +89,14 @@ std::unique_ptr<DataUse> CreateDataUseWithURL(const GURL& url, int64_t tx_bytes, int64_t rx_bytes) { - return CreateDataUseWithURLAndTab(url, 10, tx_bytes, rx_bytes); + return CreateDataUseWithURLAndTab(url, SessionID::FromSerializedValue(10), + tx_bytes, rx_bytes); } // Synthesizes a fake std::unique_ptr<DataUse> with the given |tab_id|, // |tx_bytes| // and |rx_bytes|, using arbitrary values for all other fields. -std::unique_ptr<DataUse> CreateDataUseWithTab(int32_t tab_id, +std::unique_ptr<DataUse> CreateDataUseWithTab(SessionID tab_id, int64_t tx_bytes, int64_t rx_bytes) { return CreateDataUseWithURLAndTab(GURL("http://example.com"), tab_id, @@ -795,6 +796,9 @@ } TEST_F(TrafficStatsAmortizerTest, ConcurrentTabsHistogram) { + SessionID kTabId1 = SessionID::FromSerializedValue(1); + SessionID kTabId2 = SessionID::FromSerializedValue(2); + SkipFirstAmortizationRun(); { @@ -802,17 +806,17 @@ base::HistogramTester histogram_tester; amortizer()->SetNextTrafficStats(true, 0, 0); amortizer()->AmortizeDataUse( - CreateDataUseWithTab(1, 50, 500), - ExpectDataUseCallback(CreateDataUseWithTab(1, 100, 1000))); + CreateDataUseWithTab(kTabId1, 50, 500), + ExpectDataUseCallback(CreateDataUseWithTab(kTabId1, 100, 1000))); amortizer()->AmortizeDataUse( - CreateDataUseWithTab(2, 100, 1000), - ExpectDataUseCallback(CreateDataUseWithTab(2, 200, 2000))); + CreateDataUseWithTab(kTabId2, 100, 1000), + ExpectDataUseCallback(CreateDataUseWithTab(kTabId2, 200, 2000))); amortizer()->AmortizeDataUse( - CreateDataUseWithTab(1, 50, 500), - ExpectDataUseCallback(CreateDataUseWithTab(1, 100, 1000))); + CreateDataUseWithTab(kTabId1, 50, 500), + ExpectDataUseCallback(CreateDataUseWithTab(kTabId1, 100, 1000))); amortizer()->AmortizeDataUse( - CreateDataUseWithTab(2, 100, 1000), - ExpectDataUseCallback(CreateDataUseWithTab(2, 200, 2000))); + CreateDataUseWithTab(kTabId2, 100, 1000), + ExpectDataUseCallback(CreateDataUseWithTab(kTabId2, 200, 2000))); amortizer()->SetNextTrafficStats(true, 600, 6000); AdvanceTime(kTrafficStatsQueryDelay); histogram_tester.ExpectUniqueSample(kConcurrentTabs, 2, 1); @@ -827,9 +831,10 @@ base::HistogramTester histogram_tester; for (int32_t i = 1; i <= total_tabs; ++i) { + SessionID tab_id = SessionID::FromSerializedValue(i); amortizer()->AmortizeDataUse( - CreateDataUseWithTab(i, 100, 1000), - ExpectDataUseCallback(CreateDataUseWithTab(i, 200, 2000))); + CreateDataUseWithTab(tab_id, 100, 1000), + ExpectDataUseCallback(CreateDataUseWithTab(tab_id, 200, 2000))); } amortizer()->AddTrafficStats(total_tabs * 200, total_tabs * 2000); AdvanceTime(kTrafficStatsQueryDelay);
diff --git a/components/data_usage/core/BUILD.gn b/components/data_usage/core/BUILD.gn index 42829fe7..6ce7f98 100644 --- a/components/data_usage/core/BUILD.gn +++ b/components/data_usage/core/BUILD.gn
@@ -13,6 +13,7 @@ ] deps = [ "//base", + "//components/sessions", "//net", "//url", ]
diff --git a/components/data_usage/core/DEPS b/components/data_usage/core/DEPS index d97699df..f9ac0a4 100644 --- a/components/data_usage/core/DEPS +++ b/components/data_usage/core/DEPS
@@ -1,4 +1,5 @@ include_rules = [ + "+components/sessions", "+net", "+url", ]
diff --git a/components/data_usage/core/data_use.cc b/components/data_usage/core/data_use.cc index 87942617..83998843 100644 --- a/components/data_usage/core/data_use.cc +++ b/components/data_usage/core/data_use.cc
@@ -28,7 +28,7 @@ DataUse::DataUse(const GURL& url, const base::TimeTicks& request_start, const GURL& site_for_cookies, - int32_t tab_id, + SessionID tab_id, net::NetworkChangeNotifier::ConnectionType connection_type, const std::string& mcc_mnc, int64_t tx_bytes,
diff --git a/components/data_usage/core/data_use.h b/components/data_usage/core/data_use.h index 27effe3..1762745f 100644 --- a/components/data_usage/core/data_use.h +++ b/components/data_usage/core/data_use.h
@@ -11,6 +11,7 @@ #include <utility> #include "base/time/time.h" +#include "components/sessions/core/session_id.h" #include "net/base/network_change_notifier.h" #include "url/gurl.h" @@ -25,7 +26,7 @@ DataUse(const GURL& url, const base::TimeTicks& request_start, const GURL& site_for_cookies, - int32_t tab_id, + SessionID tab_id, net::NetworkChangeNotifier::ConnectionType connection_type, const std::string& mcc_mnc, int64_t tx_bytes, @@ -50,7 +51,7 @@ // be invalid(-1) for the mainframe request since tab cannot be retrieved yet. // Could be invalid(-1) if the data use does not belong to a tab, for example // chrome-services traffic. - int32_t tab_id; + SessionID tab_id; // content::GlobalRequestID of the mainframe request. This is populated only // when tab id cannot be retrieved of a mainframe request, and used to
diff --git a/components/data_usage/core/data_use_aggregator.cc b/components/data_usage/core/data_use_aggregator.cc index 844c903..33facf8 100644 --- a/components/data_usage/core/data_use_aggregator.cc +++ b/components/data_usage/core/data_use_aggregator.cc
@@ -55,10 +55,10 @@ net::LoadTimingInfo load_timing_info; request->GetLoadTimingInfo(&load_timing_info); - std::unique_ptr<DataUse> data_use( - new DataUse(request->url(), load_timing_info.request_start, - request->site_for_cookies(), -1 /* tab_id */, - connection_type_, mcc_mnc_, tx_bytes, rx_bytes)); + std::unique_ptr<DataUse> data_use(new DataUse( + request->url(), load_timing_info.request_start, + request->site_for_cookies(), /*tab_id=*/SessionID::InvalidValue(), + connection_type_, mcc_mnc_, tx_bytes, rx_bytes)); if (!annotator_) { PassDataUseToAmortizer(std::move(data_use));
diff --git a/components/data_usage/core/data_use_aggregator_unittest.cc b/components/data_usage/core/data_use_aggregator_unittest.cc index bb3bdc4..7a8bad9 100644 --- a/components/data_usage/core/data_use_aggregator_unittest.cc +++ b/components/data_usage/core/data_use_aggregator_unittest.cc
@@ -90,7 +90,7 @@ // predetermined fake tab ID. class FakeDataUseAnnotator : public DataUseAnnotator { public: - FakeDataUseAnnotator() : tab_id_(-1) {} + FakeDataUseAnnotator() : tab_id_(SessionID::InvalidValue()) {} ~FakeDataUseAnnotator() override {} void Annotate( @@ -101,10 +101,10 @@ callback.Run(std::move(data_use)); } - void set_tab_id(int32_t tab_id) { tab_id_ = tab_id; } + void set_tab_id(SessionID tab_id) { tab_id_ = tab_id; } private: - int32_t tab_id_; + SessionID tab_id_; DISALLOW_COPY_AND_ASSIGN(FakeDataUseAnnotator); }; @@ -135,15 +135,15 @@ // The simulated context for the data usage of a net::URLRequest. struct DataUseContext { DataUseContext() - : tab_id(-1), + : tab_id(SessionID::InvalidValue()), connection_type(net::NetworkChangeNotifier::CONNECTION_UNKNOWN) {} - DataUseContext(int32_t tab_id, + DataUseContext(SessionID tab_id, net::NetworkChangeNotifier::ConnectionType connection_type, const std::string& mcc_mnc) : tab_id(tab_id), connection_type(connection_type), mcc_mnc(mcc_mnc) {} - int32_t tab_id; + SessionID tab_id; net::NetworkChangeNotifier::ConnectionType connection_type; std::string mcc_mnc; }; @@ -268,7 +268,7 @@ std::unique_ptr<net::URLRequest> ExecuteRequest( const GURL& url, const GURL& site_for_cookies, - int32_t tab_id, + SessionID tab_id, net::NetworkChangeNotifier::ConnectionType connection_type, const std::string& mcc_mnc) { net::MockRead reads[] = { @@ -344,7 +344,7 @@ Initialize(std::move(annotator), std::move(amortizer)); - const int32_t kFooTabId = 10; + const SessionID kFooTabId = SessionID::FromSerializedValue(10); const net::NetworkChangeNotifier::ConnectionType kFooConnectionType = net::NetworkChangeNotifier::CONNECTION_2G; const std::string kFooMccMnc = "foo_mcc_mnc"; @@ -352,7 +352,7 @@ ExecuteRequest(GURL("http://foo.com"), GURL("http://foofirstparty.com"), kFooTabId, kFooConnectionType, kFooMccMnc); - const int32_t kBarTabId = 20; + const SessionID kBarTabId = SessionID::FromSerializedValue(20); const net::NetworkChangeNotifier::ConnectionType kBarConnectionType = net::NetworkChangeNotifier::CONNECTION_WIFI; const std::string kBarMccMnc = "bar_mcc_mnc"; @@ -373,7 +373,7 @@ if (test_case.expect_tab_ids) EXPECT_EQ(kFooTabId, data_use_it->tab_id); else - EXPECT_EQ(-1, data_use_it->tab_id); + EXPECT_FALSE(data_use_it->tab_id.is_valid()); EXPECT_EQ(kFooConnectionType, data_use_it->connection_type); EXPECT_EQ(kFooMccMnc, data_use_it->mcc_mnc); @@ -400,7 +400,7 @@ if (test_case.expect_tab_ids) EXPECT_EQ(kBarTabId, data_use_it->tab_id); else - EXPECT_EQ(-1, data_use_it->tab_id); + EXPECT_FALSE(data_use_it->tab_id.is_valid()); EXPECT_EQ(kBarConnectionType, data_use_it->connection_type); EXPECT_EQ(kBarMccMnc, data_use_it->mcc_mnc);
diff --git a/components/exo/shell_surface_base.cc b/components/exo/shell_surface_base.cc index 8b694811..3177d6e 100644 --- a/components/exo/shell_surface_base.cc +++ b/components/exo/shell_surface_base.cc
@@ -1245,20 +1245,18 @@ void ShellSurfaceBase::UpdateWidgetBounds() { DCHECK(widget_); - // Return early if the shell is currently managing the bounds of the widget. - // 1) When a window is either maximized/fullscreen/pinned, and the bounds - // are not controlled by a client. ash::wm::WindowState* window_state = ash::wm::GetWindowState(widget_->GetNativeWindow()); - if (window_state->IsMaximizedOrFullscreenOrPinned() && - !window_state->allow_set_bounds_direct()) { - return; + // Return early if the shell is currently managing the bounds of the widget. + if (!window_state->allow_set_bounds_direct()) { + // 1) When a window is either maximized/fullscreen/pinned. + if (window_state->IsMaximizedOrFullscreenOrPinned()) + return; + // 2) When a window is being dragged by |resizer_|. + if (IsResizing()) + return; } - // 2) When a window is being dragged by |resizer_|. - if (IsResizing()) - return; - // Return early if there is pending configure requests. if (!pending_configs_.empty() || scoped_configure_) return;
diff --git a/components/favicon/core/favicon_handler.cc b/components/favicon/core/favicon_handler.cc index 1e7cd5b..52a8c144 100644 --- a/components/favicon/core/favicon_handler.cc +++ b/components/favicon/core/favicon_handler.cc
@@ -199,7 +199,7 @@ candidates_received_ = false; manifest_url_ = GURL(); non_manifest_original_candidates_.clear(); - candidates_.clear(); + final_candidates_.reset(); notification_icon_url_ = GURL(); notification_icon_type_ = favicon_base::IconType::kInvalid; current_candidate_index_ = 0u; @@ -235,8 +235,8 @@ // and hence get sorted last during prioritization). We stop immediately // to avoid downloading them all, although we don't have the certainty // that no better favicon is among them. - return current_candidate_index_ + 1 >= candidates_.size() || - candidates_[current_candidate_index_ + 1].score <= + return current_candidate_index_ + 1 >= final_candidates_->size() || + (*final_candidates_)[current_candidate_index_ + 1].score <= best_favicon_.candidate.score; } else { return best_favicon_.candidate.score == 1; @@ -327,6 +327,7 @@ candidates_received_ = true; error_other_than_404_found_ = false; non_manifest_original_candidates_ = candidates; + final_candidates_.reset(); cancelable_task_tracker_for_candidates_.TryCancelAll(); manifest_download_request_.Cancel(); image_download_request_.Cancel(); @@ -380,7 +381,7 @@ } if (has_expired_or_incomplete_result) { - manifest_download_request_.Reset(base::Bind( + manifest_download_request_.Reset(base::BindOnce( &FaviconHandler::OnDidDownloadManifest, base::Unretained(this))); delegate_->DownloadManifest(manifest_url_, manifest_download_request_.callback()); @@ -411,6 +412,8 @@ void FaviconHandler::OnGotFinalIconURLCandidates( const std::vector<FaviconURL>& candidates) { + DCHECK(!final_candidates_); + const std::vector<int> desired_pixel_sizes = GetDesiredPixelSizes(handler_type_); @@ -426,7 +429,7 @@ std::stable_sort(sorted_candidates.begin(), sorted_candidates.end(), &FaviconCandidate::CompareScore); - candidates_ = std::move(sorted_candidates); + final_candidates_ = std::move(sorted_candidates); if (got_favicon_from_history_) OnGotInitialHistoryDataAndIconURLCandidates(); @@ -444,10 +447,11 @@ } void FaviconHandler::OnGotInitialHistoryDataAndIconURLCandidates() { - DCHECK(candidates_received_); + DCHECK(final_candidates_); DCHECK(got_favicon_from_history_); + DCHECK_EQ(0U, current_candidate_index_); - if (candidates_.empty()) { + if (final_candidates_->empty()) { // The page lists no candidates that match our target |icon_types_|, so // check if any existing mappings should be deleted. MaybeDeleteFaviconMappings(); @@ -519,7 +523,8 @@ } } - if (request_next_icon && current_candidate_index_ + 1 < candidates_.size()) { + if (request_next_icon && + current_candidate_index_ + 1 < final_candidates_->size()) { // Process the next candidate. ++current_candidate_index_; DownloadCurrentCandidateOrAskFaviconService(); @@ -539,14 +544,14 @@ : favicon_base::IconType::kWebManifestIcon); } // Clear download related state. - current_candidate_index_ = candidates_.size(); + current_candidate_index_ = final_candidates_->size(); best_favicon_ = DownloadedFavicon(); } } const std::vector<GURL> FaviconHandler::GetIconURLs() const { std::vector<GURL> icon_urls; - for (const FaviconCandidate& candidate : candidates_) + for (const FaviconCandidate& candidate : *final_candidates_) icon_urls.push_back(candidate.icon_url); return icon_urls; } @@ -594,11 +599,15 @@ NotifyFaviconUpdated(favicon_bitmap_results); } - if (candidates_received_) + if (final_candidates_) OnGotInitialHistoryDataAndIconURLCandidates(); } void FaviconHandler::DownloadCurrentCandidateOrAskFaviconService() { + DCHECK(image_download_request_.IsCancelled()); + DCHECK(manifest_download_request_.IsCancelled()); + DCHECK(current_candidate()); + const GURL icon_url = current_candidate()->icon_url; const favicon_base::IconType icon_type = current_candidate()->icon_type; // If the icons listed in a manifest are being processed, skip the cache @@ -670,8 +679,8 @@ return; } image_download_request_.Reset( - base::Bind(&FaviconHandler::OnDidDownloadFavicon, base::Unretained(this), - icon_type)); + base::BindOnce(&FaviconHandler::OnDidDownloadFavicon, + base::Unretained(this), icon_type)); // A max bitmap size is specified to avoid receiving huge bitmaps in // OnDidDownloadFavicon(). See FaviconDriver::StartDownload() // for more details about the max bitmap size.
diff --git a/components/favicon/core/favicon_handler.h b/components/favicon/core/favicon_handler.h index 0ee94a11..6a8ff2f 100644 --- a/components/favicon/core/favicon_handler.h +++ b/components/favicon/core/favicon_handler.h
@@ -14,6 +14,7 @@ #include "base/containers/flat_set.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/optional.h" #include "base/task/cancelable_task_tracker.h" #include "components/favicon/core/favicon_driver_observer.h" #include "components/favicon/core/favicon_url.h" @@ -275,8 +276,9 @@ // Return the current candidate if any. const FaviconCandidate* current_candidate() const { - return current_candidate_index_ < candidates_.size() - ? &candidates_[current_candidate_index_] + DCHECK(final_candidates_); + return current_candidate_index_ < final_candidates_->size() + ? &final_candidates_.value()[current_candidate_index_] : nullptr; } @@ -318,11 +320,11 @@ bool redownload_icons_; // Requests to the renderer to download a manifest. - base::CancelableCallback<Delegate::ManifestDownloadCallback::RunType> + base::CancelableOnceCallback<Delegate::ManifestDownloadCallback::RunType> manifest_download_request_; // Requests to the renderer to download favicons. - base::CancelableCallback<Delegate::ImageDownloadCallback::RunType> + base::CancelableOnceCallback<Delegate::ImageDownloadCallback::RunType> image_download_request_; // The combination of the supported icon types. @@ -348,7 +350,8 @@ std::vector<FaviconURL> non_manifest_original_candidates_; // The prioritized favicon candidates from the page back from the renderer. - std::vector<FaviconCandidate> candidates_; + // Populated by OnGotFinalIconURLCandidates(). + base::Optional<std::vector<FaviconCandidate>> final_candidates_; // The icon URL and the icon type of the favicon in the most recent // FaviconDriver::OnFaviconAvailable() notification.
diff --git a/components/favicon/core/favicon_handler_unittest.cc b/components/favicon/core/favicon_handler_unittest.cc index 318675d..3d7363c 100644 --- a/components/favicon/core/favicon_handler_unittest.cc +++ b/components/favicon/core/favicon_handler_unittest.cc
@@ -425,7 +425,12 @@ base::Closure bound_callback = base::Bind(callback, results_[page_or_icon_url]); - if (page_or_icon_url != manual_callback_url_) { + // In addition to checking the URL against |manual_callback_url_|, we also + // defer responses if there are already pending responses (i.e. a previous + // lookup matched |manual_callback_url_|), because requests to the history + // should be executed sequentially. + if (page_or_icon_url != manual_callback_url_ && + !HasPendingManualCallback()) { return tracker->PostTask(base::ThreadTaskRunnerHandle::Get().get(), FROM_HERE, bound_callback); } @@ -1289,6 +1294,42 @@ base::RunLoop().RunUntilIdle(); } +// Tests that there is not crash and SetFavicons() is called with the +// appropriate icon URL in the following scenario: +// - The database initially has a cached but expired icon for the page. +// - Initial favicon candidates are received fast, before the history lookup +// completes. +// - Before the history lookup completes, favicon candidates are updated via +// javascript to include a different set of icons. +TEST_F(FaviconHandlerTest, + UpdateIconsViaJavascriptAfterFastCandidatesAndExpiredIcon) { + EXPECT_CALL(favicon_service_, DeleteFaviconMappings(_, _)).Times(0); + EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL64x64, _, _)); + + // Initial database contains a cached by expired icon for |kPageURL|. + favicon_service_.fake()->Store( + kPageURL, kIconURL16x16, + CreateRawBitmapResult(kIconURL16x16, kTouchIcon, /*expired=*/true)); + + // Initial candidates are received before the history lookup for |kPageURL| is + // finished. + favicon_service_.fake()->SetRunCallbackManuallyForUrl(kPageURL); + std::unique_ptr<FaviconHandler> handler = + RunHandlerWithSimpleFaviconCandidates(URLVector{kIconURL16x16}); + ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback()); + // Update candidates, now containing a different set of icons. + handler->OnUpdateCandidates( + kPageURL, {FaviconURL(kIconURL64x64, kFavicon, kEmptySizes)}, + /*manifest_url=*/GURL()); + base::RunLoop().RunUntilIdle(); + // Complete the history lookup for |kPageURL| now. + ASSERT_TRUE(favicon_service_.fake()->RunCallbackManually()); + base::RunLoop().RunUntilIdle(); + + EXPECT_THAT(favicon_service_.fake()->db_requests(), ElementsAre(kPageURL)); + EXPECT_THAT(delegate_.downloads(), ElementsAre(kIconURL64x64)); +} + // Test the favicon which is selected when the web page provides several // favicons and none of the favicons are cached in history. // The goal of this test is to be more of an integration test than @@ -1835,6 +1876,90 @@ EXPECT_THAT(delegate_.downloads(), IsEmpty()); } +// Believed to fix crbug.com/544560. +// Tests that there is not crash and SetFavicons() is called with the +// appropriate icon URL in the following scenario: +// - The database initially has a cached but expired icon for the page. +// - Initial favicon candidates are received fast, before the history lookup +// completes. There is no manifest URL initially. +// - Before the history lookup completes, favicon candidates are updated via +// javascript to include a manifest URL. +// - The manifest lists at least one icon. +TEST_F(FaviconHandlerManifestsEnabledTest, + AddManifestWithIconsViaJavascriptAfterFastCandidatesAndExpiredIcon) { + EXPECT_CALL(favicon_service_, DeleteFaviconMappings(_, _)).Times(0); + EXPECT_CALL(favicon_service_, SetFavicons(_, kManifestURL, _, _)); + + // Initial database contains a cached by expired icon for |kPageURL|. + favicon_service_.fake()->Store( + kPageURL, kIconURL16x16, + CreateRawBitmapResult(kIconURL16x16, kTouchIcon, /*expired=*/true)); + + // Manifest with icons. + const std::vector<favicon::FaviconURL> kManifestIcons = { + FaviconURL(kIconURL64x64, kWebManifestIcon, kEmptySizes), + }; + delegate_.fake_manifest_downloader().Add(kManifestURL, kManifestIcons); + + // Initial load does NOT contain a manifest. Regular candidates are received + // before the history lookup for |kPageURL| is finished. + favicon_service_.fake()->SetRunCallbackManuallyForUrl(kPageURL); + std::unique_ptr<FaviconHandler> handler = + RunHandlerWithSimpleTouchIconCandidates({kIconURL16x16}, + /*manifest_url=*/GURL()); + ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback()); + // Update candidates, now containing a manifest URL. + handler->OnUpdateCandidates( + kPageURL, {FaviconURL(kIconURL16x16, kTouchIcon, kEmptySizes)}, + kManifestURL); + base::RunLoop().RunUntilIdle(); + // Complete the history lookup for |kPageURL| now. + ASSERT_TRUE(favicon_service_.fake()->RunCallbackManually()); + base::RunLoop().RunUntilIdle(); + + EXPECT_THAT(favicon_service_.fake()->db_requests(), + ElementsAre(kPageURL, kManifestURL)); + EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL64x64)); +} + +// Believed to fix crbug.com/544560. +// Same as the test above with the difference that the manifest contains no +// icons. +TEST_F(FaviconHandlerManifestsEnabledTest, + AddManifestWithoutIconsViaJavascriptAfterFastCandidatesAndExpiredIcon) { + EXPECT_CALL(favicon_service_, DeleteFaviconMappings(_, _)).Times(0); + EXPECT_CALL(favicon_service_, SetFavicons(_, kIconURL16x16, _, _)); + + // Initial database contains a cached by expired icon for |kPageURL|. + favicon_service_.fake()->Store( + kPageURL, kIconURL16x16, + CreateRawBitmapResult(kIconURL16x16, kTouchIcon, /*expired=*/true)); + + // Manifest without icons. + delegate_.fake_manifest_downloader().Add(kManifestURL, + std::vector<favicon::FaviconURL>()); + + // Initial load does NOT contain a manifest. Regular candidates are received + // before the history lookup for |kPageURL| is finished. + favicon_service_.fake()->SetRunCallbackManuallyForUrl(kPageURL); + std::unique_ptr<FaviconHandler> handler = + RunHandlerWithSimpleTouchIconCandidates({kIconURL16x16}, + /*manifest_url=*/GURL()); + ASSERT_TRUE(favicon_service_.fake()->HasPendingManualCallback()); + // Update candidates, now containing a manifest URL. + handler->OnUpdateCandidates( + kPageURL, {FaviconURL(kIconURL16x16, kTouchIcon, kEmptySizes)}, + kManifestURL); + base::RunLoop().RunUntilIdle(); + // Complete the history lookup for |kPageURL| now. + ASSERT_TRUE(favicon_service_.fake()->RunCallbackManually()); + base::RunLoop().RunUntilIdle(); + + EXPECT_THAT(favicon_service_.fake()->db_requests(), + ElementsAre(kPageURL, kManifestURL)); + EXPECT_THAT(delegate_.downloads(), ElementsAre(kManifestURL, kIconURL16x16)); +} + // Test that a favicon corresponding to a web manifest is reported when there is // data in the database for neither the page URL nor the manifest URL. TEST_F(FaviconHandlerManifestsEnabledTest, GetFaviconFromUnknownManifest) {
diff --git a/components/omnibox/browser/base_search_provider.cc b/components/omnibox/browser/base_search_provider.cc index 4800d933..c10a7e9 100644 --- a/components/omnibox/browser/base_search_provider.cc +++ b/components/omnibox/browser/base_search_provider.cc
@@ -149,9 +149,20 @@ // mode. They also assume the caller knows what it's doing and we set // this match to look as if it was received/created synchronously. SearchSuggestionParser::SuggestResult suggest_result( - suggestion, type, 0, suggestion, base::string16(), base::string16(), - base::string16(), base::string16(), nullptr, std::string(), std::string(), - from_keyword_provider, 0, false, false, base::string16()); + suggestion, type, + /*subtype_identifier=*/0, + /*match_contents=*/suggestion, + /*match_contents_prefix=*/base::string16(), + /*annotation=*/base::string16(), + /*answer_contents=*/base::string16(), + /*answer_type=*/base::string16(), + /*answer=*/nullptr, + /*suggest_query_params=*/std::string(), + /*deletion_url=*/std::string(), from_keyword_provider, + /*relevance=*/0, + /*relevance_from_server=*/false, + /*should_prefetch=*/false, + /*input_text=*/base::string16()); suggest_result.set_received_after_last_keystroke(false); return CreateSearchSuggestion(nullptr, AutocompleteInput(), from_keyword_provider, suggest_result, @@ -170,7 +181,7 @@ const TemplateURL* template_url = match.GetTemplateURL(client_->GetTemplateURLService(), false); - // This may be NULL if the template corresponding to the keyword has been + // This may be nullptr if the template corresponding to the keyword has been // deleted or there is no keyword set. if (template_url != nullptr) { client_->DeleteMatchingURLsForKeywordFromHistory(template_url->id(),
diff --git a/components/omnibox/browser/base_search_provider_unittest.cc b/components/omnibox/browser/base_search_provider_unittest.cc index ec6d575..19c9ce3 100644 --- a/components/omnibox/browser/base_search_provider_unittest.cc +++ b/components/omnibox/browser/base_search_provider_unittest.cc
@@ -108,18 +108,39 @@ .WillRepeatedly(Return(template_url.get())); SearchSuggestionParser::SuggestResult more_relevant( - query, AutocompleteMatchType::SEARCH_HISTORY, 0, query, base::string16(), - base::string16(), base::string16(), base::string16(), nullptr, - std::string(), std::string(), false, 1300, true, false, query); + query, AutocompleteMatchType::SEARCH_HISTORY, + /*subtype_identifier=*/0, + /*match_contents=*/query, + /*match_contents_prefix=*/base::string16(), + /*annotation=*/base::string16(), + /*answer_contents=*/base::string16(), + /*answer_type=*/base::string16(), + /*answer=*/nullptr, + /*suggest_query_params=*/std::string(), + /*deletion_url=*/std::string(), + /*from_keyword_provider=*/false, + /*relevance=*/1300, + /*relevance_from_server=*/true, + /*should_prefetch=*/false, + /*input_text=*/query); provider_->AddMatchToMap( more_relevant, std::string(), TemplateURLRef::NO_SUGGESTION_CHOSEN, false, false, &map); SearchSuggestionParser::SuggestResult less_relevant( - query, AutocompleteMatchType::SEARCH_SUGGEST, 0, query, base::string16(), - base::string16(), answer_contents, answer_type, - SuggestionAnswer::copy(answer.get()), std::string(), std::string(), false, - 850, true, false, query); + query, AutocompleteMatchType::SEARCH_SUGGEST, + /*subtype_identifier=*/0, + /*match_contents=*/query, + /*match_contents_prefix=*/base::string16(), + /*annotation=*/base::string16(), answer_contents, answer_type, + SuggestionAnswer::copy(answer.get()), + /*suggest_query_params=*/std::string(), + /*deletion_url=*/std::string(), + /*from_keyword_provider=*/false, + /*relevance=*/850, + /*relevance_from_server=*/true, + /*should_prefetch=*/false, + /*input_text=*/query); provider_->AddMatchToMap( less_relevant, std::string(), TemplateURLRef::NO_SUGGESTION_CHOSEN, false, false, &map); @@ -148,10 +169,19 @@ std::unique_ptr<SuggestionAnswer> answer2(new SuggestionAnswer()); answer2->set_type(8242); more_relevant = SearchSuggestionParser::SuggestResult( - query, AutocompleteMatchType::SEARCH_HISTORY, 0, query, base::string16(), - base::string16(), answer_contents2, answer_type2, - SuggestionAnswer::copy(answer2.get()), std::string(), std::string(), - false, 1300, true, false, query); + query, AutocompleteMatchType::SEARCH_HISTORY, + /*subtype_identifier=*/0, + /*match_contents_prefix=*/query, + /*annotation=*/base::string16(), + /*answer_contents=*/base::string16(), answer_contents2, answer_type2, + SuggestionAnswer::copy(answer2.get()), + /*suggest_query_params=*/std::string(), + /*deletion_url=*/std::string(), + /*from_keyword_provider=*/false, + /*relevance=*/1300, + /*relevance_from_server=*/true, + /*should_prefetch=*/false, + /*input_text=*/query); provider_->AddMatchToMap( more_relevant, std::string(), TemplateURLRef::NO_SUGGESTION_CHOSEN, false, false, &map); @@ -193,10 +223,21 @@ base::string16 query = base::ASCIIToUTF16("angeles now"); base::string16 suggestion = base::ASCIIToUTF16("weather los ") + query; SearchSuggestionParser::SuggestResult suggest_result( - suggestion, AutocompleteMatchType::SEARCH_SUGGEST_TAIL, 0, query, - base::ASCIIToUTF16("..."), base::string16(), base::string16(), - base::string16(), nullptr, std::string(), std::string(), false, 1300, - true, false, query); + suggestion, AutocompleteMatchType::SEARCH_SUGGEST_TAIL, + /*subtype_identifier=*/0, + /*match_contents=*/query, + /*match_contents_prefix=*/base::ASCIIToUTF16("..."), + /*annotation=*/base::string16(), + /*answer_contents=*/base::string16(), + /*answer_type=*/base::string16(), + /*answer=*/nullptr, + /*suggest_query_params=*/std::string(), + /*deletion_url=*/std::string(), + /*from_keyword_provider=*/false, + /*relevance=*/1300, + /*relevance_from_server=*/true, + /*should_prefetch=*/false, + /*input_text=*/query); TestBaseSearchProvider::MatchMap map; provider_->AddMatchToMap(suggest_result, std::string(),
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc index 524df8c..d657ed0 100644 --- a/components/omnibox/browser/omnibox_edit_model.cc +++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -645,7 +645,7 @@ popup_open, dropdown_ignored ? 0 : index, !pasted_text.empty(), - -1, // don't yet know tab ID; set later if appropriate + SessionID::InvalidValue(), // don't know tab ID; set later if appropriate ClassifyPage(), elapsed_time_since_user_first_modified_omnibox, match.allowed_to_be_default_match ? match.inline_autocompletion.length() : @@ -664,7 +664,7 @@ // If we know the destination is being opened in the current tab, // we can easily get the tab ID. (If it's being opened in a new // tab, we don't know the tab ID yet.) - log.tab_id = client_->GetSessionID().id(); + log.tab_id = client_->GetSessionID(); } autocomplete_controller()->AddProvidersInfo(&log.providers_info); client_->OnURLOpenedFromOmnibox(&log);
diff --git a/components/omnibox/browser/omnibox_edit_model_unittest.cc b/components/omnibox/browser/omnibox_edit_model_unittest.cc index 0ebd51a..82402773 100644 --- a/components/omnibox/browser/omnibox_edit_model_unittest.cc +++ b/components/omnibox/browser/omnibox_edit_model_unittest.cc
@@ -146,7 +146,8 @@ }; for (size_t i = 0; i < arraysize(input); ++i) { - toolbar_model()->set_text(base::ASCIIToUTF16(input[i].url_for_editing)); + toolbar_model()->set_formatted_full_url( + base::ASCIIToUTF16(input[i].url_for_editing)); model()->ResetDisplayUrls(); model()->SetInputInProgress(input[i].is_match_selected_in_popup);
diff --git a/components/omnibox/browser/omnibox_log.cc b/components/omnibox/browser/omnibox_log.cc index f14ae3c..00c30abd 100644 --- a/components/omnibox/browser/omnibox_log.cc +++ b/components/omnibox/browser/omnibox_log.cc
@@ -11,7 +11,7 @@ bool is_popup_open, size_t selected_index, bool is_paste_and_go, - SessionID::id_type tab_id, + SessionID tab_id, metrics::OmniboxEventProto::PageClassification current_page_classification, base::TimeDelta elapsed_time_since_user_first_modified_omnibox, size_t completed_length,
diff --git a/components/omnibox/browser/omnibox_log.h b/components/omnibox/browser/omnibox_log.h index 7145040b..b281bc5 100644 --- a/components/omnibox/browser/omnibox_log.h +++ b/components/omnibox/browser/omnibox_log.h
@@ -25,7 +25,7 @@ bool is_popup_open, size_t selected_index, bool is_paste_and_go, - SessionID::id_type tab_id, + SessionID tab_id, metrics::OmniboxEventProto::PageClassification current_page_classification, base::TimeDelta elapsed_time_since_user_first_modified_omnibox, @@ -55,9 +55,9 @@ // (The codebase refers to both these types as paste-and-go.) bool is_paste_and_go; - // ID of the tab the selected autocomplete suggestion was opened in. - // Set to -1 if we haven't yet determined the destination tab. - SessionID::id_type tab_id; + // ID of the tab the selected autocomplete suggestion was opened in. Set to + // SessionID::InvalidValue() if we haven't yet determined the destination tab. + SessionID tab_id; // The type of page (e.g., new tab page, regular web page) that the // user was viewing before going somewhere with the omnibox.
diff --git a/components/omnibox/browser/omnibox_metrics_provider.cc b/components/omnibox/browser/omnibox_metrics_provider.cc index 70e50c7..367c6b8 100644 --- a/components/omnibox/browser/omnibox_metrics_provider.cc +++ b/components/omnibox/browser/omnibox_metrics_provider.cc
@@ -122,9 +122,9 @@ OmniboxEventProto* omnibox_event = omnibox_events_cache.add_omnibox_event(); omnibox_event->set_time_sec(metrics::MetricsLog::GetCurrentTime()); - if (log.tab_id != -1) { + if (log.tab_id.is_valid()) { // If we know what tab the autocomplete URL was opened in, log it. - omnibox_event->set_tab_id(log.tab_id); + omnibox_event->set_tab_id(log.tab_id.id()); } omnibox_event->set_typed_length(log.text.length()); omnibox_event->set_just_deleted_text(log.just_deleted_text);
diff --git a/components/prefs/pref_service.h b/components/prefs/pref_service.h index 7b4b8ff..8047b3b1 100644 --- a/components/prefs/pref_service.h +++ b/components/prefs/pref_service.h
@@ -358,7 +358,8 @@ // Pref Stores and profile that we passed to the PrefValueStore. const scoped_refptr<PersistentPrefStore> user_pref_store_; - // Callback to call when a read error occurs. + // Callback to call when a read error occurs. Always invoked on the sequence + // this PrefService was created own. const base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)> read_error_callback_;
diff --git a/components/prefs/pref_service_factory.h b/components/prefs/pref_service_factory.h index 1f59c6a..c4579fb 100644 --- a/components/prefs/pref_service_factory.h +++ b/components/prefs/pref_service_factory.h
@@ -52,8 +52,9 @@ recommended_prefs_.swap(prefs); } - // Sets up error callback for the PrefService. A do-nothing default - // is provided if this is not called. + // Sets up error callback for the PrefService. A do-nothing default is + // provided if this is not called. This callback is always invoked (async or + // not) on the sequence on which Create is invoked. void set_read_error_callback( base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)> read_error_callback) {
diff --git a/components/safe_browsing/base_ping_manager.cc b/components/safe_browsing/base_ping_manager.cc index 2bff3f32..4174206 100644 --- a/components/safe_browsing/base_ping_manager.cc +++ b/components/safe_browsing/base_ping_manager.cc
@@ -6,18 +6,15 @@ #include <utility> -#include "base/base64.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "base/values.h" #include "components/data_use_measurement/core/data_use_user_data.h" #include "content/public/browser/browser_thread.h" #include "google_apis/google_api_keys.h" #include "net/base/escape.h" #include "net/base/load_flags.h" -#include "net/log/net_log_source_type.h" #include "net/traffic_annotation/network_traffic_annotation.h" #include "net/url_request/url_fetcher.h" #include "net/url_request/url_request_context.h" @@ -28,34 +25,6 @@ using content::BrowserThread; namespace { -// Returns a dictionary with "url"=|url-spec| and "data"=|payload| for -// netlogging the start phase of a ping. -std::unique_ptr<base::Value> NetLogPingStartCallback( - const net::NetLogWithSource& net_log, - const GURL& url, - const std::string& payload, - net::NetLogCaptureMode) { - std::unique_ptr<base::DictionaryValue> event_params( - new base::DictionaryValue()); - event_params->SetString("url", url.spec()); - event_params->SetString("payload", payload); - net_log.source().AddToEventParameters(event_params.get()); - return std::move(event_params); -} - -// Returns a dictionary with "url"=|url-spec|, "status"=|status| and -// "error"=|error| for netlogging the end phase of a ping. -std::unique_ptr<base::Value> NetLogPingEndCallback( - const net::NetLogWithSource& net_log, - const net::URLRequestStatus& status, - net::NetLogCaptureMode) { - std::unique_ptr<base::DictionaryValue> event_params( - new base::DictionaryValue()); - event_params->SetInteger("status", status.status()); - event_params->SetInteger("error", status.error()); - net_log.source().AddToEventParameters(event_params.get()); - return std::move(event_params); -} net::NetworkTrafficAnnotationTag kTrafficAnnotation = net::DefineNetworkTrafficAnnotation("safe_browsing_extended_reporting", @@ -116,12 +85,6 @@ url_prefix_(config.url_prefix) { DCHECK(!url_prefix_.empty()); - if (request_context_getter) { - net_log_ = net::NetLogWithSource::Make( - request_context_getter->GetURLRequestContext()->net_log(), - net::NetLogSourceType::SAFE_BROWSING); - } - version_ = ProtocolManagerHelper::Version(); } @@ -131,9 +94,6 @@ // All SafeBrowsing request responses are handled here. void BasePingManager::OnURLFetchComplete(const net::URLFetcher* source) { - net_log_.EndEvent( - net::NetLogEventType::SAFE_BROWSING_PING, - base::Bind(&NetLogPingEndCallback, net_log_, source->GetStatus())); auto it = std::find_if(safebrowsing_reports_.begin(), safebrowsing_reports_.end(), [source](const std::unique_ptr<net::URLFetcher>& ptr) { @@ -157,16 +117,8 @@ report, data_use_measurement::DataUseUserData::SAFE_BROWSING); report_ptr->SetLoadFlags(net::LOAD_DISABLE_CACHE); report_ptr->SetRequestContext(request_context_getter_.get()); - std::string post_data_base64; - if (!hit_report.post_data.empty()) { + if (!hit_report.post_data.empty()) report_ptr->SetUploadData("text/plain", hit_report.post_data); - base::Base64Encode(hit_report.post_data, &post_data_base64); - } - - net_log_.BeginEvent( - net::NetLogEventType::SAFE_BROWSING_PING, - base::Bind(&NetLogPingStartCallback, net_log_, - report_ptr->GetOriginalURL(), post_data_base64)); report->Start(); safebrowsing_reports_.insert(std::move(report_ptr)); @@ -185,12 +137,6 @@ // Don't try too hard to send reports on failures. fetcher->SetAutomaticallyRetryOn5xx(false); - std::string report_base64; - base::Base64Encode(report, &report_base64); - net_log_.BeginEvent(net::NetLogEventType::SAFE_BROWSING_PING, - base::Bind(&NetLogPingStartCallback, net_log_, - fetcher->GetOriginalURL(), report_base64)); - fetcher->Start(); safebrowsing_reports_.insert(std::move(fetcher)); }
diff --git a/components/safe_browsing/base_ping_manager.h b/components/safe_browsing/base_ping_manager.h index 5b64c30..16169bcd 100644 --- a/components/safe_browsing/base_ping_manager.h +++ b/components/safe_browsing/base_ping_manager.h
@@ -18,7 +18,6 @@ #include "components/safe_browsing/db/hit_report.h" #include "components/safe_browsing/db/util.h" #include "content/public/browser/permission_type.h" -#include "net/log/net_log_with_source.h" #include "net/url_request/url_fetcher_delegate.h" #include "url/gurl.h" @@ -87,8 +86,6 @@ // We add both "hit" and "detail" fetchers in this set. Reports safebrowsing_reports_; - net::NetLogWithSource net_log_; - DISALLOW_COPY_AND_ASSIGN(BasePingManager); };
diff --git a/components/safe_browsing/base_ping_manager_unittest.cc b/components/safe_browsing/base_ping_manager_unittest.cc index 7a197ff..2dfcd5d 100644 --- a/components/safe_browsing/base_ping_manager_unittest.cc +++ b/components/safe_browsing/base_ping_manager_unittest.cc
@@ -12,10 +12,6 @@ #include "base/values.h" #include "google_apis/google_api_keys.h" #include "net/base/escape.h" -#include "net/log/net_log.h" -#include "net/log/net_log_source_type.h" -#include "net/log/test_net_log.h" -#include "net/log/test_net_log_entry.h" #include "net/url_request/report_sender.h" #include "net/url_request/test_url_fetcher_factory.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,10 +29,7 @@ class BasePingManagerTest : public testing::Test { public: - BasePingManagerTest() : net_log_(new net::TestNetLog()) { - net_log_with_source_ = net::NetLogWithSource::Make( - net_log_.get(), net::NetLogSourceType::SAFE_BROWSING); - } + BasePingManagerTest() {} protected: void SetUp() override { @@ -51,14 +44,11 @@ config.url_prefix = kUrlPrefix; ping_manager_.reset(new BasePingManager(nullptr, config)); ping_manager_->version_ = kAppVer; - ping_manager_->net_log_ = net_log_with_source_; } BasePingManager* ping_manager() { return ping_manager_.get(); } std::string key_param_; - std::unique_ptr<net::TestNetLog> net_log_; - net::NetLogWithSource net_log_with_source_; net::TestURLFetcherFactory fetcher_factory_; std::unique_ptr<BasePingManager> ping_manager_; }; @@ -206,126 +196,4 @@ ping_manager()->ThreatDetailsUrl().spec()); } -TEST_F(BasePingManagerTest, TestReportThreatDetails) { - const std::string kThreatDetailsReportString = "Threat Details Report String"; - std::string encoded_threat_report = ""; - base::Base64Encode(kThreatDetailsReportString, &encoded_threat_report); - std::string expected_threat_details_url = - ping_manager()->ThreatDetailsUrl().spec(); - const int kRequestErrorCode = -123; - - // Start the report. - ping_manager()->ReportThreatDetails(kThreatDetailsReportString); - - net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0); - DCHECK(fetcher); - // Set some error response data on the fetcher to make things interesting. - fetcher->set_status( - net::URLRequestStatus(net::URLRequestStatus::FAILED, kRequestErrorCode)); - // Tell the test fetcher to invoke the fetch callback. - fetcher->delegate()->OnURLFetchComplete(fetcher); - - // We expect two net log entries: one when the ping starts, one when it ends. - net::TestNetLogEntry::List entries; - net_log_->GetEntries(&entries); - ASSERT_EQ(2u, entries.size()); - - // Check for expected log entries for the begin phase. - const net::TestNetLogEntry& start_entry = entries[0]; - ASSERT_EQ(3u, start_entry.params->size()); - - std::string string_value; - EXPECT_TRUE(start_entry.GetStringValue("url", &string_value)); - EXPECT_EQ(expected_threat_details_url, string_value); - - EXPECT_TRUE(start_entry.GetStringValue("payload", &string_value)); - EXPECT_EQ(encoded_threat_report, string_value); - - // We don't really care what the source_dependency value is, just making sure - // it's there. - EXPECT_TRUE(start_entry.params->HasKey("source_dependency")); - - // Check for expected log entries for the end phase. - const net::TestNetLogEntry& end_entry = entries[1]; - ASSERT_EQ(3u, end_entry.params->size()); - - int int_value; - EXPECT_TRUE(end_entry.GetIntegerValue("status", &int_value)); - EXPECT_EQ(net::URLRequestStatus::FAILED, int_value); - - EXPECT_TRUE(end_entry.GetIntegerValue("error", &int_value)); - EXPECT_EQ(kRequestErrorCode, int_value); - - // We don't really care what the source_dependency value is, just making sure - // it's there. - EXPECT_TRUE(end_entry.params->HasKey("source_dependency")); -} - -TEST_F(BasePingManagerTest, TestReportSafeBrowsingHit) { - const std::string kHitReportPostData = "Hit Report POST Data"; - std::string encoded_post_data = ""; - base::Base64Encode(kHitReportPostData, &encoded_post_data); - - HitReport hp; - hp.malicious_url = GURL("http://malicious.url.com"); - hp.page_url = GURL("http://page.url.com"); - hp.referrer_url = GURL("http://referrer.url.com"); - hp.threat_type = SB_THREAT_TYPE_URL_CLIENT_SIDE_MALWARE; - hp.threat_source = ThreatSource::LOCAL_PVER4; - hp.extended_reporting_level = SBER_LEVEL_OFF; - hp.is_metrics_reporting_active = false; - hp.is_subresource = true; - hp.population_id = "foo bar"; - hp.post_data = kHitReportPostData; - std::string expected_hit_report_url = - ping_manager()->SafeBrowsingHitUrl(hp).spec(); - const int kRequestErrorCode = -321; - - // Start the report. - ping_manager()->ReportSafeBrowsingHit(hp); - - net::TestURLFetcher* fetcher = fetcher_factory_.GetFetcherByID(0); - DCHECK(fetcher); - // Set some error response data on the fetcher to make things interesting. - fetcher->set_status( - net::URLRequestStatus(net::URLRequestStatus::FAILED, kRequestErrorCode)); - // Tell the test fetcher to invoke the fetch callback. - fetcher->delegate()->OnURLFetchComplete(fetcher); - - // We expect two net log entries: one when the ping starts, one when it ends. - net::TestNetLogEntry::List entries; - net_log_->GetEntries(&entries); - ASSERT_EQ(2u, entries.size()); - - // Check for expected log entries for the begin phase. - const net::TestNetLogEntry& start_entry = entries[0]; - ASSERT_EQ(3u, start_entry.params->size()); - - std::string string_value; - EXPECT_TRUE(start_entry.GetStringValue("url", &string_value)); - EXPECT_EQ(expected_hit_report_url, string_value); - - EXPECT_TRUE(start_entry.GetStringValue("payload", &string_value)); - EXPECT_EQ(encoded_post_data, string_value); - - // We don't really care what the source_dependency value is, just making sure - // it's there. - EXPECT_TRUE(start_entry.params->HasKey("source_dependency")); - - // Check for expected log entries for the end phase. - const net::TestNetLogEntry& end_entry = entries[1]; - ASSERT_EQ(3u, end_entry.params->size()); - - int int_value; - EXPECT_TRUE(end_entry.GetIntegerValue("status", &int_value)); - EXPECT_EQ(net::URLRequestStatus::FAILED, int_value); - - EXPECT_TRUE(end_entry.GetIntegerValue("error", &int_value)); - EXPECT_EQ(kRequestErrorCode, int_value); - - // We don't really care what the source_dependency value is, just making sure - // it's there. - EXPECT_TRUE(end_entry.params->HasKey("source_dependency")); -} - } // namespace safe_browsing
diff --git a/components/safe_browsing/password_protection/BUILD.gn b/components/safe_browsing/password_protection/BUILD.gn index e34a2e1..f898a91 100644 --- a/components/safe_browsing/password_protection/BUILD.gn +++ b/components/safe_browsing/password_protection/BUILD.gn
@@ -29,6 +29,7 @@ "//components/safe_browsing/db:database_manager", "//components/safe_browsing/db:v4_protocol_manager_util", "//components/safe_browsing/db:whitelist_checker_client", + "//components/sessions", "//content/public/browser:browser", "//net:net", "//third_party/protobuf:protobuf_lite",
diff --git a/components/safe_browsing/password_protection/DEPS b/components/safe_browsing/password_protection/DEPS index c09e58fd..41ce05c 100644 --- a/components/safe_browsing/password_protection/DEPS +++ b/components/safe_browsing/password_protection/DEPS
@@ -2,6 +2,7 @@ "+components/content_settings/core/browser", "+components/history/core/browser", "+components/password_manager/core/browser/password_reuse_detector.h", + "+components/sessions", "+components/sync_preferences/testing_pref_service_syncable.h", "+content/public/test", "+net",
diff --git a/components/safe_browsing/password_protection/password_protection_request.cc b/components/safe_browsing/password_protection/password_protection_request.cc index 13be5a6..903784f 100644 --- a/components/safe_browsing/password_protection/password_protection_request.cc +++ b/components/safe_browsing/password_protection/password_protection_request.cc
@@ -149,7 +149,7 @@ main_frame->set_url(main_frame_url_.spec()); main_frame->set_frame_index(0 /* main frame */); password_protection_service_->FillReferrerChain( - main_frame_url_, -1 /* tab id not available */, main_frame); + main_frame_url_, SessionID::InvalidValue(), main_frame); bool clicked_through_interstitial = password_protection_service_->UserClickedThroughSBInterstitial( web_contents_);
diff --git a/components/safe_browsing/password_protection/password_protection_service.h b/components/safe_browsing/password_protection/password_protection_service.h index 57bc6de..b4ae0a3 100644 --- a/components/safe_browsing/password_protection/password_protection_service.h +++ b/components/safe_browsing/password_protection/password_protection_service.h
@@ -21,6 +21,7 @@ #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/safe_browsing/db/v4_protocol_manager_util.h" #include "components/safe_browsing/proto/csd.pb.h" +#include "components/sessions/core/session_id.h" #include "services/network/public/cpp/shared_url_loader_factory.h" #include "third_party/protobuf/src/google/protobuf/repeated_field.h" @@ -282,7 +283,8 @@ // info into |frame|. virtual void FillReferrerChain( const GURL& event_url, - int event_tab_id, // -1 if tab id is not available. + SessionID + event_tab_id, // SessionID::InvalidValue() if tab not available. LoginReputationClientRequest::Frame* frame) = 0; void FillUserPopulation(
diff --git a/components/safe_browsing/password_protection/password_protection_service_unittest.cc b/components/safe_browsing/password_protection/password_protection_service_unittest.cc index e5da260..3db8e9e 100644 --- a/components/safe_browsing/password_protection/password_protection_service_unittest.cc +++ b/components/safe_browsing/password_protection/password_protection_service_unittest.cc
@@ -143,7 +143,9 @@ } MOCK_METHOD3(FillReferrerChain, - void(const GURL&, int, LoginReputationClientRequest::Frame*)); + void(const GURL&, + SessionID, + LoginReputationClientRequest::Frame*)); MOCK_METHOD1(MaybeLogPasswordReuseDetectedEvent, void(content::WebContents*)); MOCK_METHOD2(ShowModalWarning, void(content::WebContents*, const std::string&));
diff --git a/components/services/heap_profiling/BUILD.gn b/components/services/heap_profiling/BUILD.gn new file mode 100644 index 0000000..16f128c --- /dev/null +++ b/components/services/heap_profiling/BUILD.gn
@@ -0,0 +1,76 @@ +# Copyright 2017 The Chromium 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/service_manager/public/cpp/service.gni") +import("//services/service_manager/public/service_manifest.gni") +import("//testing/libfuzzer/fuzzer_test.gni") + +static_library("heap_profiling") { + sources = [ + "address.h", + "allocation_event.cc", + "allocation_event.h", + "allocation_tracker.cc", + "allocation_tracker.h", + "backtrace.cc", + "backtrace.h", + "backtrace_storage.cc", + "backtrace_storage.h", + "connection_manager.cc", + "connection_manager.h", + "heap_profiling_service.cc", + "heap_profiling_service.h", + "json_exporter.cc", + "json_exporter.h", + "receiver.h", + "receiver_pipe.cc", + "receiver_pipe.h", + "receiver_pipe_posix.cc", + "receiver_pipe_posix.h", + "receiver_pipe_win.cc", + "receiver_pipe_win.h", + "stream_parser.cc", + "stream_parser.h", + "stream_receiver.h", + ] + + deps = [ + "//base", + "//components/services/heap_profiling/public/cpp", + "//mojo/edk", + "//services/resource_coordinator/public/cpp:resource_coordinator_cpp", + "//third_party/zlib", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ + "backtrace_storage_unittest.cc", + "json_exporter_unittest.cc", + "stream_parser_unittest.cc", + ] + deps = [ + ":heap_profiling", + "//base", + "//services/resource_coordinator/public/cpp:resource_coordinator_cpp", + "//testing/gtest", + ] +} + +service_manifest("manifest") { + name = "heap_profiling" + source = "heap_profiling_manifest.json" +} + +fuzzer_test("profiling_fuzzer") { + sources = [ + "stream_fuzzer.cc", + ] + deps = [ + ":heap_profiling", + ] + libfuzzer_options = [ "max_len = 64000" ] + dict = "stream_fuzzer.dict" +}
diff --git a/chrome/profiling/DEPS b/components/services/heap_profiling/DEPS similarity index 70% rename from chrome/profiling/DEPS rename to components/services/heap_profiling/DEPS index b45205cc..6973709 100644 --- a/chrome/profiling/DEPS +++ b/components/services/heap_profiling/DEPS
@@ -1,8 +1,6 @@ include_rules = [ "+components/services/heap_profiling/public", - "+content/public/child", "+mojo/edk/embedder", "+services/resource_coordinator/public", - "+services/service_manager/public/cpp", "+third_party/zlib/zlib.h", ]
diff --git a/components/services/heap_profiling/OWNERS b/components/services/heap_profiling/OWNERS index 987c0c88..80cbc1b 100644 --- a/components/services/heap_profiling/OWNERS +++ b/components/services/heap_profiling/OWNERS
@@ -1 +1,4 @@ erikchen@chromium.org + +per-file heap_profiling_manifest.json=set noparent +per-file heap_profiling_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chrome/profiling/address.h b/components/services/heap_profiling/address.h similarity index 91% rename from chrome/profiling/address.h rename to components/services/heap_profiling/address.h index 9a78e1d..4b1b9e4 100644 --- a/chrome/profiling/address.h +++ b/components/services/heap_profiling/address.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_ADDRESS_H_ -#define CHROME_PROFILING_ADDRESS_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_ADDRESS_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_ADDRESS_H_ #include <stdint.h> @@ -62,4 +62,4 @@ } // namespace std -#endif // CHROME_PROFILING_ADDRESS_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_ADDRESS_H_
diff --git a/chrome/profiling/allocation_event.cc b/components/services/heap_profiling/allocation_event.cc similarity index 92% rename from chrome/profiling/allocation_event.cc rename to components/services/heap_profiling/allocation_event.cc index d8d3c95..a1f283eb 100644 --- a/chrome/profiling/allocation_event.cc +++ b/components/services/heap_profiling/allocation_event.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/allocation_event.h" +#include "components/services/heap_profiling/allocation_event.h" namespace profiling {
diff --git a/chrome/profiling/allocation_event.h b/components/services/heap_profiling/allocation_event.h similarity index 91% rename from chrome/profiling/allocation_event.h rename to components/services/heap_profiling/allocation_event.h index b9225b1..b923d769 100644 --- a/chrome/profiling/allocation_event.h +++ b/components/services/heap_profiling/allocation_event.h
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_ALLOCATION_EVENT_H_ -#define CHROME_PROFILING_ALLOCATION_EVENT_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_ALLOCATION_EVENT_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_ALLOCATION_EVENT_H_ #include <functional> #include <map> #include <unordered_set> -#include "chrome/profiling/address.h" -#include "chrome/profiling/backtrace_storage.h" +#include "components/services/heap_profiling/address.h" +#include "components/services/heap_profiling/backtrace_storage.h" #include "components/services/heap_profiling/public/cpp/stream.h" namespace profiling { @@ -100,4 +100,4 @@ } // namespace profiling -#endif // CHROME_PROFILING_ALLOCATION_EVENT_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_ALLOCATION_EVENT_H_
diff --git a/chrome/profiling/allocation_tracker.cc b/components/services/heap_profiling/allocation_tracker.cc similarity index 96% rename from chrome/profiling/allocation_tracker.cc rename to components/services/heap_profiling/allocation_tracker.cc index 2f7914c..b29624a 100644 --- a/chrome/profiling/allocation_tracker.cc +++ b/components/services/heap_profiling/allocation_tracker.cc
@@ -2,12 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/allocation_tracker.h" +#include "components/services/heap_profiling/allocation_tracker.h" #include "base/callback.h" #include "base/json/string_escape.h" #include "base/threading/thread_task_runner_handle.h" -#include "chrome/profiling/backtrace_storage.h" +#include "components/services/heap_profiling/backtrace_storage.h" namespace profiling {
diff --git a/chrome/profiling/allocation_tracker.h b/components/services/heap_profiling/allocation_tracker.h similarity index 89% rename from chrome/profiling/allocation_tracker.h rename to components/services/heap_profiling/allocation_tracker.h index bdb25e0..26604fd3 100644 --- a/chrome/profiling/allocation_tracker.h +++ b/components/services/heap_profiling/allocation_tracker.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_ALLOCATION_TRACKER_H_ -#define CHROME_PROFILING_ALLOCATION_TRACKER_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_ALLOCATION_TRACKER_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_ALLOCATION_TRACKER_H_ #include <map> #include <unordered_map> @@ -12,9 +12,9 @@ #include "base/macros.h" #include "base/sequenced_task_runner.h" #include "base/synchronization/lock.h" -#include "chrome/profiling/allocation_event.h" -#include "chrome/profiling/backtrace_storage.h" -#include "chrome/profiling/memlog_receiver.h" +#include "components/services/heap_profiling/allocation_event.h" +#include "components/services/heap_profiling/backtrace_storage.h" +#include "components/services/heap_profiling/receiver.h" namespace profiling { @@ -22,7 +22,7 @@ // allocation register and needs to be merged/deduped. // // This class is not threadsafe except as noted. -class AllocationTracker : public MemlogReceiver { +class AllocationTracker : public Receiver { public: using CompleteCallback = base::OnceClosure; using ContextMap = std::map<std::string, int>; @@ -95,4 +95,4 @@ } // namespace profiling -#endif // CHROME_PROFILING_ALLOCATION_TRACKER_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_ALLOCATION_TRACKER_H_
diff --git a/chrome/profiling/backtrace.cc b/components/services/heap_profiling/backtrace.cc similarity index 90% rename from chrome/profiling/backtrace.cc rename to components/services/heap_profiling/backtrace.cc index 406f6a4..6f9e24b 100644 --- a/chrome/profiling/backtrace.cc +++ b/components/services/heap_profiling/backtrace.cc
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/backtrace.h" +#include "components/services/heap_profiling/backtrace.h" #include <string.h> #include <algorithm> #include "base/hash.h" -#include "chrome/profiling/backtrace_storage.h" +#include "components/services/heap_profiling/backtrace_storage.h" namespace profiling {
diff --git a/chrome/profiling/backtrace.h b/components/services/heap_profiling/backtrace.h similarity index 90% rename from chrome/profiling/backtrace.h rename to components/services/heap_profiling/backtrace.h index c724786..10b8a31 100644 --- a/chrome/profiling/backtrace.h +++ b/components/services/heap_profiling/backtrace.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_BACKTRACE_H_ -#define CHROME_PROFILING_BACKTRACE_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_BACKTRACE_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_BACKTRACE_H_ #include <functional> #include <vector> #include "base/macros.h" -#include "chrome/profiling/address.h" +#include "components/services/heap_profiling/address.h" namespace profiling { @@ -75,4 +75,4 @@ } // namespace std -#endif // CHROME_PROFILING_BACKTRACE_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_BACKTRACE_H_
diff --git a/chrome/profiling/backtrace_storage.cc b/components/services/heap_profiling/backtrace_storage.cc similarity index 96% rename from chrome/profiling/backtrace_storage.cc rename to components/services/heap_profiling/backtrace_storage.cc index c23e8b4c..789de6ba 100644 --- a/chrome/profiling/backtrace_storage.cc +++ b/components/services/heap_profiling/backtrace_storage.cc
@@ -2,10 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/backtrace_storage.h" +#include "components/services/heap_profiling/backtrace_storage.h" #include "base/logging.h" -#include "chrome/profiling/backtrace.h" +#include "components/services/heap_profiling/backtrace.h" namespace profiling {
diff --git a/chrome/profiling/backtrace_storage.h b/components/services/heap_profiling/backtrace_storage.h similarity index 92% rename from chrome/profiling/backtrace_storage.h rename to components/services/heap_profiling/backtrace_storage.h index d4c65ed..540f214a 100644 --- a/chrome/profiling/backtrace_storage.h +++ b/components/services/heap_profiling/backtrace_storage.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_BACKTRACE_STORAGE_H_ -#define CHROME_PROFILING_BACKTRACE_STORAGE_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_BACKTRACE_STORAGE_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_BACKTRACE_STORAGE_H_ #include <unordered_set> #include <vector> @@ -11,7 +11,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/synchronization/lock.h" -#include "chrome/profiling/backtrace.h" +#include "components/services/heap_profiling/backtrace.h" namespace profiling { @@ -104,4 +104,4 @@ } // namespace profiling -#endif // CHROME_PROFILING_BACKTRACE_STORAGE_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_BACKTRACE_STORAGE_H_
diff --git a/chrome/profiling/backtrace_storage_unittest.cc b/components/services/heap_profiling/backtrace_storage_unittest.cc similarity index 93% rename from chrome/profiling/backtrace_storage_unittest.cc rename to components/services/heap_profiling/backtrace_storage_unittest.cc index 40e54c1f..4ed9828 100644 --- a/chrome/profiling/backtrace_storage_unittest.cc +++ b/components/services/heap_profiling/backtrace_storage_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/backtrace_storage.h" +#include "components/services/heap_profiling/backtrace_storage.h" #include <vector>
diff --git a/chrome/profiling/memlog_connection_manager.cc b/components/services/heap_profiling/connection_manager.cc similarity index 82% rename from chrome/profiling/memlog_connection_manager.cc rename to components/services/heap_profiling/connection_manager.cc index f3404e3..5f90017 100644 --- a/chrome/profiling/memlog_connection_manager.cc +++ b/components/services/heap_profiling/connection_manager.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/memlog_connection_manager.h" +#include "components/services/heap_profiling/connection_manager.h" #include "base/bind.h" #include "base/memory/ptr_util.h" @@ -11,11 +11,11 @@ #include "base/strings/stringprintf.h" #include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/thread.h" -#include "chrome/profiling/allocation_tracker.h" -#include "chrome/profiling/json_exporter.h" -#include "chrome/profiling/memlog_receiver_pipe.h" -#include "chrome/profiling/memlog_stream_parser.h" +#include "components/services/heap_profiling/allocation_tracker.h" +#include "components/services/heap_profiling/json_exporter.h" #include "components/services/heap_profiling/public/cpp/client.h" +#include "components/services/heap_profiling/receiver_pipe.h" +#include "components/services/heap_profiling/stream_parser.h" #include "mojo/public/cpp/system/buffer.h" #include "mojo/public/cpp/system/platform_handle.h" #include "third_party/zlib/zlib.h" @@ -31,10 +31,10 @@ const size_t kMinCountThreshold = 1024; } // namespace -MemlogConnectionManager::DumpArgs::DumpArgs() = default; -MemlogConnectionManager::DumpArgs::DumpArgs(DumpArgs&& other) noexcept +ConnectionManager::DumpArgs::DumpArgs() = default; +ConnectionManager::DumpArgs::DumpArgs(DumpArgs&& other) noexcept : backtrace_storage_lock(std::move(other.backtrace_storage_lock)) {} -MemlogConnectionManager::DumpArgs::~DumpArgs() = default; +ConnectionManager::DumpArgs::~DumpArgs() = default; // Tracking information for DumpProcessForTracing(). This struct is // refcounted since there will be many background thread calls (one for each @@ -43,8 +43,8 @@ // // This class is not threadsafe, its members must only be accessed on the // I/O thread. -struct MemlogConnectionManager::DumpProcessesForTracingTracking - : public MemlogConnectionManager::DumpArgs, +struct ConnectionManager::DumpProcessesForTracingTracking + : public ConnectionManager::DumpArgs, public base::RefCountedThreadSafe<DumpProcessesForTracingTracking> { DumpProcessesForTracingTracking() = default; @@ -66,12 +66,12 @@ virtual ~DumpProcessesForTracingTracking() = default; }; -struct MemlogConnectionManager::Connection { +struct ConnectionManager::Connection { Connection(AllocationTracker::CompleteCallback complete_cb, BacktraceStorage* backtrace_storage, base::ProcessId pid, mojom::ProfilingClientPtr client, - scoped_refptr<MemlogReceiverPipe> p, + scoped_refptr<ReceiverPipe> p, mojom::ProcessType process_type, uint32_t sampling_rate, mojom::StackMode stack_mode) @@ -99,8 +99,8 @@ base::Thread thread; mojom::ProfilingClientPtr client; - scoped_refptr<MemlogReceiverPipe> pipe; - scoped_refptr<MemlogStreamParser> parser; + scoped_refptr<ReceiverPipe> pipe; + scoped_refptr<StreamParser> parser; mojom::ProcessType process_type; mojom::StackMode stack_mode; @@ -117,21 +117,20 @@ uint32_t sampling_rate = 1; }; -MemlogConnectionManager::MemlogConnectionManager() +ConnectionManager::ConnectionManager() : blocking_thread_("Blocking thread"), weak_factory_(this) { blocking_thread_.Start(); - metrics_timer_.Start(FROM_HERE, base::TimeDelta::FromHours(24), - base::Bind(&MemlogConnectionManager::ReportMetrics, - base::Unretained(this))); + metrics_timer_.Start( + FROM_HERE, base::TimeDelta::FromHours(24), + base::Bind(&ConnectionManager::ReportMetrics, base::Unretained(this))); } -MemlogConnectionManager::~MemlogConnectionManager() = default; +ConnectionManager::~ConnectionManager() = default; -void MemlogConnectionManager::OnNewConnection( - base::ProcessId pid, - mojom::ProfilingClientPtr client, - mojo::ScopedHandle receiver_pipe_end, - mojom::ProcessType process_type, - mojom::ProfilingParamsPtr params) { +void ConnectionManager::OnNewConnection(base::ProcessId pid, + mojom::ProfilingClientPtr client, + mojo::ScopedHandle receiver_pipe_end, + mojom::ProcessType process_type, + mojom::ProfilingParamsPtr params) { base::AutoLock lock(connections_lock_); // Attempting to start profiling on an already profiled processs should have @@ -142,7 +141,7 @@ // It's theoretically possible that we started profiling a process, the // profiling was stopped [e.g. by hitting the 10-s timeout], and then we tried // to start profiling again. The ProfilingClient will refuse to start again. - // But the MemlogConnectionManager will not be able to distinguish this + // But the ConnectionManager will not be able to distinguish this // never-started ProfilingClient from a brand new ProfilingClient that happens // to share the same pid. This is a rare condition which should only happen // when the user is attempting to manually start profiling for processes, so @@ -151,14 +150,14 @@ base::PlatformFile receiver_handle; CHECK_EQ(MOJO_RESULT_OK, mojo::UnwrapPlatformFile( std::move(receiver_pipe_end), &receiver_handle)); - scoped_refptr<MemlogReceiverPipe> new_pipe = - new MemlogReceiverPipe(mojo::edk::ScopedPlatformHandle( + scoped_refptr<ReceiverPipe> new_pipe = + new ReceiverPipe(mojo::edk::ScopedPlatformHandle( mojo::edk::PlatformHandle(receiver_handle))); // The allocation tracker will call this on a background thread, so thunk // back to the current thread with weak pointers. AllocationTracker::CompleteCallback complete_cb = - base::BindOnce(&MemlogConnectionManager::OnConnectionCompleteThunk, + base::BindOnce(&ConnectionManager::OnConnectionCompleteThunk, base::MessageLoop::current()->task_runner(), weak_factory_.GetWeakPtr(), pid); @@ -170,12 +169,11 @@ options.message_loop_type = base::MessageLoop::TYPE_IO; connection->thread.StartWithOptions(options); - connection->parser = new MemlogStreamParser(&connection->tracker); + connection->parser = new StreamParser(&connection->tracker); new_pipe->SetReceiver(connection->thread.task_runner(), connection->parser); connection->thread.task_runner()->PostTask( - FROM_HERE, - base::Bind(&MemlogReceiverPipe::StartReadingOnIOThread, new_pipe)); + FROM_HERE, base::Bind(&ReceiverPipe::StartReadingOnIOThread, new_pipe)); // Request the client start sending us data. connection->client->StartProfiling(std::move(params)); @@ -183,7 +181,7 @@ connections_[pid] = std::move(connection); // Transfers ownership. } -std::vector<base::ProcessId> MemlogConnectionManager::GetConnectionPids() { +std::vector<base::ProcessId> ConnectionManager::GetConnectionPids() { base::AutoLock lock(connections_lock_); std::vector<base::ProcessId> results; results.reserve(connections_.size()); @@ -194,7 +192,7 @@ } std::vector<base::ProcessId> -MemlogConnectionManager::GetConnectionPidsThatNeedVmRegions() { +ConnectionManager::GetConnectionPidsThatNeedVmRegions() { base::AutoLock lock(connections_lock_); std::vector<base::ProcessId> results; results.reserve(connections_.size()); @@ -205,14 +203,14 @@ return results; } -void MemlogConnectionManager::OnConnectionComplete(base::ProcessId pid) { +void ConnectionManager::OnConnectionComplete(base::ProcessId pid) { base::AutoLock lock(connections_lock_); auto found = connections_.find(pid); CHECK(found != connections_.end()); connections_.erase(found); } -void MemlogConnectionManager::ReportMetrics() { +void ConnectionManager::ReportMetrics() { base::AutoLock lock(connections_lock_); for (auto& pair : connections_) { UMA_HISTOGRAM_ENUMERATION( @@ -223,16 +221,16 @@ } // static -void MemlogConnectionManager::OnConnectionCompleteThunk( +void ConnectionManager::OnConnectionCompleteThunk( scoped_refptr<base::SequencedTaskRunner> task_runner, - base::WeakPtr<MemlogConnectionManager> connection_manager, + base::WeakPtr<ConnectionManager> connection_manager, base::ProcessId pid) { - task_runner->PostTask( - FROM_HERE, base::BindOnce(&MemlogConnectionManager::OnConnectionComplete, - connection_manager, pid)); + task_runner->PostTask(FROM_HERE, + base::BindOnce(&ConnectionManager::OnConnectionComplete, + connection_manager, pid)); } -void MemlogConnectionManager::DumpProcessesForTracing( +void ConnectionManager::DumpProcessesForTracing( bool keep_small_allocations, bool strip_path_from_mapped_files, DumpProcessesForTracingCallback callback, @@ -267,7 +265,7 @@ // need to thunk back to the I/O thread. connection->tracker.SnapshotOnBarrier( barrier_id, task_runner, - base::BindOnce(&MemlogConnectionManager::DoDumpOneProcessForTracing, + base::BindOnce(&ConnectionManager::DoDumpOneProcessForTracing, weak_factory_.GetWeakPtr(), tracking, pid, connection->process_type, keep_small_allocations, strip_path_from_mapped_files, @@ -276,7 +274,7 @@ } } -void MemlogConnectionManager::DoDumpOneProcessForTracing( +void ConnectionManager::DoDumpOneProcessForTracing( scoped_refptr<DumpProcessesForTracingTracking> tracking, base::ProcessId pid, mojom::ProcessType process_type,
diff --git a/chrome/profiling/memlog_connection_manager.h b/components/services/heap_profiling/connection_manager.h similarity index 85% rename from chrome/profiling/memlog_connection_manager.h rename to components/services/heap_profiling/connection_manager.h index 40931b05..33886cd 100644 --- a/chrome/profiling/memlog_connection_manager.h +++ b/components/services/heap_profiling/connection_manager.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_MEMLOG_CONNECTION_MANAGER_H_ -#define CHROME_PROFILING_MEMLOG_CONNECTION_MANAGER_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_CONNECTION_MANAGER_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_CONNECTION_MANAGER_H_ #include <string> #include <vector> @@ -17,9 +17,9 @@ #include "base/threading/thread.h" #include "base/values.h" #include "build/build_config.h" -#include "chrome/profiling/allocation_event.h" -#include "chrome/profiling/allocation_tracker.h" -#include "chrome/profiling/backtrace_storage.h" +#include "components/services/heap_profiling/allocation_event.h" +#include "components/services/heap_profiling/allocation_tracker.h" +#include "components/services/heap_profiling/backtrace_storage.h" #include "components/services/heap_profiling/public/mojom/heap_profiling_service.mojom.h" #include "mojo/edk/embedder/scoped_platform_handle.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" @@ -39,17 +39,17 @@ // Manages all connections and logging for each process. Pipes are supplied by // the pipe server and this class will connect them to a parser and logger. // -// Note |backtrace_storage| must outlive MemlogConnectionManager. +// Note |backtrace_storage| must outlive ConnectionManager. // // This object is constructed on the UI thread, but the rest of the usage // (including deletion) is on the IO thread. -class MemlogConnectionManager { +class ConnectionManager { using DumpProcessesForTracingCallback = memory_instrumentation::mojom:: HeapProfiler::DumpProcessesForTracingCallback; public: - MemlogConnectionManager(); - ~MemlogConnectionManager(); + ConnectionManager(); + ~ConnectionManager(); // Shared types for the dump-type-specific args structures. struct DumpArgs { @@ -58,7 +58,7 @@ ~DumpArgs(); private: - friend MemlogConnectionManager; + friend ConnectionManager; // This lock keeps the backtrace atoms alive throughout the dumping // process. It will be initialized by DumpProcess. @@ -112,7 +112,7 @@ // These thunks post the request back to the given thread. static void OnConnectionCompleteThunk( scoped_refptr<base::SequencedTaskRunner> main_loop, - base::WeakPtr<MemlogConnectionManager> connection_manager, + base::WeakPtr<ConnectionManager> connection_manager, base::ProcessId process_id); BacktraceStorage backtrace_storage_; @@ -134,16 +134,15 @@ // To avoid deadlock, synchronous calls to the browser are made on a dedicated // thread that does nothing else. Both the IO thread and connection-specific // threads could potentially be processing messages from the browser process, - // which in turn could be blocked on sending more messages over the memlog - // pipe. + // which in turn could be blocked on sending more messages over the pipe. base::Thread blocking_thread_; // Must be last. - base::WeakPtrFactory<MemlogConnectionManager> weak_factory_; + base::WeakPtrFactory<ConnectionManager> weak_factory_; - DISALLOW_COPY_AND_ASSIGN(MemlogConnectionManager); + DISALLOW_COPY_AND_ASSIGN(ConnectionManager); }; } // namespace profiling -#endif // CHROME_PROFILING_MEMLOG_CONNECTION_MANAGER_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_CONNECTION_MANAGER_H_
diff --git a/chrome/profiling/profiling_manifest.json b/components/services/heap_profiling/heap_profiling_manifest.json similarity index 85% rename from chrome/profiling/profiling_manifest.json rename to components/services/heap_profiling/heap_profiling_manifest.json index 5eb6f0ec..014a40dd 100644 --- a/chrome/profiling/profiling_manifest.json +++ b/components/services/heap_profiling/heap_profiling_manifest.json
@@ -1,6 +1,6 @@ { - "name": "profiling", - "display_name": "Profiling Service", + "name": "heap_profiling", + "display_name": "Heap Profiling Service", "sandbox_type": "profiling", "interface_provider_specs": { "service_manager:connector": {
diff --git a/chrome/profiling/profiling_service.cc b/components/services/heap_profiling/heap_profiling_service.cc similarity index 63% rename from chrome/profiling/profiling_service.cc rename to components/services/heap_profiling/heap_profiling_service.cc index a6f0f01..c86ecb5 100644 --- a/chrome/profiling/profiling_service.cc +++ b/components/services/heap_profiling/heap_profiling_service.cc
@@ -2,10 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/profiling_service.h" +#include "components/services/heap_profiling/heap_profiling_service.h" #include "base/logging.h" -#include "content/public/common/service_manager_connection.h" #include "mojo/public/cpp/system/platform_handle.h" #include "services/resource_coordinator/public/cpp/resource_coordinator_features.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" @@ -14,61 +13,64 @@ namespace profiling { -ProfilingService::ProfilingService() +HeapProfilingService::HeapProfilingService() : binding_(this), heap_profiler_binding_(this), weak_factory_(this) {} -ProfilingService::~ProfilingService() {} +HeapProfilingService::~HeapProfilingService() {} -std::unique_ptr<service_manager::Service> ProfilingService::CreateService() { - return std::make_unique<ProfilingService>(); +std::unique_ptr<service_manager::Service> +HeapProfilingService::CreateService() { + return std::make_unique<HeapProfilingService>(); } -void ProfilingService::OnStart() { +void HeapProfilingService::OnStart() { + registry_.AddInterface( + base::Bind(&HeapProfilingService::OnProfilingServiceRequest, + base::Unretained(this))); registry_.AddInterface(base::Bind( - &ProfilingService::OnProfilingServiceRequest, base::Unretained(this))); - registry_.AddInterface(base::Bind(&ProfilingService::OnHeapProfilerRequest, - base::Unretained(this))); + &HeapProfilingService::OnHeapProfilerRequest, base::Unretained(this))); } -void ProfilingService::OnBindInterface( +void HeapProfilingService::OnBindInterface( const service_manager::BindSourceInfo& source_info, const std::string& interface_name, mojo::ScopedMessagePipeHandle interface_pipe) { registry_.BindInterface(interface_name, std::move(interface_pipe)); } -void ProfilingService::OnProfilingServiceRequest( +void HeapProfilingService::OnProfilingServiceRequest( mojom::ProfilingServiceRequest request) { binding_.Bind(std::move(request)); } -void ProfilingService::OnHeapProfilerRequest( +void HeapProfilingService::OnHeapProfilerRequest( memory_instrumentation::mojom::HeapProfilerRequest request) { heap_profiler_binding_.Bind(std::move(request)); } -void ProfilingService::AddProfilingClient( +void HeapProfilingService::AddProfilingClient( base::ProcessId pid, mojom::ProfilingClientPtr client, - mojo::ScopedHandle memlog_pipe_receiver, + mojo::ScopedHandle pipe_receiver, mojom::ProcessType process_type, mojom::ProfilingParamsPtr params) { if (params->sampling_rate == 0) params->sampling_rate = 1; connection_manager_.OnNewConnection(pid, std::move(client), - std::move(memlog_pipe_receiver), - process_type, std::move(params)); + std::move(pipe_receiver), process_type, + std::move(params)); } -void ProfilingService::SetKeepSmallAllocations(bool keep_small_allocations) { +void HeapProfilingService::SetKeepSmallAllocations( + bool keep_small_allocations) { keep_small_allocations_ = keep_small_allocations; } -void ProfilingService::GetProfiledPids(GetProfiledPidsCallback callback) { +void HeapProfilingService::GetProfiledPids(GetProfiledPidsCallback callback) { std::move(callback).Run(connection_manager_.GetConnectionPids()); } -void ProfilingService::DumpProcessesForTracing( +void HeapProfilingService::DumpProcessesForTracing( bool strip_path_from_mapped_files, const DumpProcessesForTracingCallback& callback) { if (!helper_) { @@ -86,15 +88,14 @@ // Need a memory map to make sense of the dump. The dump will be triggered // in the memory map global dump callback. helper_->GetVmRegionsForHeapProfiler( - pids, - base::Bind( - &ProfilingService::OnGetVmRegionsCompleteForDumpProcessesForTracing, - weak_factory_.GetWeakPtr(), strip_path_from_mapped_files, - callback)); + pids, base::Bind(&HeapProfilingService:: + OnGetVmRegionsCompleteForDumpProcessesForTracing, + weak_factory_.GetWeakPtr(), + strip_path_from_mapped_files, callback)); } } -void ProfilingService::OnGetVmRegionsCompleteForDumpProcessesForTracing( +void HeapProfilingService::OnGetVmRegionsCompleteForDumpProcessesForTracing( bool strip_path_from_mapped_files, const DumpProcessesForTracingCallback& callback, VmRegions vm_regions) {
diff --git a/chrome/profiling/profiling_service.h b/components/services/heap_profiling/heap_profiling_service.h similarity index 78% rename from chrome/profiling/profiling_service.h rename to components/services/heap_profiling/heap_profiling_service.h index 952c6bb..3d73b661 100644 --- a/chrome/profiling/profiling_service.h +++ b/components/services/heap_profiling/heap_profiling_service.h
@@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_PROFILING_SERVICE_H_ -#define CHROME_PROFILING_PROFILING_SERVICE_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_HEAP_PROFILING_SERVICE_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_HEAP_PROFILING_SERVICE_H_ #include "base/memory/weak_ptr.h" -#include "chrome/profiling/memlog_connection_manager.h" +#include "components/services/heap_profiling/connection_manager.h" #include "components/services/heap_profiling/public/mojom/heap_profiling_service.mojom.h" #include "mojo/public/cpp/bindings/binding.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" @@ -15,23 +15,22 @@ namespace profiling { -class MemlogImpl; - // Service implementation for Profiling. This will be called in the profiling // process (which is a sandboxed utility process created on demand by the // ServiceManager) to set manage the global state as well as the bound // interface. // // This class lives in the I/O thread of the Utility process. -class ProfilingService : public service_manager::Service, - public mojom::ProfilingService, - public memory_instrumentation::mojom::HeapProfiler { +class HeapProfilingService + : public service_manager::Service, + public mojom::ProfilingService, + public memory_instrumentation::mojom::HeapProfiler { using DumpProcessesForTracingCallback = memory_instrumentation::mojom:: HeapProfiler::DumpProcessesForTracingCallback; public: - ProfilingService(); - ~ProfilingService() override; + HeapProfilingService(); + ~HeapProfilingService() override; // Factory method for creating the service. Used by the ServiceManager piping // to instantiate this thing. @@ -46,7 +45,7 @@ // ProfilingService implementation. void AddProfilingClient(base::ProcessId pid, mojom::ProfilingClientPtr client, - mojo::ScopedHandle memlog_pipe_receiver, + mojo::ScopedHandle pipe_receiver, mojom::ProcessType process_type, mojom::ProfilingParamsPtr params) override; void SetKeepSmallAllocations(bool keep_small_allocations) override; @@ -58,8 +57,7 @@ const DumpProcessesForTracingCallback& callback) override; private: - void OnProfilingServiceRequest( - mojom::ProfilingServiceRequest request); + void OnProfilingServiceRequest(mojom::ProfilingServiceRequest request); void OnHeapProfilerRequest( memory_instrumentation::mojom::HeapProfilerRequest request); @@ -75,14 +73,14 @@ heap_profiler_binding_; memory_instrumentation::mojom::HeapProfilerHelperPtr helper_; - MemlogConnectionManager connection_manager_; + ConnectionManager connection_manager_; bool keep_small_allocations_ = false; // Must be last. - base::WeakPtrFactory<ProfilingService> weak_factory_; + base::WeakPtrFactory<HeapProfilingService> weak_factory_; }; } // namespace profiling -#endif // CHROME_PROFILING_PROFILING_SERVICE_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_HEAP_PROFILING_SERVICE_H_
diff --git a/chrome/profiling/json_exporter.cc b/components/services/heap_profiling/json_exporter.cc similarity index 99% rename from chrome/profiling/json_exporter.cc rename to components/services/heap_profiling/json_exporter.cc index b401734..e80bd2ab0 100644 --- a/chrome/profiling/json_exporter.cc +++ b/components/services/heap_profiling/json_exporter.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/json_exporter.h" +#include "components/services/heap_profiling/json_exporter.h" #include <map>
diff --git a/chrome/profiling/json_exporter.h b/components/services/heap_profiling/json_exporter.h similarity index 91% rename from chrome/profiling/json_exporter.h rename to components/services/heap_profiling/json_exporter.h index d370626..fb4b700b 100644 --- a/chrome/profiling/json_exporter.h +++ b/components/services/heap_profiling/json_exporter.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_JSON_EXPORTER_H_ -#define CHROME_PROFILING_JSON_EXPORTER_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_JSON_EXPORTER_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_JSON_EXPORTER_H_ #include <iosfwd> #include <vector> #include "base/values.h" -#include "chrome/profiling/allocation_event.h" +#include "components/services/heap_profiling/allocation_event.h" #include "components/services/heap_profiling/public/cpp/stream.h" #include "components/services/heap_profiling/public/mojom/heap_profiling_service.mojom.h" #include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h" @@ -71,4 +71,4 @@ } // namespace profiling -#endif // CHROME_PROFILING_JSON_EXPORTER_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_JSON_EXPORTER_H_
diff --git a/chrome/profiling/json_exporter_unittest.cc b/components/services/heap_profiling/json_exporter_unittest.cc similarity index 98% rename from chrome/profiling/json_exporter_unittest.cc rename to components/services/heap_profiling/json_exporter_unittest.cc index 2551a74e..1d958ca 100644 --- a/chrome/profiling/json_exporter_unittest.cc +++ b/components/services/heap_profiling/json_exporter_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/json_exporter.h" +#include "components/services/heap_profiling/json_exporter.h" #include <sstream> @@ -13,7 +13,7 @@ #include "base/strings/string_number_conversions.h" #include "base/values.h" #include "build/build_config.h" -#include "chrome/profiling/backtrace_storage.h" +#include "components/services/heap_profiling/backtrace_storage.h" #include "services/resource_coordinator/public/cpp/memory_instrumentation/os_metrics.h" #include "testing/gtest/include/gtest/gtest.h"
diff --git a/components/services/heap_profiling/public/mojom/constants.mojom b/components/services/heap_profiling/public/mojom/constants.mojom index 6527af9..bd58c2e3 100644 --- a/components/services/heap_profiling/public/mojom/constants.mojom +++ b/components/services/heap_profiling/public/mojom/constants.mojom
@@ -4,4 +4,4 @@ module profiling.mojom; -const string kServiceName = "profiling"; +const string kServiceName = "heap_profiling";
diff --git a/chrome/profiling/memlog_receiver.h b/components/services/heap_profiling/receiver.h similarity index 73% rename from chrome/profiling/memlog_receiver.h rename to components/services/heap_profiling/receiver.h index 9e906e8..6061e98 100644 --- a/chrome/profiling/memlog_receiver.h +++ b/components/services/heap_profiling/receiver.h
@@ -2,22 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_MEMLOG_RECEIVER_H_ -#define CHROME_PROFILING_MEMLOG_RECEIVER_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_H_ #include <vector> #include "base/memory/ref_counted.h" -#include "chrome/profiling/address.h" +#include "components/services/heap_profiling/address.h" #include "components/services/heap_profiling/public/cpp/stream.h" namespace profiling { // A log receiver is a sink for parsed allocation events. See also -// MemlogStreamReceiver which is for the unparsed data blocks. -class MemlogReceiver { +// StreamReceiver which is for the unparsed data blocks. +class Receiver { public: - virtual ~MemlogReceiver() {} + virtual ~Receiver() {} virtual void OnHeader(const StreamHeader& header) = 0; virtual void OnAlloc(const AllocPacket& alloc_packet, @@ -32,4 +32,4 @@ } // namespace profiling -#endif // CHROME_PROFILING_MEMLOG_RECEIVER_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_H_
diff --git a/components/services/heap_profiling/receiver_pipe.cc b/components/services/heap_profiling/receiver_pipe.cc new file mode 100644 index 0000000..d7d9dfc7 --- /dev/null +++ b/components/services/heap_profiling/receiver_pipe.cc
@@ -0,0 +1,38 @@ +// Copyright 2017 The Chromium Authors. 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/services/heap_profiling/receiver_pipe.h" + +#include "base/bind.h" +#include "base/task_runner.h" +#include "components/services/heap_profiling/stream_receiver.h" + +namespace profiling { + +ReceiverPipeBase::ReceiverPipeBase(mojo::edk::ScopedPlatformHandle handle) + : handle_(std::move(handle)) {} + +ReceiverPipeBase::~ReceiverPipeBase() = default; + +void ReceiverPipeBase::SetReceiver(scoped_refptr<base::TaskRunner> task_runner, + scoped_refptr<StreamReceiver> receiver) { + receiver_task_runner_ = std::move(task_runner); + receiver_ = receiver; +} + +void ReceiverPipeBase::ReportError() { + handle_.reset(); +} + +void ReceiverPipeBase::OnStreamDataThunk( + scoped_refptr<base::TaskRunner> pipe_task_runner, + std::unique_ptr<char[]> data, + size_t size) { + if (!receiver_->OnStreamData(std::move(data), size)) { + pipe_task_runner->PostTask( + FROM_HERE, base::BindOnce(&ReceiverPipeBase::ReportError, this)); + } +} + +} // namespace profiling
diff --git a/chrome/profiling/memlog_receiver_pipe.h b/components/services/heap_profiling/receiver_pipe.h similarity index 64% rename from chrome/profiling/memlog_receiver_pipe.h rename to components/services/heap_profiling/receiver_pipe.h index f51b0c8e..c91c21d1 100644 --- a/chrome/profiling/memlog_receiver_pipe.h +++ b/components/services/heap_profiling/receiver_pipe.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_H_ -#define CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_PIPE_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_PIPE_H_ #include "base/memory/ref_counted.h" #include "build/build_config.h" @@ -15,23 +15,22 @@ namespace profiling { -class MemlogStreamReceiver; +class StreamReceiver; // Base class for the platform-specific receiver pipes. Since there is only // ever one actual implementation of this in the system, those implementations -// are called "MemlogReceiverPipe" and the common functions are not +// are called "ReceiverPipe" and the common functions are not // virtual. This class is just for the shared implementation. -class MemlogReceiverPipeBase - : public base::RefCountedThreadSafe<MemlogReceiverPipeBase> { +class ReceiverPipeBase : public base::RefCountedThreadSafe<ReceiverPipeBase> { public: void SetReceiver(scoped_refptr<base::TaskRunner> task_runner, - scoped_refptr<MemlogStreamReceiver> receiver); + scoped_refptr<StreamReceiver> receiver); protected: - friend class base::RefCountedThreadSafe<MemlogReceiverPipeBase>; + friend class base::RefCountedThreadSafe<ReceiverPipeBase>; - explicit MemlogReceiverPipeBase(mojo::edk::ScopedPlatformHandle handle); - virtual ~MemlogReceiverPipeBase(); + explicit ReceiverPipeBase(mojo::edk::ScopedPlatformHandle handle); + virtual ~ReceiverPipeBase(); // Callback that indicates an error has occurred and the connection should // be closed. May be called more than once in an error condition. @@ -45,7 +44,7 @@ size_t size); scoped_refptr<base::TaskRunner> receiver_task_runner_; - scoped_refptr<MemlogStreamReceiver> receiver_; + scoped_refptr<StreamReceiver> receiver_; mojo::edk::ScopedPlatformHandle handle_; }; @@ -54,9 +53,9 @@ // Define the platform-specific specialization. #if defined(OS_WIN) -#include "chrome/profiling/memlog_receiver_pipe_win.h" +#include "components/services/heap_profiling/receiver_pipe_win.h" #else -#include "chrome/profiling/memlog_receiver_pipe_posix.h" +#include "components/services/heap_profiling/receiver_pipe_posix.h" #endif -#endif // CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_PIPE_H_
diff --git a/chrome/profiling/memlog_receiver_pipe_posix.cc b/components/services/heap_profiling/receiver_pipe_posix.cc similarity index 64% rename from chrome/profiling/memlog_receiver_pipe_posix.cc rename to components/services/heap_profiling/receiver_pipe_posix.cc index fa4a99b..11f84352 100644 --- a/chrome/profiling/memlog_receiver_pipe_posix.cc +++ b/components/services/heap_profiling/receiver_pipe_posix.cc
@@ -2,36 +2,36 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/memlog_receiver_pipe_posix.h" +#include "components/services/heap_profiling/receiver_pipe_posix.h" #include "base/bind.h" #include "base/logging.h" #include "base/posix/eintr_wrapper.h" #include "base/threading/thread.h" #include "build/build_config.h" -#include "chrome/profiling/memlog_receiver_pipe.h" -#include "chrome/profiling/memlog_stream_receiver.h" #include "components/services/heap_profiling/public/cpp/sender_pipe.h" +#include "components/services/heap_profiling/receiver_pipe.h" +#include "components/services/heap_profiling/stream_receiver.h" #include "mojo/edk/embedder/platform_channel_utils_posix.h" #include "mojo/edk/embedder/platform_handle.h" namespace profiling { -MemlogReceiverPipe::MemlogReceiverPipe(mojo::edk::ScopedPlatformHandle handle) - : MemlogReceiverPipeBase(std::move(handle)), +ReceiverPipe::ReceiverPipe(mojo::edk::ScopedPlatformHandle handle) + : ReceiverPipeBase(std::move(handle)), controller_(FROM_HERE), read_buffer_(new char[SenderPipe::kPipeSize]) {} -MemlogReceiverPipe::~MemlogReceiverPipe() {} +ReceiverPipe::~ReceiverPipe() {} -void MemlogReceiverPipe::StartReadingOnIOThread() { +void ReceiverPipe::StartReadingOnIOThread() { base::MessageLoopForIO::current()->WatchFileDescriptor( handle_.get().handle, true, base::MessageLoopForIO::WATCH_READ, &controller_, this); OnFileCanReadWithoutBlocking(handle_.get().handle); } -void MemlogReceiverPipe::OnFileCanReadWithoutBlocking(int fd) { +void ReceiverPipe::OnFileCanReadWithoutBlocking(int fd) { ssize_t bytes_read = 0; do { base::circular_deque<mojo::edk::PlatformHandle> dummy_for_receive; @@ -40,11 +40,10 @@ read(handle_.get().handle, read_buffer_.get(), SenderPipe::kPipeSize)); if (bytes_read > 0) { receiver_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&MemlogReceiverPipe::OnStreamDataThunk, this, - base::MessageLoop::current()->task_runner(), - std::move(read_buffer_), - static_cast<size_t>(bytes_read))); + FROM_HERE, base::BindOnce(&ReceiverPipe::OnStreamDataThunk, this, + base::MessageLoop::current()->task_runner(), + std::move(read_buffer_), + static_cast<size_t>(bytes_read))); read_buffer_.reset(new char[SenderPipe::kPipeSize]); return; } else if (bytes_read == 0) { @@ -53,7 +52,7 @@ DCHECK(receiver_task_runner_); receiver_task_runner_->PostTask( FROM_HERE, - base::BindOnce(&MemlogStreamReceiver::OnStreamComplete, receiver_)); + base::BindOnce(&StreamReceiver::OnStreamComplete, receiver_)); return; } else { if (errno != EAGAIN && errno != EWOULDBLOCK) { @@ -62,13 +61,13 @@ DCHECK(receiver_task_runner_); receiver_task_runner_->PostTask( FROM_HERE, - base::BindOnce(&MemlogStreamReceiver::OnStreamComplete, receiver_)); + base::BindOnce(&StreamReceiver::OnStreamComplete, receiver_)); } } } while (bytes_read > 0); } -void MemlogReceiverPipe::OnFileCanWriteWithoutBlocking(int fd) { +void ReceiverPipe::OnFileCanWriteWithoutBlocking(int fd) { NOTREACHED(); }
diff --git a/components/services/heap_profiling/receiver_pipe_posix.h b/components/services/heap_profiling/receiver_pipe_posix.h new file mode 100644 index 0000000..e9b5b36 --- /dev/null +++ b/components/services/heap_profiling/receiver_pipe_posix.h
@@ -0,0 +1,41 @@ +// Copyright 2017 The Chromium Authors. 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_SERVICES_HEAP_PROFILING_RECEIVER_PIPE_POSIX_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_PIPE_POSIX_H_ + +#include <string> + +#include "base/files/platform_file.h" +#include "base/macros.h" +#include "base/message_loop/message_loop.h" +#include "build/build_config.h" +#include "components/services/heap_profiling/receiver_pipe.h" + +namespace profiling { + +class ReceiverPipe : public ReceiverPipeBase, + public base::MessageLoopForIO::Watcher { + public: + explicit ReceiverPipe(mojo::edk::ScopedPlatformHandle handle); + + // Must be called on the IO thread. + void StartReadingOnIOThread(); + + private: + ~ReceiverPipe() override; + + // MessageLoopForIO::Watcher implementation. + void OnFileCanReadWithoutBlocking(int fd) override; + void OnFileCanWriteWithoutBlocking(int fd) override; + + base::MessageLoopForIO::FileDescriptorWatcher controller_; + std::unique_ptr<char[]> read_buffer_; + + DISALLOW_COPY_AND_ASSIGN(ReceiverPipe); +}; + +} // namespace profiling + +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_PIPE_POSIX_H_
diff --git a/chrome/profiling/memlog_receiver_pipe_win.cc b/components/services/heap_profiling/receiver_pipe_win.cc similarity index 72% rename from chrome/profiling/memlog_receiver_pipe_win.cc rename to components/services/heap_profiling/receiver_pipe_win.cc index 478b4cc..3c27de0 100644 --- a/chrome/profiling/memlog_receiver_pipe_win.cc +++ b/components/services/heap_profiling/receiver_pipe_win.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/memlog_receiver_pipe_win.h" +#include "components/services/heap_profiling/receiver_pipe_win.h" #include "base/bind.h" #include "base/logging.h" @@ -10,28 +10,27 @@ #include "base/strings/string16.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread.h" -#include "chrome/profiling/memlog_receiver_pipe.h" -#include "chrome/profiling/memlog_stream_receiver.h" #include "components/services/heap_profiling/public/cpp/sender_pipe.h" +#include "components/services/heap_profiling/receiver_pipe.h" +#include "components/services/heap_profiling/stream_receiver.h" namespace profiling { -MemlogReceiverPipe::MemlogReceiverPipe(mojo::edk::ScopedPlatformHandle handle) - : MemlogReceiverPipeBase(std::move(handle)), +ReceiverPipe::ReceiverPipe(mojo::edk::ScopedPlatformHandle handle) + : ReceiverPipeBase(std::move(handle)), read_buffer_(new char[SenderPipe::kPipeSize]) { ZeroOverlapped(); base::MessageLoopForIO::current()->RegisterIOHandler(handle_.get().handle, this); } -MemlogReceiverPipe::~MemlogReceiverPipe() { -} +ReceiverPipe::~ReceiverPipe() {} -void MemlogReceiverPipe::StartReadingOnIOThread() { +void ReceiverPipe::StartReadingOnIOThread() { ReadUntilBlocking(); } -void MemlogReceiverPipe::ReadUntilBlocking() { +void ReceiverPipe::ReadUntilBlocking() { // TODO(brettw) note that the IO completion callback will always be issued, // even for sync returns of ReadFile. If there is a lot of data ready to be // read, it would be nice to process them all in this loop rather than having @@ -50,31 +49,30 @@ if (receiver_) { receiver_task_runner_->PostTask( FROM_HERE, - base::BindOnce(&MemlogStreamReceiver::OnStreamComplete, receiver_)); + base::BindOnce(&StreamReceiver::OnStreamComplete, receiver_)); } return; } } } -void MemlogReceiverPipe::ZeroOverlapped() { +void ReceiverPipe::ZeroOverlapped() { memset(&context_.overlapped, 0, sizeof(OVERLAPPED)); } -void MemlogReceiverPipe::OnIOCompleted( - base::MessagePumpForIO::IOContext* context, - DWORD bytes_transfered, - DWORD error) { +void ReceiverPipe::OnIOCompleted(base::MessagePumpForIO::IOContext* context, + DWORD bytes_transfered, + DWORD error) { // Note: any crashes with this on the stack are likely a result of destroying // a relevant class while there is I/O pending. DCHECK(read_outstanding_); // Clear |read_outstanding_| but retain the reference to keep ourself alive // until this function returns. - scoped_refptr<MemlogReceiverPipe> self(std::move(read_outstanding_)); + scoped_refptr<ReceiverPipe> self(std::move(read_outstanding_)); if (bytes_transfered && receiver_) { receiver_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&MemlogReceiverPipe::OnStreamDataThunk, this, + FROM_HERE, base::BindOnce(&ReceiverPipe::OnStreamDataThunk, this, base::MessageLoop::current()->task_runner(), std::move(read_buffer_), static_cast<size_t>(bytes_transfered)));
diff --git a/chrome/profiling/memlog_receiver_pipe_win.h b/components/services/heap_profiling/receiver_pipe_win.h similarity index 64% rename from chrome/profiling/memlog_receiver_pipe_win.h rename to components/services/heap_profiling/receiver_pipe_win.h index 064f5418..75d2aa9 100644 --- a/chrome/profiling/memlog_receiver_pipe_win.h +++ b/components/services/heap_profiling/receiver_pipe_win.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_WIN_H_ -#define CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_WIN_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_PIPE_WIN_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_PIPE_WIN_H_ #include <windows.h> @@ -14,20 +14,20 @@ #include "base/message_loop/message_pump_win.h" #include "base/strings/string16.h" #include "build/build_config.h" -#include "chrome/profiling/memlog_receiver_pipe.h" +#include "components/services/heap_profiling/receiver_pipe.h" namespace profiling { -class MemlogReceiverPipe : public MemlogReceiverPipeBase, - public base::MessagePumpForIO::IOHandler { +class ReceiverPipe : public ReceiverPipeBase, + public base::MessagePumpForIO::IOHandler { public: - explicit MemlogReceiverPipe(mojo::edk::ScopedPlatformHandle handle); + explicit ReceiverPipe(mojo::edk::ScopedPlatformHandle handle); // Must be called on the IO thread. void StartReadingOnIOThread(); private: - ~MemlogReceiverPipe() override; + ~ReceiverPipe() override; void ReadUntilBlocking(); void ZeroOverlapped(); @@ -41,13 +41,13 @@ // Used to keep |this| live while awaiting IO completion, which is required // to avoid premature destruction during shutdown. - scoped_refptr<MemlogReceiverPipe> read_outstanding_; + scoped_refptr<ReceiverPipe> read_outstanding_; std::unique_ptr<char[]> read_buffer_; - DISALLOW_COPY_AND_ASSIGN(MemlogReceiverPipe); + DISALLOW_COPY_AND_ASSIGN(ReceiverPipe); }; } // namespace profiling -#endif // CHROME_PROFILING_MEMLOG_RECEIVER_PIPE_WIN_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_RECEIVER_PIPE_WIN_H_
diff --git a/chrome/profiling/memlog_stream_fuzzer.cc b/components/services/heap_profiling/stream_fuzzer.cc similarity index 76% rename from chrome/profiling/memlog_stream_fuzzer.cc rename to components/services/heap_profiling/stream_fuzzer.cc index b277a7e5..d8aa4964 100644 --- a/chrome/profiling/memlog_stream_fuzzer.cc +++ b/components/services/heap_profiling/stream_fuzzer.cc
@@ -2,15 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/memlog_receiver.h" -#include "chrome/profiling/memlog_stream_parser.h" +#include "components/services/heap_profiling/receiver.h" +#include "components/services/heap_profiling/stream_parser.h" #include <utility> namespace profiling { namespace { -class DummyMemlogReceiver : public profiling::MemlogReceiver { +class DummyReceiver : public profiling::Receiver { void OnHeader(const StreamHeader& header) override {} void OnAlloc(const AllocPacket& alloc_packet, std::vector<Address>&& stack, @@ -27,9 +27,9 @@ // Entry point for LibFuzzer. extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { - profiling::DummyMemlogReceiver receiver; - scoped_refptr<profiling::MemlogStreamParser> parser( - new profiling::MemlogStreamParser(&receiver)); + profiling::DummyReceiver receiver; + scoped_refptr<profiling::StreamParser> parser( + new profiling::StreamParser(&receiver)); std::unique_ptr<char[]> stream_data(new char[size]); memcpy(stream_data.get(), data, size); parser->OnStreamData(std::move(stream_data), size);
diff --git a/chrome/profiling/memlog_stream_fuzzer.dict b/components/services/heap_profiling/stream_fuzzer.dict similarity index 68% rename from chrome/profiling/memlog_stream_fuzzer.dict rename to components/services/heap_profiling/stream_fuzzer.dict index 1460b85..7accea7 100644 --- a/chrome/profiling/memlog_stream_fuzzer.dict +++ b/components/services/heap_profiling/stream_fuzzer.dict
@@ -1,4 +1,4 @@ -# These values are obtained from chrome/common/profiling//memlog_stream.h. +# These values are obtained from components/services/heap_profiling/stream.h. stream_signature="\xF6\x10\x3B\x71" alloc_packet="\xF6\x10\x3B\x72" free_packet="\xF6\x10\x3B\x73"
diff --git a/chrome/profiling/memlog_stream_parser.cc b/components/services/heap_profiling/stream_parser.cc similarity index 80% rename from chrome/profiling/memlog_stream_parser.cc rename to components/services/heap_profiling/stream_parser.cc index 034a453..d4e63d6 100644 --- a/chrome/profiling/memlog_stream_parser.cc +++ b/components/services/heap_profiling/stream_parser.cc
@@ -2,36 +2,35 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/memlog_stream_parser.h" +#include "components/services/heap_profiling/stream_parser.h" #include <algorithm> #include "base/containers/stack_container.h" #include "base/strings/stringprintf.h" -#include "chrome/profiling/address.h" -#include "chrome/profiling/backtrace.h" +#include "components/services/heap_profiling/address.h" +#include "components/services/heap_profiling/backtrace.h" #include "components/services/heap_profiling/public/cpp/stream.h" namespace profiling { -MemlogStreamParser::Block::Block(std::unique_ptr<char[]> d, size_t s) +StreamParser::Block::Block(std::unique_ptr<char[]> d, size_t s) : data(std::move(d)), size(s) {} -MemlogStreamParser::Block::Block(Block&& other) noexcept = default; +StreamParser::Block::Block(Block&& other) noexcept = default; -MemlogStreamParser::Block::~Block() = default; +StreamParser::Block::~Block() = default; -MemlogStreamParser::MemlogStreamParser(MemlogReceiver* receiver) - : receiver_(receiver) {} +StreamParser::StreamParser(Receiver* receiver) : receiver_(receiver) {} -MemlogStreamParser::~MemlogStreamParser() {} +StreamParser::~StreamParser() {} -void MemlogStreamParser::DisconnectReceivers() { +void StreamParser::DisconnectReceivers() { base::AutoLock lock(lock_); receiver_ = nullptr; } -bool MemlogStreamParser::OnStreamData(std::unique_ptr<char[]> data, size_t sz) { +bool StreamParser::OnStreamData(std::unique_ptr<char[]> data, size_t sz) { base::AutoLock l(lock_); if (!receiver_ || error_) return false; @@ -84,13 +83,13 @@ } } -void MemlogStreamParser::OnStreamComplete() { +void StreamParser::OnStreamComplete() { base::AutoLock l(lock_); if (receiver_) receiver_->OnComplete(); } -bool MemlogStreamParser::AreBytesAvailable(size_t count) const { +bool StreamParser::AreBytesAvailable(size_t count) const { size_t used = 0; size_t current_block_offset = block_zero_offset_; for (auto it = blocks_.begin(); it != blocks_.end() && used < count; ++it) { @@ -100,7 +99,7 @@ return used >= count; } -bool MemlogStreamParser::PeekBytes(size_t count, void* dest) const { +bool StreamParser::PeekBytes(size_t count, void* dest) const { char* dest_char = static_cast<char*>(dest); size_t used = 0; @@ -118,14 +117,14 @@ return used == count; } -bool MemlogStreamParser::ReadBytes(size_t count, void* dest) { +bool StreamParser::ReadBytes(size_t count, void* dest) { if (!PeekBytes(count, dest)) return false; ConsumeBytes(count); return true; } -void MemlogStreamParser::ConsumeBytes(size_t count) { +void StreamParser::ConsumeBytes(size_t count) { DCHECK(AreBytesAvailable(count)); while (count > 0) { size_t bytes_left_in_block = blocks_.front().size - block_zero_offset_; @@ -142,7 +141,7 @@ } } -MemlogStreamParser::ReadStatus MemlogStreamParser::ParseHeader() { +StreamParser::ReadStatus StreamParser::ParseHeader() { StreamHeader header; if (!ReadBytes(sizeof(StreamHeader), &header)) return READ_NO_DATA; @@ -155,7 +154,7 @@ return READ_OK; } -MemlogStreamParser::ReadStatus MemlogStreamParser::ParseAlloc() { +StreamParser::ReadStatus StreamParser::ParseAlloc() { // Read the packet. Can't commit the read until the stack is read and // that has to be done below. AllocPacket alloc_packet; @@ -194,7 +193,7 @@ return READ_OK; } -MemlogStreamParser::ReadStatus MemlogStreamParser::ParseFree() { +StreamParser::ReadStatus StreamParser::ParseFree() { FreePacket free_packet; if (!ReadBytes(sizeof(FreePacket), &free_packet)) return READ_NO_DATA; @@ -203,7 +202,7 @@ return READ_OK; } -MemlogStreamParser::ReadStatus MemlogStreamParser::ParseBarrier() { +StreamParser::ReadStatus StreamParser::ParseBarrier() { BarrierPacket barrier_packet; if (!ReadBytes(sizeof(BarrierPacket), &barrier_packet)) return READ_NO_DATA; @@ -212,7 +211,7 @@ return READ_OK; } -MemlogStreamParser::ReadStatus MemlogStreamParser::ParseStringMapping() { +StreamParser::ReadStatus StreamParser::ParseStringMapping() { StringMappingPacket string_mapping_packet; if (!PeekBytes(sizeof(StringMappingPacket), &string_mapping_packet)) return READ_NO_DATA; @@ -235,8 +234,8 @@ return READ_OK; } -void MemlogStreamParser::SetErrorState() { - LOG(ERROR) << "MemlogStreamParser parsing error"; +void StreamParser::SetErrorState() { + LOG(ERROR) << "StreamParser parsing error"; error_ = true; receiver_->OnComplete(); }
diff --git a/chrome/profiling/memlog_stream_parser.h b/components/services/heap_profiling/stream_parser.h similarity index 82% rename from chrome/profiling/memlog_stream_parser.h rename to components/services/heap_profiling/stream_parser.h index 12137982..bd27260 100644 --- a/chrome/profiling/memlog_stream_parser.h +++ b/components/services/heap_profiling/stream_parser.h
@@ -2,24 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_MEMLOG_STREAM_PARSER_H_ -#define CHROME_PROFILING_MEMLOG_STREAM_PARSER_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_STREAM_PARSER_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_STREAM_PARSER_H_ #include "base/callback.h" #include "base/containers/circular_deque.h" #include "base/macros.h" #include "base/synchronization/lock.h" -#include "chrome/profiling/memlog_receiver.h" -#include "chrome/profiling/memlog_stream_receiver.h" +#include "components/services/heap_profiling/receiver.h" +#include "components/services/heap_profiling/stream_receiver.h" namespace profiling { // Parses a memory stream. Refcounted via StreamReceiver. -class MemlogStreamParser : public MemlogStreamReceiver { +class StreamParser : public StreamReceiver { public: // Both receivers must either outlive this class or live until // DisconnectReceivers is called. - explicit MemlogStreamParser(MemlogReceiver* receiver); + explicit StreamParser(Receiver* receiver); // For tear-down, resets both receivers so they will not be called. void DisconnectReceivers(); @@ -49,7 +49,7 @@ READ_NO_DATA // Not enough data, try again when we get more }; - ~MemlogStreamParser() override; + ~StreamParser() override; // Returns true if the given number of bytes are available now. bool AreBytesAvailable(size_t count) const; @@ -69,7 +69,7 @@ void SetErrorState(); // Not owned by this class. - MemlogReceiver* receiver_; + Receiver* receiver_; base::circular_deque<Block> blocks_; @@ -84,9 +84,9 @@ // the memory dumper. base::Lock lock_; - DISALLOW_COPY_AND_ASSIGN(MemlogStreamParser); + DISALLOW_COPY_AND_ASSIGN(StreamParser); }; } // namespace profiling -#endif // CHROME_PROFILING_MEMLOG_STREAM_PARSER_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_STREAM_PARSER_H_
diff --git a/chrome/profiling/memlog_stream_parser_unittest.cc b/components/services/heap_profiling/stream_parser_unittest.cc similarity index 85% rename from chrome/profiling/memlog_stream_parser_unittest.cc rename to components/services/heap_profiling/stream_parser_unittest.cc index 255ac63..57330c5 100644 --- a/chrome/profiling/memlog_stream_parser_unittest.cc +++ b/components/services/heap_profiling/stream_parser_unittest.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/profiling/memlog_stream_parser.h" +#include "components/services/heap_profiling/stream_parser.h" #include "testing/gtest/include/gtest/gtest.h" @@ -10,7 +10,7 @@ namespace { -void SendData(const scoped_refptr<MemlogStreamParser>& parser, +void SendData(const scoped_refptr<StreamParser>& parser, const void* data, size_t size) { std::unique_ptr<char[]> heap(new char[size]); @@ -18,12 +18,12 @@ parser->OnStreamData(std::move(heap), size); } -void SendHeader(scoped_refptr<MemlogStreamParser>& parser) { +void SendHeader(scoped_refptr<StreamParser>& parser) { StreamHeader header; SendData(parser, &header, sizeof(StreamHeader)); } -class TestReceiver : public MemlogReceiver { +class TestReceiver : public Receiver { public: TestReceiver() { // Make our saved header invalid so we can't confuse the locally @@ -113,9 +113,9 @@ } // namespace -TEST(MemlogStreamParser, NormalHeader) { +TEST(StreamParser, NormalHeader) { TestReceiver receiver; - scoped_refptr<MemlogStreamParser> parser(new MemlogStreamParser(&receiver)); + scoped_refptr<StreamParser> parser(new StreamParser(&receiver)); // Should work to send in two packets. StreamHeader header; @@ -131,9 +131,9 @@ EXPECT_TRUE(receiver.got_complete()); } -TEST(MemlogStreamParser, BadHeader) { +TEST(StreamParser, BadHeader) { TestReceiver receiver; - scoped_refptr<MemlogStreamParser> parser(new MemlogStreamParser(&receiver)); + scoped_refptr<StreamParser> parser(new StreamParser(&receiver)); StreamHeader header; header.signature = 15; @@ -143,9 +143,9 @@ EXPECT_TRUE(parser->has_error()); } -TEST(MemlogStreamParser, GoodAlloc) { +TEST(StreamParser, GoodAlloc) { TestReceiver receiver; - scoped_refptr<MemlogStreamParser> parser(new MemlogStreamParser(&receiver)); + scoped_refptr<StreamParser> parser(new StreamParser(&receiver)); SendHeader(parser); constexpr size_t kStackSize = 4; @@ -180,9 +180,9 @@ EXPECT_EQ(stack[3], receiver.last_alloc_stack()[3].value); } -TEST(MemlogStreamParser, AllocBigStack) { +TEST(StreamParser, AllocBigStack) { TestReceiver receiver; - scoped_refptr<MemlogStreamParser> parser(new MemlogStreamParser(&receiver)); + scoped_refptr<StreamParser> parser(new StreamParser(&receiver)); SendHeader(parser); AllocPacket alloc; @@ -200,9 +200,9 @@ EXPECT_TRUE(receiver.got_complete()); } -TEST(MemlogStreamParser, AllocBigContext) { +TEST(StreamParser, AllocBigContext) { TestReceiver receiver; - scoped_refptr<MemlogStreamParser> parser(new MemlogStreamParser(&receiver)); + scoped_refptr<StreamParser> parser(new StreamParser(&receiver)); SendHeader(parser); AllocPacket alloc; @@ -220,9 +220,9 @@ EXPECT_TRUE(receiver.got_complete()); } -TEST(MemlogStreamParser, GoodFree) { +TEST(StreamParser, GoodFree) { TestReceiver receiver; - scoped_refptr<MemlogStreamParser> parser(new MemlogStreamParser(&receiver)); + scoped_refptr<StreamParser> parser(new StreamParser(&receiver)); SendHeader(parser); FreePacket fr; @@ -234,9 +234,9 @@ EXPECT_EQ(fr.address, receiver.last_free().address); } -TEST(MemlogStreamParser, Barrier) { +TEST(StreamParser, Barrier) { TestReceiver receiver; - scoped_refptr<MemlogStreamParser> parser(new MemlogStreamParser(&receiver)); + scoped_refptr<StreamParser> parser(new StreamParser(&receiver)); SendHeader(parser); constexpr uint32_t barrier_id = 0x12345678; @@ -250,9 +250,9 @@ EXPECT_EQ(barrier_id, receiver.last_barrier().barrier_id); } -TEST(MemlogStreamParser, StringMapping) { +TEST(StreamParser, StringMapping) { TestReceiver receiver; - scoped_refptr<MemlogStreamParser> parser(new MemlogStreamParser(&receiver)); + scoped_refptr<StreamParser> parser(new StreamParser(&receiver)); SendHeader(parser); const std::string kDummyText = "kDummyText";
diff --git a/chrome/profiling/memlog_stream_receiver.h b/components/services/heap_profiling/stream_receiver.h similarity index 67% rename from chrome/profiling/memlog_stream_receiver.h rename to components/services/heap_profiling/stream_receiver.h index daedd5e..c1d0e1fe 100644 --- a/chrome/profiling/memlog_stream_receiver.h +++ b/components/services/heap_profiling/stream_receiver.h
@@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_PROFILING_MEMLOG_STREAM_RECEIVER_H_ -#define CHROME_PROFILING_MEMLOG_STREAM_RECEIVER_H_ +#ifndef COMPONENTS_SERVICES_HEAP_PROFILING_STREAM_RECEIVER_H_ +#define COMPONENTS_SERVICES_HEAP_PROFILING_STREAM_RECEIVER_H_ #include <memory> @@ -13,10 +13,9 @@ namespace profiling { // A stream receiver is a sink for unparsed bytes. See also LogReceiver. -class MemlogStreamReceiver - : public base::RefCountedThreadSafe<MemlogStreamReceiver> { +class StreamReceiver : public base::RefCountedThreadSafe<StreamReceiver> { public: - MemlogStreamReceiver() {} + StreamReceiver() {} // Returns true on success, false on unrecoverable error. The implementation // should be able to handle calls after an error has been reported (some @@ -27,10 +26,10 @@ virtual void OnStreamComplete() = 0; protected: - friend class base::RefCountedThreadSafe<MemlogStreamReceiver>; - virtual ~MemlogStreamReceiver() {} + friend class base::RefCountedThreadSafe<StreamReceiver>; + virtual ~StreamReceiver() {} }; } // namespace profiling -#endif // CHROME_PROFILING_MEMLOG_STREAM_RECEIVER_H_ +#endif // COMPONENTS_SERVICES_HEAP_PROFILING_STREAM_RECEIVER_H_
diff --git a/components/sessions/core/session_id.h b/components/sessions/core/session_id.h index f31f206..fbe9fee 100644 --- a/components/sessions/core/session_id.h +++ b/components/sessions/core/session_id.h
@@ -46,6 +46,10 @@ // Sets underlying type (deprecated: use FromSerializedValue() instead). void set_id(id_type id) { id_ = id; } + struct Hasher { + inline std::size_t operator()(SessionID id) const { return id.id(); } + }; + private: explicit constexpr SessionID(id_type id) : id_(id) {}
diff --git a/components/sync/BUILD.gn b/components/sync/BUILD.gn index e65dd5f..10e60ec 100644 --- a/components/sync/BUILD.gn +++ b/components/sync/BUILD.gn
@@ -561,6 +561,7 @@ "//components/version_info", "//crypto", "//google_apis", + "//services/identity/public/cpp", "//sql", "//third_party/cacheinvalidation", "//third_party/crc32c",
diff --git a/components/sync/driver/DEPS b/components/sync/driver/DEPS index 72a2c53..296536a 100644 --- a/components/sync/driver/DEPS +++ b/components/sync/driver/DEPS
@@ -19,4 +19,5 @@ "+google/cacheinvalidation", "+net", "+policy", + "+services/identity/public/cpp", ]
diff --git a/components/sync/driver/signin_manager_wrapper.cc b/components/sync/driver/signin_manager_wrapper.cc index bf96127..d1d02e0 100644 --- a/components/sync/driver/signin_manager_wrapper.cc +++ b/components/sync/driver/signin_manager_wrapper.cc
@@ -7,21 +7,27 @@ #include "components/signin/core/browser/signin_manager_base.h" #include "google_apis/gaia/gaia_constants.h" -SigninManagerWrapper::SigninManagerWrapper(SigninManagerBase* original) - : original_(original) {} +SigninManagerWrapper::SigninManagerWrapper( + identity::IdentityManager* identity_manager, + SigninManagerBase* signin_manager) + : identity_manager_(identity_manager), signin_manager_(signin_manager) {} SigninManagerWrapper::~SigninManagerWrapper() {} -SigninManagerBase* SigninManagerWrapper::GetOriginal() { - return original_; +identity::IdentityManager* SigninManagerWrapper::GetIdentityManager() { + return identity_manager_; +} + +SigninManagerBase* SigninManagerWrapper::GetSigninManager() { + return signin_manager_; } std::string SigninManagerWrapper::GetEffectiveUsername() const { - return original_->GetAuthenticatedAccountInfo().email; + return signin_manager_->GetAuthenticatedAccountInfo().email; } std::string SigninManagerWrapper::GetAccountIdToUse() const { - return original_->GetAuthenticatedAccountId(); + return signin_manager_->GetAuthenticatedAccountId(); } std::string SigninManagerWrapper::GetSyncScopeToUse() const {
diff --git a/components/sync/driver/signin_manager_wrapper.h b/components/sync/driver/signin_manager_wrapper.h index cb1398d..43e22486 100644 --- a/components/sync/driver/signin_manager_wrapper.h +++ b/components/sync/driver/signin_manager_wrapper.h
@@ -11,13 +11,18 @@ class SigninManagerBase; +namespace identity { +class IdentityManager; +} + // Wraps SigninManager so subclasses can support different ways of getting // account information if necessary. Currently exists for supervised users; // the subclass SupervisedUserSigninManagerWrapper may be merged back into // this class once supervised users are componentized. class SigninManagerWrapper { public: - explicit SigninManagerWrapper(SigninManagerBase* original); + explicit SigninManagerWrapper(identity::IdentityManager* identity_manager, + SigninManagerBase* signin_manager); virtual ~SigninManagerWrapper(); // Get the email address to use for this account. @@ -29,11 +34,15 @@ // Get the OAuth2 scope to use for this account. virtual std::string GetSyncScopeToUse() const; + // Return the original IdentityManager object that was passed in. + identity::IdentityManager* GetIdentityManager(); + // Return the original SigninManagerBase object that was passed in. - SigninManagerBase* GetOriginal(); + SigninManagerBase* GetSigninManager(); private: - SigninManagerBase* original_; + identity::IdentityManager* identity_manager_; + SigninManagerBase* signin_manager_; DISALLOW_COPY_AND_ASSIGN(SigninManagerWrapper); };
diff --git a/components/sync/driver/sync_service_base.cc b/components/sync/driver/sync_service_base.cc index 511e8fb..acd7836 100644 --- a/components/sync/driver/sync_service_base.cc +++ b/components/sync/driver/sync_service_base.cc
@@ -85,7 +85,7 @@ AccountInfo SyncServiceBase::GetAuthenticatedAccountInfo() const { DCHECK(thread_checker_.CalledOnValidThread()); - return signin_ ? signin_->GetOriginal()->GetAuthenticatedAccountInfo() + return signin_ ? signin_->GetSigninManager()->GetAuthenticatedAccountInfo() : AccountInfo(); }
diff --git a/components/toolbar/test_toolbar_model.cc b/components/toolbar/test_toolbar_model.cc index a465092..86ccbeb 100644 --- a/components/toolbar/test_toolbar_model.cc +++ b/components/toolbar/test_toolbar_model.cc
@@ -19,11 +19,11 @@ TestToolbarModel::~TestToolbarModel() {} base::string16 TestToolbarModel::GetFormattedFullURL() const { - return text_; + return formatted_full_url_; } base::string16 TestToolbarModel::GetURLForDisplay() const { - return text_; + return url_for_display_; } GURL TestToolbarModel::GetURL() const {
diff --git a/components/toolbar/test_toolbar_model.h b/components/toolbar/test_toolbar_model.h index 639332d..e7be4534 100644 --- a/components/toolbar/test_toolbar_model.h +++ b/components/toolbar/test_toolbar_model.h
@@ -34,7 +34,12 @@ bool ShouldDisplayURL() const override; bool IsOfflinePage() const override; - void set_text(const base::string16& text) { text_ = text; } + void set_formatted_full_url(const base::string16& url) { + formatted_full_url_ = url; + } + void set_url_for_display(const base::string16& url) { + url_for_display_ = url; + } void set_url(const GURL& url) { url_ = url; } void set_security_level(security_state::SecurityLevel security_level) { security_level_ = security_level; @@ -49,7 +54,8 @@ void set_offline_page(bool offline_page) { offline_page_ = offline_page; } private: - base::string16 text_; + base::string16 formatted_full_url_; + base::string16 url_for_display_; GURL url_; security_state::SecurityLevel security_level_ = security_state::NONE; const gfx::VectorIcon* icon_ = nullptr;
diff --git a/components/ukm/ukm_service.cc b/components/ukm/ukm_service.cc index 31bb4a2f..2368c4b8 100644 --- a/components/ukm/ukm_service.cc +++ b/components/ukm/ukm_service.cc
@@ -60,8 +60,10 @@ } // namespace UkmService::UkmService(PrefService* pref_service, - metrics::MetricsServiceClient* client) + metrics::MetricsServiceClient* client, + bool restrict_to_whitelist_entries) : pref_service_(pref_service), + restrict_to_whitelist_entries_(restrict_to_whitelist_entries), client_id_(0), session_id_(0), report_count_(0), @@ -251,4 +253,8 @@ reporting_service_.ukm_log_store()->StoreLog(serialized_log); } +bool UkmService::ShouldRestrictToWhitelistedEntries() const { + return restrict_to_whitelist_entries_; +} + } // namespace ukm
diff --git a/components/ukm/ukm_service.h b/components/ukm/ukm_service.h index 4c5b6807..0beed526 100644 --- a/components/ukm/ukm_service.h +++ b/components/ukm/ukm_service.h
@@ -42,7 +42,9 @@ // Constructs a UkmService. // Calling code is responsible for ensuring that the lifetime of // |pref_service| is longer than the lifetime of UkmService. - UkmService(PrefService* pref_service, metrics::MetricsServiceClient* client); + UkmService(PrefService* pref_service, + metrics::MetricsServiceClient* client, + bool restrict_to_whitelist_entries); ~UkmService() override; // Initializes the UKM service. @@ -111,9 +113,15 @@ // Called by log_uploader_ when the an upload is completed. void OnLogUploadComplete(int response_code); + // ukm::UkmRecorderImpl: + bool ShouldRestrictToWhitelistedEntries() const override; + // A weak pointer to the PrefService used to read and write preferences. PrefService* pref_service_; + // If true, only whitelisted Entries should be recorded. + bool restrict_to_whitelist_entries_; + // The UKM client id stored in prefs. uint64_t client_id_;
diff --git a/components/ukm/ukm_service_unittest.cc b/components/ukm/ukm_service_unittest.cc index f5efded..1acb64a 100644 --- a/components/ukm/ukm_service_unittest.cc +++ b/components/ukm/ukm_service_unittest.cc
@@ -171,7 +171,8 @@ } // namespace TEST_F(UkmServiceTest, EnableDisableSchedule) { - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); EXPECT_FALSE(task_runner_->HasPendingTask()); service.Initialize(); EXPECT_FALSE(task_runner_->HasPendingTask()); @@ -188,7 +189,8 @@ ScopedUkmFeatureParams params(base::FeatureList::OVERRIDE_ENABLE_FEATURE, {{"WhitelistEntries", "PageLoad"}}); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(GetPersistedLogCount(), 0); service.Initialize(); @@ -214,7 +216,8 @@ } TEST_F(UkmServiceTest, SourceSerialization) { - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(GetPersistedLogCount(), 0); service.Initialize(); @@ -245,7 +248,8 @@ ScopedUkmFeatureParams params(base::FeatureList::OVERRIDE_ENABLE_FEATURE, {{"WhitelistEntries", "foo,bar"}}); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(0, GetPersistedLogCount()); service.Initialize(); @@ -313,7 +317,8 @@ ScopedUkmFeatureParams params(base::FeatureList::OVERRIDE_ENABLE_FEATURE, {{"WhitelistEntries", "PageLoad"}}); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); ASSERT_EQ(0, GetPersistedLogCount()); service.Initialize(); @@ -336,7 +341,8 @@ ScopedUkmFeatureParams params(base::FeatureList::OVERRIDE_ENABLE_FEATURE, {{"WhitelistEntries", "PageLoad"}}); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); metrics::TestMetricsProvider* provider = new metrics::TestMetricsProvider(); @@ -371,7 +377,8 @@ } TEST_F(UkmServiceTest, LogsRotation) { - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(GetPersistedLogCount(), 0); service.Initialize(); @@ -416,7 +423,8 @@ ScopedUkmFeatureParams params(base::FeatureList::OVERRIDE_ENABLE_FEATURE, {{"WhitelistEntries", "PageLoad"}}); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(GetPersistedLogCount(), 0); service.Initialize(); @@ -477,7 +485,8 @@ {{"RecordInitialUrl", should_record_initial_url ? "true" : "false"}}); ClearPrefs(); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(GetPersistedLogCount(), 0); service.Initialize(); @@ -518,7 +527,8 @@ {"WhitelistEntries", "FakeEntry"}}); ClearPrefs(); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(GetPersistedLogCount(), 0); service.Initialize(); @@ -560,7 +570,8 @@ TEST_F(UkmServiceTest, RecordSessionId) { ClearPrefs(); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(0, GetPersistedLogCount()); service.Initialize(); @@ -586,7 +597,8 @@ {{"MaxSources", "2"}}); ClearPrefs(); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(0, GetPersistedLogCount()); service.Initialize(); @@ -611,7 +623,8 @@ } TEST_F(UkmServiceTest, PurgeMidUpload) { - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(GetPersistedLogCount(), 0); service.Initialize(); @@ -638,7 +651,8 @@ {{"WhitelistEntries", "EntryA,EntryB"}}); ClearPrefs(); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(0, GetPersistedLogCount()); service.Initialize(); @@ -684,7 +698,8 @@ } TEST_F(UkmServiceTest, SourceURLLength) { - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(0, GetPersistedLogCount()); service.Initialize(); @@ -720,7 +735,8 @@ restrict_to_whitelisted_source_ids ? "true" : "false"}}); ClearPrefs(); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(0, GetPersistedLogCount()); service.Initialize(); @@ -838,7 +854,8 @@ for (const auto& test : test_cases) { ClearPrefs(); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); ASSERT_EQ(GetPersistedLogCount(), 0); @@ -923,7 +940,8 @@ for (const auto& test : test_cases) { ClearPrefs(); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(GetPersistedLogCount(), 0); @@ -1014,7 +1032,8 @@ base::FieldTrialList field_trial_list(nullptr /* entropy_provider */); ScopedUkmFeatureParams params(base::FeatureList::OVERRIDE_ENABLE_FEATURE, {}); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); service.SetIsWebstoreExtensionCallback( base::BindRepeating(&TestIsWebstoreExtension)); @@ -1071,7 +1090,8 @@ base::FieldTrialList field_trial_list(nullptr /* entropy_provider */); ScopedUkmFeatureParams params(base::FeatureList::OVERRIDE_ENABLE_FEATURE, {}); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(GetPersistedLogCount(), 0); @@ -1108,7 +1128,8 @@ } TEST_F(UkmServiceTest, SanitizeUrlAuthParams) { - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); EXPECT_EQ(0, GetPersistedLogCount()); service.Initialize(); @@ -1146,7 +1167,8 @@ for (const auto& test : test_cases) { ClearPrefs(); - UkmService service(&prefs_, &client_); + UkmService service(&prefs_, &client_, + true /* restrict_to_whitelisted_entries */); TestRecordingHelper recorder(&service); service.SetIsWebstoreExtensionCallback( base::BindRepeating(&TestIsWebstoreExtension));
diff --git a/components/webrtc_logging/browser/log_cleanup.cc b/components/webrtc_logging/browser/log_cleanup.cc index 2f3fc805..184357d 100644 --- a/components/webrtc_logging/browser/log_cleanup.cc +++ b/components/webrtc_logging/browser/log_cleanup.cc
@@ -25,16 +25,21 @@ // Remove any empty entries from the log list. One line is one log entry, see // WebRtcLogUploader::AddLocallyStoredLogInfoToUploadListFile for more // information about the format. -void RemoveEmptyEntriesInLogList(std::string* log_list) { - static const char kEmptyLine[] = ",,\n"; +void RemoveEmptyEntriesFromLogList(std::string* log_list) { + // TODO(crbug.com/826253): Make this more robust to errors; corrupt entries + // should also be removed. (Better to move away from a .csv altogether.) + static const char kEmptyLineStart[] = ",,,"; // And a timestamp after it. size_t pos = 0; do { - pos = log_list->find(kEmptyLine, pos); + pos = log_list->find(kEmptyLineStart, pos); if (pos == std::string::npos) break; - DCHECK(pos == 0 || (*log_list)[pos - 1] == '\n'); - log_list->erase(pos, arraysize(kEmptyLine) - 1); - } while (true); + const size_t line_end = log_list->find("\n", pos); + DCHECK(line_end == std::string::npos || pos < line_end); + const size_t delete_len = + line_end == std::string::npos ? std::string::npos : line_end - pos + 1; + log_list->erase(pos, delete_len); + } while (pos < log_list->size()); } } // namespace @@ -62,10 +67,18 @@ std::string log_list; const bool update_log_list = base::PathExists(log_list_path); if (update_log_list) { - bool read_ok = base::ReadFileToString(log_list_path, &log_list); - DPCHECK(read_ok); + constexpr size_t kMaxIndexSizeBytes = 1000000; // Intentional overshot. + const bool read_ok = base::ReadFileToStringWithMaxSize( + log_list_path, &log_list, kMaxIndexSizeBytes); + if (!read_ok) { + // If the maximum size was exceeded, updating it will corrupt it. However, + // the size would not be exceeded unless the user edits it manually. + LOG(ERROR) << "Couldn't read WebRTC textual logs list (" << log_list_path + << ")."; + } } + // Delete relevant logs files (and their associated entries in the index). base::FileEnumerator log_files(log_dir, false, base::FileEnumerator::FILES); bool delete_ok = true; for (base::FilePath name = log_files.Next(); !name.empty(); @@ -73,6 +86,8 @@ if (name == log_list_path) continue; base::FileEnumerator::FileInfo file_info(log_files.GetInfo()); + // TODO(crbug.com/827167): Handle mismatch between timestamps of the .gz + // file and the .meta file, as well as with the index. base::TimeDelta file_age = now - file_info.GetLastModifiedTime(); if (file_age > time_to_keep_logs || (!delete_begin_time.is_max() && @@ -93,7 +108,11 @@ if (!delete_ok) LOG(WARNING) << "Could not delete all old WebRTC logs."; - RemoveEmptyEntriesInLogList(&log_list); + // TODO(crbug.com/826254): Purge index file separately, too, to ensure + // entries for logs whose files were manually removed, are also subject + // to expiry and browsing data clearing. + + RemoveEmptyEntriesFromLogList(&log_list); if (update_log_list) { int written = base::WriteFile(log_list_path, &log_list[0], log_list.size());
diff --git a/components/webrtc_logging/browser/log_cleanup.h b/components/webrtc_logging/browser/log_cleanup.h index dc8fdd9..704d9d5 100644 --- a/components/webrtc_logging/browser/log_cleanup.h +++ b/components/webrtc_logging/browser/log_cleanup.h
@@ -12,14 +12,19 @@ namespace webrtc_logging { -// Deletes logs files older that 5 days. Updates the log file list. Must be -// called on the FILE thread. +// Deletes logs files older that 5 days. Updates the log file list. +// Must be called on a task runner that's allowed to block. +// TODO(crbug.com/826221): Only call on the same task runner as where writing +// is done. void DeleteOldWebRtcLogFiles(const base::FilePath& log_dir); // Deletes logs files older that 5 days and logs younger than // |delete_begin_time|. Updates the log file list. If |delete_begin_time| is // base::time::Max(), no recent logs will be deleted, and the function is -// equal to DeleteOldWebRtcLogFiles(). Must be called on the FILE thread. +// equal to DeleteOldWebRtcLogFiles(). +// Must be called on a task runner that's allowed to block. +// TODO(crbug.com/826221): Only call on the same task runner as where writing +// is done. void DeleteOldAndRecentWebRtcLogFiles(const base::FilePath& log_dir, const base::Time& delete_begin_time);
diff --git a/components/webrtc_logging/browser/log_cleanup_unittest.cc b/components/webrtc_logging/browser/log_cleanup_unittest.cc index 5d6ec15..1de8bdd 100644 --- a/components/webrtc_logging/browser/log_cleanup_unittest.cc +++ b/components/webrtc_logging/browser/log_cleanup_unittest.cc
@@ -73,4 +73,6 @@ VerifyFiles(1); } +// TODO(crbug.com/826251): Write tests for the index file. + } // namespace webrtc_logging
diff --git a/content/browser/blob_storage/blob_dispatcher_host.cc b/content/browser/blob_storage/blob_dispatcher_host.cc index 4b81c8b..9de9c3f 100644 --- a/content/browser/blob_storage/blob_dispatcher_host.cc +++ b/content/browser/blob_storage/blob_dispatcher_host.cc
@@ -90,25 +90,6 @@ public_blob_urls_.insert(public_url); } -namespace { - -void RevokePublicBlobURLHelperIO( - scoped_refptr<ChromeBlobStorageContext> context, - const GURL& public_url) { - context->context()->RevokePublicBlobURL(public_url); -} - -void RevokePublicBlobURLHelperUI( - scoped_refptr<ChromeBlobStorageContext> context, - const GURL& public_url) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); - BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, - base::BindOnce(&RevokePublicBlobURLHelperIO, - std::move(context), public_url)); -} - -} // namespace - void BlobDispatcherHost::OnRevokePublicBlobURL(const GURL& public_url) { DCHECK_CURRENTLY_ON(BrowserThread::IO); if (!public_url.is_valid()) { @@ -123,10 +104,8 @@ BDH_TRACING_ENUM_LAST); return; } + context()->RevokePublicBlobURL(public_url); public_blob_urls_.erase(public_url); - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::BindOnce(&RevokePublicBlobURLHelperUI, - blob_storage_context_, public_url)); } storage::BlobStorageContext* BlobDispatcherHost::context() {
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc index 3379b8a..bf9f57f 100644 --- a/content/browser/browser_child_process_host_impl.cc +++ b/content/browser/browser_child_process_host_impl.cc
@@ -262,6 +262,7 @@ *base::CommandLine::ForCurrentProcess(); static const char* const kForwardSwitches[] = { service_manager::switches::kDisableInProcessStackTraces, + switches::kDisableBackgroundTasks, switches::kDisableLogging, switches::kEnableLogging, switches::kIPCConnectionTimeout,
diff --git a/content/browser/devtools/browser_devtools_agent_host.cc b/content/browser/devtools/browser_devtools_agent_host.cc index ea9984b..bd0c470 100644 --- a/content/browser/devtools/browser_devtools_agent_host.cc +++ b/content/browser/devtools/browser_devtools_agent_host.cc
@@ -66,10 +66,8 @@ session->AddHandler(base::WrapUnique(new protocol::SystemInfoHandler())); session->AddHandler(base::WrapUnique(new protocol::TetheringHandler( socket_callback_, tethering_task_runner_))); - session->AddHandler(base::WrapUnique(new protocol::TracingHandler( - protocol::TracingHandler::Browser, - FrameTreeNode::kFrameTreeNodeInvalidId, - GetIOContext()))); + session->AddHandler( + base::WrapUnique(new protocol::TracingHandler(nullptr, GetIOContext()))); return true; }
diff --git a/content/browser/devtools/protocol/tracing_handler.cc b/content/browser/devtools/protocol/tracing_handler.cc index 96336dc8..f1d2104 100644 --- a/content/browser/devtools/protocol/tracing_handler.cc +++ b/content/browser/devtools/protocol/tracing_handler.cc
@@ -28,6 +28,9 @@ #include "content/browser/devtools/devtools_frame_trace_recorder_for_viz.h" #include "content/browser/devtools/devtools_io_context.h" #include "content/browser/devtools/devtools_session.h" +#include "content/browser/frame_host/frame_tree.h" +#include "content/browser/frame_host/frame_tree_node.h" +#include "content/browser/frame_host/navigation_handle_impl.h" #include "content/browser/frame_host/render_frame_host_impl.h" #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/browser/tracing/tracing_controller_impl.h" @@ -144,15 +147,56 @@ base::WeakPtr<TracingHandler> tracing_handler_; }; +std::string GetProcessHostHex(RenderProcessHost* host) { + return base::StringPrintf("0x%" PRIxPTR, reinterpret_cast<uintptr_t>(host)); +} + +void SendProcessReadyInBrowserEvent(const base::UnguessableToken& frame_token, + RenderProcessHost* host) { + auto data = std::make_unique<base::trace_event::TracedValue>(); + data->SetString("frame", frame_token.ToString()); + data->SetString("processPseudoId", GetProcessHostHex(host)); + data->SetInteger("processId", + static_cast<int>(base::GetProcId(host->GetHandle()))); + TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), + "ProcessReadyInBrowser", TRACE_EVENT_SCOPE_THREAD, + "data", std::move(data)); +} + +void FillFrameData(base::trace_event::TracedValue* data, + FrameTreeNode* node, + RenderFrameHostImpl* frame_host, + const GURL& url) { + url::Replacements<char> strip_fragment; + strip_fragment.ClearRef(); + data->SetString("frame", node->devtools_frame_token().ToString()); + data->SetString("url", url.ReplaceComponents(strip_fragment).spec()); + data->SetString("name", node->frame_name()); + if (node->parent()) + data->SetString("parent", + node->parent()->devtools_frame_token().ToString()); + if (frame_host) { + RenderProcessHost* process_host = frame_host->GetProcess(); + base::ProcessId process_id = base::GetProcId(process_host->GetHandle()); + if (process_id == base::kNullProcessId) { + data->SetString("processPseudoId", GetProcessHostHex(process_host)); + frame_host->GetProcess()->PostTaskWhenProcessIsReady( + base::BindOnce(&SendProcessReadyInBrowserEvent, + node->devtools_frame_token(), process_host)); + } else { + // Cast process id to int to be compatible with tracing. + data->SetInteger("processId", static_cast<int>(process_id)); + } + } +} + } // namespace -TracingHandler::TracingHandler(TracingHandler::Target target, - int frame_tree_node_id, +TracingHandler::TracingHandler(FrameTreeNode* frame_tree_node_, DevToolsIOContext* io_context) : DevToolsDomainHandler(Tracing::Metainfo::domainName), - target_(target), io_context_(io_context), - frame_tree_node_id_(frame_tree_node_id), + frame_tree_node_(frame_tree_node_), did_initiate_recording_(false), return_as_stream_(false), gzip_compression_(false), @@ -343,7 +387,7 @@ // If inspected target is a render process Tracing.start will be handled by // tracing agent in the renderer. - if (target_ == Renderer) + if (frame_tree_node_) callback->fallThrough(); TracingController::GetInstance()->StartTracing( @@ -380,7 +424,7 @@ } // If inspected target is a render process Tracing.end will be handled by // tracing agent in the renderer. - if (target_ == Renderer) + if (frame_tree_node_) callback->fallThrough(); else callback->sendSuccess(); @@ -396,10 +440,9 @@ void TracingHandler::OnRecordingEnabled( std::unique_ptr<StartCallback> callback) { - TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), - "TracingStartedInBrowser", TRACE_EVENT_SCOPE_THREAD, - "frameTreeNodeId", frame_tree_node_id_); - if (target_ != Renderer) + EmitFrameTree(); + + if (!frame_tree_node_) callback->sendSuccess(); bool screenshot_enabled; @@ -489,6 +532,53 @@ return TracingController::GetInstance()->IsTracing(); } +void TracingHandler::EmitFrameTree() { + auto data = std::make_unique<base::trace_event::TracedValue>(); + if (frame_tree_node_) { + data->SetInteger("frameTreeNodeId", frame_tree_node_->frame_tree_node_id()); + data->SetBoolean("persistentIds", true); + data->BeginArray("frames"); + FrameTree::NodeRange subtree = + frame_tree_node_->frame_tree()->SubtreeNodes(frame_tree_node_); + for (FrameTreeNode* node : subtree) { + data->BeginDictionary(); + FillFrameData(data.get(), node, node->current_frame_host(), + node->current_url()); + data->EndDictionary(); + } + data->EndArray(); + } + TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), + "TracingStartedInBrowser", TRACE_EVENT_SCOPE_THREAD, + "data", std::move(data)); +} + +void TracingHandler::ReadyToCommitNavigation( + NavigationHandleImpl* navigation_handle) { + if (!did_initiate_recording_) + return; + auto data = std::make_unique<base::trace_event::TracedValue>(); + FillFrameData(data.get(), navigation_handle->frame_tree_node(), + navigation_handle->GetRenderFrameHost(), + navigation_handle->GetURL()); + TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), + "FrameCommittedInBrowser", TRACE_EVENT_SCOPE_THREAD, + "data", std::move(data)); +} + +void TracingHandler::FrameDeleted(RenderFrameHostImpl* frame_host) { + if (!did_initiate_recording_) + return; + auto data = std::make_unique<base::trace_event::TracedValue>(); + data->SetString( + "frame", + frame_host->frame_tree_node()->devtools_frame_token().ToString()); + TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("devtools.timeline"), + "FrameDeletedInBrowser", TRACE_EVENT_SCOPE_THREAD, + "data", std::move(data)); +} + +// static bool TracingHandler::IsStartupTracingActive() { return ::tracing::TraceConfigFile::GetInstance()->IsEnabled(); }
diff --git a/content/browser/devtools/protocol/tracing_handler.h b/content/browser/devtools/protocol/tracing_handler.h index 8515e3a..8383129 100644 --- a/content/browser/devtools/protocol/tracing_handler.h +++ b/content/browser/devtools/protocol/tracing_handler.h
@@ -31,14 +31,14 @@ class DevToolsAgentHostImpl; class DevToolsFrameTraceRecorderForViz; class DevToolsIOContext; +class FrameTreeNode; +class NavigationHandleImpl; namespace protocol { class TracingHandler : public DevToolsDomainHandler, public Tracing::Backend { public: - enum Target { Browser, Renderer }; - CONTENT_EXPORT TracingHandler(Target target, - int frame_tree_node_id, + CONTENT_EXPORT TracingHandler(FrameTreeNode* frame_tree_node, DevToolsIOContext* io_context); CONTENT_EXPORT ~TracingHandler() override; @@ -69,6 +69,8 @@ Response RecordClockSyncMarker(const std::string& sync_id) override; bool did_initiate_recording() { return did_initiate_recording_; } + void ReadyToCommitNavigation(NavigationHandleImpl* navigation_handle); + void FrameDeleted(RenderFrameHostImpl* frame_host); private: friend class TracingHandlerTest; @@ -102,17 +104,17 @@ const scoped_refptr<TracingController::TraceDataEndpoint>& endpoint, const std::string& agent_label); bool IsTracing() const; + void EmitFrameTree(); static bool IsStartupTracingActive(); CONTENT_EXPORT static base::trace_event::TraceConfig GetTraceConfigFromDevToolsConfig( const base::DictionaryValue& devtools_config); std::unique_ptr<base::Timer> buffer_usage_poll_timer_; - Target target_; std::unique_ptr<Tracing::Frontend> frontend_; DevToolsIOContext* io_context_; - int frame_tree_node_id_; + FrameTreeNode* frame_tree_node_; bool did_initiate_recording_; bool return_as_stream_; bool gzip_compression_;
diff --git a/content/browser/devtools/protocol/tracing_handler_unittest.cc b/content/browser/devtools/protocol/tracing_handler_unittest.cc index 5af1a8d..a3927429 100644 --- a/content/browser/devtools/protocol/tracing_handler_unittest.cc +++ b/content/browser/devtools/protocol/tracing_handler_unittest.cc
@@ -72,8 +72,7 @@ class TracingHandlerTest : public testing::Test { public: void SetUp() override { - tracing_handler_.reset( - new TracingHandler(TracingHandler::Browser, 0, nullptr)); + tracing_handler_.reset(new TracingHandler(nullptr, nullptr)); } void TearDown() override { tracing_handler_.reset(); }
diff --git a/content/browser/devtools/render_frame_devtools_agent_host.cc b/content/browser/devtools/render_frame_devtools_agent_host.cc index f2171cb3..3fd83a1 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host.cc
@@ -392,13 +392,13 @@ session->AddHandler(base::WrapUnique( new protocol::TargetHandler(false /* browser_only */))); } - session->AddHandler(base::WrapUnique(new protocol::TracingHandler( - protocol::TracingHandler::Renderer, - frame_tree_node_ ? frame_tree_node_->frame_tree_node_id() : 0, - GetIOContext()))); session->AddHandler( base::WrapUnique(new protocol::PageHandler(emulation_handler))); session->AddHandler(base::WrapUnique(new protocol::SecurityHandler())); + if (!frame_tree_node_ || !frame_tree_node_->parent()) { + session->AddHandler(base::WrapUnique( + new protocol::TracingHandler(frame_tree_node_, GetIOContext()))); + } if (EnsureAgent()) session->AttachToAgent(agent_ptr_); @@ -466,6 +466,9 @@ NavigationHandle* navigation_handle) { NavigationHandleImpl* handle = static_cast<NavigationHandleImpl*>(navigation_handle); + for (auto* tracing : protocol::TracingHandler::ForAgentHost(this)) + tracing->ReadyToCommitNavigation(handle); + if (handle->frame_tree_node() != frame_tree_node_) { if (ShouldForceCreation() && handle->GetRenderFrameHost() && handle->GetRenderFrameHost()->IsCrossProcessSubframe()) { @@ -611,9 +614,12 @@ } void RenderFrameDevToolsAgentHost::FrameDeleted(RenderFrameHost* rfh) { - if (static_cast<RenderFrameHostImpl*>(rfh)->frame_tree_node() == - frame_tree_node_) { - DestroyOnRenderFrameGone(); // |this| may be deleted at this point. + RenderFrameHostImpl* host = static_cast<RenderFrameHostImpl*>(rfh); + for (auto* tracing : protocol::TracingHandler::ForAgentHost(this)) + tracing->FrameDeleted(host); + if (host->frame_tree_node() == frame_tree_node_) { + DestroyOnRenderFrameGone(); + // |this| may be deleted at this point. } }
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index a0eabb72..4fcc36fb 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc
@@ -2901,8 +2901,8 @@ ASSERT_TRUE(server.ShutdownAndWaitUntilComplete()); } -// A request for a non-existent resource should result in an aborted navigation, -// and the old site staying current. +// A request for a non-existent same-origin resource should result in a +// DownloadItem that's created in an interrupted state. IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeServerError) { GURL download_url = embedded_test_server()->GetURL("/download/does-not-exist"); @@ -2910,15 +2910,16 @@ std::string("/download/download-attribute.html?target=") + download_url.spec()); - auto observer = std::make_unique<content::TestNavigationObserver>( - shell()->web_contents(), 2); - NavigateToURL(shell(), document_url); - observer->Wait(); - EXPECT_FALSE(observer->last_navigation_succeeded()); + download::DownloadItem* download = + StartDownloadAndReturnItem(shell(), document_url); + WaitForInterrupt(download); + + EXPECT_EQ(download::DOWNLOAD_INTERRUPT_REASON_SERVER_BAD_CONTENT, + download->GetLastReason()); } -// A request that fails before it gets a response from the server should also -// result in the old page staying current. +// A cross-origin request that fails before it gets a response from the server +// should result in the old page staying current. IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadAttributeNetworkError) { SetupErrorInjectionDownloads(); GURL url = TestDownloadHttpResponse::GetNextURLForDownload();
diff --git a/content/browser/renderer_host/input/touch_action_filter.cc b/content/browser/renderer_host/input/touch_action_filter.cc index 0c8cec82..6077595 100644 --- a/content/browser/renderer_host/input/touch_action_filter.cc +++ b/content/browser/renderer_host/input/touch_action_filter.cc
@@ -39,8 +39,7 @@ drop_current_tap_ending_event_(false), allow_current_double_tap_event_(true), force_enable_zoom_(false), - allowed_touch_action_(cc::kTouchActionAuto), - white_listed_touch_action_(cc::kTouchActionAuto) {} + allowed_touch_action_(cc::kTouchActionAuto) {} bool TouchActionFilter::FilterGestureEvent(WebGestureEvent* gesture_event) { if (gesture_event->SourceDevice() != blink::kWebGestureDeviceTouchscreen) @@ -192,8 +191,11 @@ // Report how often the effective touch action computed by blink is or is // not equivalent to the whitelisted touch action computed by the // compositor. - UMA_HISTOGRAM_BOOLEAN("TouchAction.EquivalentEffectiveAndWhiteListed", - allowed_touch_action_ == white_listed_touch_action_); + if (white_listed_touch_action_.has_value()) { + UMA_HISTOGRAM_BOOLEAN( + "TouchAction.EquivalentEffectiveAndWhiteListed", + allowed_touch_action_ == white_listed_touch_action_.value()); + } ResetTouchAction(); } @@ -201,22 +203,19 @@ // Note that resetting the action mid-sequence is tolerated. Gestures that had // their begin event(s) suppressed will be suppressed until the next sequence. allowed_touch_action_ = cc::kTouchActionAuto; - white_listed_touch_action_ = cc::kTouchActionAuto; + white_listed_touch_action_.reset(); } void TouchActionFilter::OnSetWhiteListedTouchAction( cc::TouchAction white_listed_touch_action) { - // For multiple fingers, we take the intersection of the touch actions for all - // fingers that have gone down during this action. In the majority of - // real-world scenarios the touch action for all fingers will be the same. - // This is left as implementation because of the relationship of gestures - // (which are off limits for the spec). We believe the following are - // desirable properties of this choice: - // 1. Not sensitive to finger touch order. Behavior of putting two fingers - // down "at once" will be deterministic. - // 2. Only subtractive - eg. can't trigger scrolling on an element that - // otherwise has scrolling disabling by the addition of a finger. - white_listed_touch_action_ &= white_listed_touch_action; + // We use '&' here to account for the multiple-finger case, which is the same + // as OnSetTouchAction. + if (white_listed_touch_action_.has_value()) { + white_listed_touch_action_ = + white_listed_touch_action_.value() & white_listed_touch_action; + } else { + white_listed_touch_action_ = white_listed_touch_action; + } } bool TouchActionFilter::ShouldSuppressManipulation(
diff --git a/content/browser/renderer_host/input/touch_action_filter.h b/content/browser/renderer_host/input/touch_action_filter.h index d2c0061..fd6d5e6 100644 --- a/content/browser/renderer_host/input/touch_action_filter.h +++ b/content/browser/renderer_host/input/touch_action_filter.h
@@ -6,6 +6,7 @@ #define CONTENT_BROWSER_RENDERER_HOST_INPUT_TOUCH_ACTION_FILTER_H_ #include "base/macros.h" +#include "base/optional.h" #include "cc/input/touch_action.h" #include "content/common/content_export.h" @@ -80,7 +81,7 @@ cc::TouchAction allowed_touch_action_; // Whitelisted touch action received from the compositor. - cc::TouchAction white_listed_touch_action_; + base::Optional<cc::TouchAction> white_listed_touch_action_; DISALLOW_COPY_AND_ASSIGN(TouchActionFilter); };
diff --git a/content/browser/renderer_host/overscroll_controller.cc b/content/browser/renderer_host/overscroll_controller.cc index 527809b..6a09f92 100644 --- a/content/browser/renderer_host/overscroll_controller.cc +++ b/content/browser/renderer_host/overscroll_controller.cc
@@ -85,6 +85,9 @@ } bool OverscrollController::WillHandleEvent(const blink::WebInputEvent& event) { + if (event.GetType() == blink::WebInputEvent::kGestureScrollBegin) + ignore_following_inertial_events_ = false; + if (!ShouldProcessEvent(event)) return false; @@ -99,6 +102,18 @@ return false; } + // Consume the scroll-update events if they are from a inertial scroll (fling) + // event that completed an overscroll gesture. + if (ignore_following_inertial_events_ && + event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) { + const blink::WebGestureEvent& gesture = + static_cast<const blink::WebGestureEvent&>(event); + if (gesture.data.scroll_update.inertial_phase == + blink::WebGestureEvent::kMomentumPhase) { + return true; + } + } + bool reset_scroll_state = false; if (scroll_state_ != ScrollState::NONE || overscroll_delta_x_ || overscroll_delta_y_) { @@ -199,7 +214,7 @@ ResetScrollState(); } -bool OverscrollController::DispatchEventCompletesAction ( +bool OverscrollController::DispatchEventCompletesAction( const blink::WebInputEvent& event) const { if (overscroll_mode_ == OVERSCROLL_NONE) return false; @@ -209,9 +224,23 @@ // after the threshold. if (event.GetType() != blink::WebInputEvent::kMouseMove && event.GetType() != blink::WebInputEvent::kGestureScrollEnd && - event.GetType() != blink::WebInputEvent::kGestureFlingStart) + event.GetType() != blink::WebInputEvent::kGestureFlingStart && + event.GetType() != blink::WebInputEvent::kGestureScrollUpdate) return false; + // Complete the overscroll gesture for inertial scroll (fling) event from + // touchpad. + if (event.GetType() == blink::WebInputEvent::kGestureScrollUpdate) { + if (overscroll_source_ != OverscrollSource::TOUCHPAD) + return false; + DCHECK(IsGestureEventFromTouchpad(event)); + const blink::WebGestureEvent gesture_event = + static_cast<const blink::WebGestureEvent&>(event); + if (gesture_event.data.scroll_update.inertial_phase != + blink::WebGestureEvent::kMomentumPhase) + return false; + } + if (event.GetType() == blink::WebInputEvent::kGestureScrollEnd && overscroll_source_ == OverscrollSource::TOUCHPAD) { DCHECK(IsGestureEventFromTouchpad(event)); @@ -469,6 +498,7 @@ } void OverscrollController::CompleteAction() { + ignore_following_inertial_events_ = true; if (delegate_) delegate_->OnOverscrollComplete(overscroll_mode_); Reset();
diff --git a/content/browser/renderer_host/overscroll_controller.h b/content/browser/renderer_host/overscroll_controller.h index f32f835..8bb2c25 100644 --- a/content/browser/renderer_host/overscroll_controller.h +++ b/content/browser/renderer_host/overscroll_controller.h
@@ -97,8 +97,7 @@ // Returns true if the event indicates that the in-progress overscroll gesture // can now be completed. - bool DispatchEventCompletesAction( - const blink::WebInputEvent& event) const; + bool DispatchEventCompletesAction(const blink::WebInputEvent& event) const; // Returns true to indicate that dispatching the event should reset the // overscroll gesture status. @@ -158,6 +157,11 @@ bool wheel_scroll_latching_enabled_; + // A inertial scroll (fling) event may complete an overscroll gesture and + // navigate to a new page, but the inertial scroll can continue to generate + // scroll-update events. These events need to be ignored. + bool ignore_following_inertial_events_ = false; + DISALLOW_COPY_AND_ASSIGN(OverscrollController); };
diff --git a/content/browser/renderer_host/overscroll_controller_unittest.cc b/content/browser/renderer_host/overscroll_controller_unittest.cc index db2f3d4..cef55e38 100644 --- a/content/browser/renderer_host/overscroll_controller_unittest.cc +++ b/content/browser/renderer_host/overscroll_controller_unittest.cc
@@ -11,6 +11,7 @@ #include "content/common/input/synthetic_web_input_event_builders.h" #include "content/test/test_overscroll_delegate.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/WebKit/public/platform/WebInputEvent.h" namespace content { @@ -39,15 +40,31 @@ return controller_->WillHandleEvent(*current_event_); } + // Creates and sends a gesture event to the overscroll controller. Returns + // |true| if the event is consumed by the overscroll controller. + bool SimulateGestureEvent(blink::WebInputEvent::Type type, + blink::WebGestureDevice source_device) { + DCHECK(!current_event_); + current_event_ = std::make_unique<blink::WebGestureEvent>( + SyntheticWebGestureEventBuilder::Build(type, source_device)); + return controller_->WillHandleEvent(*current_event_); + } + // Creates and sends a gesture-scroll-update event to the overscroll // controller. Returns |true| if the event is consumed by the overscroll // controller. bool SimulateGestureScrollUpdate(float dx, float dy, - blink::WebGestureDevice device) { + blink::WebGestureDevice device, + bool inertial_update) { DCHECK(!current_event_); - current_event_ = std::make_unique<blink::WebGestureEvent>( + auto event = std::make_unique<blink::WebGestureEvent>( SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, dy, 0, device)); + if (inertial_update) { + event->data.scroll_update.inertial_phase = + blink::WebGestureEvent::kMomentumPhase; + } + current_event_ = std::move(event); return controller_->WillHandleEvent(*current_event_); } @@ -88,8 +105,8 @@ // passing the start threshold, no overscroll should happen. EXPECT_FALSE(SimulateMouseWheel(10, 0)); SimulateAck(false); - EXPECT_FALSE( - SimulateGestureScrollUpdate(10, 0, blink::kWebGestureDeviceTouchpad)); + EXPECT_FALSE(SimulateGestureScrollUpdate( + 10, 0, blink::kWebGestureDeviceTouchpad, false)); SimulateAck(false); EXPECT_EQ(OVERSCROLL_NONE, controller_mode()); EXPECT_EQ(OverscrollSource::NONE, controller_source()); @@ -111,8 +128,8 @@ // marked as processed. EXPECT_FALSE(SimulateMouseWheel(100, 0)); SimulateAck(false); - EXPECT_FALSE( - SimulateGestureScrollUpdate(100, 0, blink::kWebGestureDeviceTouchpad)); + EXPECT_FALSE(SimulateGestureScrollUpdate( + 100, 0, blink::kWebGestureDeviceTouchpad, false)); SimulateAck(false); EXPECT_EQ(OVERSCROLL_NONE, controller_mode()); EXPECT_EQ(OverscrollSource::NONE, controller_source()); @@ -120,4 +137,34 @@ EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode()); } +// Verifying the inertial scroll event completes overscroll. After that we will +// ignore the following inertial scroll events until new sequence start. +TEST_F(OverscrollControllerTest, + InertialGestureScrollUpdateCompletesOverscroll) { + EXPECT_FALSE(SimulateGestureEvent(blink::WebInputEvent::kGestureScrollBegin, + blink::kWebGestureDeviceTouchpad)); + SimulateAck(false); + + EXPECT_FALSE(SimulateGestureScrollUpdate( + 200, 0, blink::kWebGestureDeviceTouchpad, false)); + SimulateAck(false); + EXPECT_EQ(OVERSCROLL_EAST, controller_mode()); + EXPECT_EQ(OverscrollSource::TOUCHPAD, controller_source()); + EXPECT_EQ(OVERSCROLL_EAST, delegate()->current_mode()); + EXPECT_EQ(OVERSCROLL_NONE, delegate()->completed_mode()); + + // Inertial update event complete the overscroll action. + EXPECT_FALSE(SimulateGestureScrollUpdate( + 100, 0, blink::kWebGestureDeviceTouchpad, true)); + SimulateAck(false); + EXPECT_EQ(OVERSCROLL_EAST, controller_mode()); + EXPECT_EQ(OverscrollSource::TOUCHPAD, controller_source()); + EXPECT_EQ(OVERSCROLL_EAST, delegate()->current_mode()); + EXPECT_EQ(OVERSCROLL_EAST, delegate()->completed_mode()); + + // Next Inertial update event would be consumed by overscroll controller. + EXPECT_TRUE(SimulateGestureScrollUpdate( + 100, 0, blink::kWebGestureDeviceTouchpad, true)); +} + } // namespace content
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index d1eed97..6e9c3c18 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2633,6 +2633,7 @@ switches::kDisable2dCanvasImageChromium, switches::kDisableAcceleratedJpegDecoding, switches::kDisableAcceleratedVideoDecode, + switches::kDisableBackgroundTasks, switches::kDisableBackgroundTimerThrottling, switches::kDisableBreakpad, switches::kDisableCompositorUkmForTests,
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc index 7a3d9700..185e633 100644 --- a/content/browser/webauth/authenticator_impl_unittest.cc +++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -45,12 +45,14 @@ using webauth::mojom::MakeCredentialAuthenticatorResponsePtr; using webauth::mojom::PublicKeyCredentialCreationOptions; using webauth::mojom::PublicKeyCredentialCreationOptionsPtr; +using webauth::mojom::PublicKeyCredentialDescriptor; using webauth::mojom::PublicKeyCredentialParameters; using webauth::mojom::PublicKeyCredentialParametersPtr; using webauth::mojom::PublicKeyCredentialRequestOptions; using webauth::mojom::PublicKeyCredentialRequestOptionsPtr; using webauth::mojom::PublicKeyCredentialRpEntity; using webauth::mojom::PublicKeyCredentialRpEntityPtr; +using webauth::mojom::PublicKeyCredentialType; using webauth::mojom::PublicKeyCredentialUserEntity; using webauth::mojom::PublicKeyCredentialUserEntityPtr; @@ -653,6 +655,44 @@ EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, cb.status()); } +TEST_F(AuthenticatorImplTest, OversizedCredentialId) { + device::test::ScopedVirtualFidoDevice virtual_device_; + TestServiceManagerContext smc_; + // 255 is the maximum size of a U2F credential ID. We also test one greater + // (256) to ensure that nothing untoward happens. + const std::vector<size_t> kSizes = {255, 256}; + + for (size_t size : kSizes) { + SCOPED_TRACE(size); + + SimulateNavigation(GURL(kTestOrigin1)); + AuthenticatorPtr authenticator = ConnectToAuthenticator(); + PublicKeyCredentialRequestOptionsPtr options = + GetTestPublicKeyCredentialRequestOptions(); + auto credential = PublicKeyCredentialDescriptor::New(); + credential->type = PublicKeyCredentialType::PUBLIC_KEY; + credential->id.resize(size); + + const bool should_be_valid = size < 256; + if (should_be_valid) { + ASSERT_TRUE(virtual_device_.mutable_state()->InjectRegistration( + credential->id, kTestRelyingPartyId)); + } + + options->allow_credentials.emplace_back(std::move(credential)); + + TestGetAssertionCallback cb; + authenticator->GetAssertion(std::move(options), cb.callback()); + cb.WaitForCallback(); + + if (should_be_valid) { + EXPECT_EQ(AuthenticatorStatus::SUCCESS, cb.status()); + } else { + EXPECT_EQ(AuthenticatorStatus::NOT_ALLOWED_ERROR, cb.status()); + } + } +} + enum class IndividualAttestation { REQUESTED, NOT_REQUESTED,
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java index 0faca8a..c646bab 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCoreImpl.java
@@ -35,7 +35,6 @@ import org.chromium.device.gamepad.GamepadList; import org.chromium.ui.base.EventForwarder; import org.chromium.ui.base.ViewAndroidDelegate; -import org.chromium.ui.base.ViewUtils; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.display.DisplayAndroid; import org.chromium.ui.display.DisplayAndroid.DisplayAndroidObserver; @@ -73,15 +72,20 @@ // A ViewAndroidDelegate that delegates to the current container view. private ViewAndroidDelegate mViewAndroidDelegate; - // TODO(mthiesse): Clean up the focus code here, this boolean doesn't actually reflect view - // focus. It reflects a combination of both view focus and resumed state. + // Whether the container view has view-level focus. private Boolean mHasViewFocus; - // This is used in place of window focus, as we can't actually use window focus due to issues - // where content expects to be focused while a popup steals window focus. + // This is used in place of window focus on the container view, as we can't actually use window + // focus due to issues where content expects to be focused while a popup steals window focus. // See https://crbug.com/686232 for more context. private boolean mPaused; + // Whether we consider this CVC to have input focus. This is computed through mHasViewFocus and + // mPaused. See the comments on mPaused for how this doesn't exactly match Android's notion of + // input focus and why we need to do this. + private Boolean mHasInputFocus; + private boolean mHideKeyboardOnBlur; + // The list of observers that are notified when ContentViewCore changes its WindowAndroid. private final ObserverList<WindowAndroidChangedObserver> mWindowAndroidChangedObservers = new ObserverList<>(); @@ -389,14 +393,16 @@ @Override public void onPause() { + if (mPaused) return; mPaused = true; - onFocusChanged(false, true); + onFocusChanged(); } @Override public void onResume() { + if (!mPaused) return; mPaused = false; - onFocusChanged(ViewUtils.hasFocus(getContainerView()), true); + onFocusChanged(); } @Override @@ -408,12 +414,20 @@ } @Override - public void onFocusChanged(boolean gainFocus, boolean hideKeyboardOnBlur) { + public void onViewFocusChanged(boolean gainFocus) { if (mHasViewFocus != null && mHasViewFocus == gainFocus) return; - // TODO(mthiesse): Clean this up. mHasViewFocus isn't view focus really, it's a combination - // of view focus and resumed state. - if (gainFocus && mPaused) return; mHasViewFocus = gainFocus; + onFocusChanged(); + } + + private void onFocusChanged() { + // Wait for view focus to be set before propagating focus changes. + if (mHasViewFocus == null) return; + + // See the comments on mPaused for why we use it to compute input focus. + boolean hasInputFocus = mHasViewFocus && !mPaused; + if (mHasInputFocus != null && mHasInputFocus == hasInputFocus) return; + mHasInputFocus = hasInputFocus; if (mWebContents == null) { // CVC is on its way to destruction. The rest needs not running as all the states @@ -422,12 +436,12 @@ return; } - getImeAdapter().onViewFocusChanged(gainFocus, hideKeyboardOnBlur); + getImeAdapter().onViewFocusChanged(mHasInputFocus, mHideKeyboardOnBlur); getJoystick().setScrollEnabled( - gainFocus && !getSelectionPopupController().isFocusedNodeEditable()); + mHasInputFocus && !getSelectionPopupController().isFocusedNodeEditable()); SelectionPopupControllerImpl controller = getSelectionPopupController(); - if (gainFocus) { + if (mHasInputFocus) { controller.restoreSelectionPopupsIfNecessary(); } else { getImeAdapter().cancelRequestToScrollFocusedEditableNodeIntoView(); @@ -442,7 +456,12 @@ controller.clearSelection(); } } - if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, gainFocus); + if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, mHasInputFocus); + } + + @Override + public void setHideKeyboardOnBlur(boolean hideKeyboardOnBlur) { + mHideKeyboardOnBlur = hideKeyboardOnBlur; } @Override
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content_public/browser/ContentViewCore.java index 792ca034..c134d3f8 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ContentViewCore.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ContentViewCore.java
@@ -199,11 +199,16 @@ void onResume(); /** - * Called when keyboard/IME focus has changed. + * Called when view-level focus for the container view has changed. * @param gainFocus {@code true} if the focus is gained, otherwise {@code false}. + */ + void onViewFocusChanged(boolean gainFocus); + + /** + * Sets whether the keyboard should be hidden when losing input focus. * @param hideKeyboardOnBlur {@code true} if we should hide soft keyboard when losing focus. */ - void onFocusChanged(boolean gainFocus, boolean hideKeyboardOnBlur); + void setHideKeyboardOnBlur(boolean hideKeyboardOnBlur); /** * @see View#scrollBy(int, int)
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 877da992..154a7c26 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
@@ -893,7 +893,7 @@ ThreadUtils.runOnUiThreadBlocking(new Runnable() { @Override public void run() { - contentViewCore.onFocusChanged(gainFocus, true); + contentViewCore.onViewFocusChanged(gainFocus); } }); }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/PopupZoomerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/PopupZoomerTest.java index df35db2..a7c55d1 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/PopupZoomerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/PopupZoomerTest.java
@@ -234,7 +234,7 @@ Assert.assertTrue(mPopupZoomer.isShowing()); // Simulate losing the focus. - mContentViewCore.onFocusChanged(false, true); + mContentViewCore.onViewFocusChanged(false); // Wait for the hide animation to finish. mPopupZoomer.finishPendingDraws();
diff --git a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestContentViewCore.java b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestContentViewCore.java index daa04100..507bfb7 100644 --- a/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestContentViewCore.java +++ b/content/public/test/android/javatests/src/org/chromium/content/browser/test/util/TestContentViewCore.java
@@ -86,7 +86,10 @@ public void onResume() {} @Override - public void onFocusChanged(boolean gainFocus, boolean hideKeyboardOnBlur) {} + public void onViewFocusChanged(boolean gainFocus) {} + + @Override + public void setHideKeyboardOnBlur(boolean hideKeyboardOnBlur) {} @Override public void scrollBy(float dxPix, float dyPix) {}
diff --git a/content/renderer/dom_storage/dom_storage_cached_area.cc b/content/renderer/dom_storage/dom_storage_cached_area.cc index 654ed9e..18215ac 100644 --- a/content/renderer/dom_storage/dom_storage_cached_area.cc +++ b/content/renderer/dom_storage/dom_storage_cached_area.cc
@@ -73,8 +73,9 @@ // Ignore mutations to 'key' until OnSetItemComplete. blink::WebScopedVirtualTimePauser virtual_time_pauser = - main_thread_scheduler_->CreateWebScopedVirtualTimePauser(); - virtual_time_pauser.PauseVirtualTime(true); + main_thread_scheduler_->CreateWebScopedVirtualTimePauser( + "DOMStorageCachedArea"); + virtual_time_pauser.PauseVirtualTime(); ignore_key_mutations_[key]++; proxy_->SetItem(connection_id, key, value, old_value, page_url, base::BindOnce(&DOMStorageCachedArea::OnSetItemComplete, @@ -100,8 +101,9 @@ // Ignore mutations to 'key' until OnRemoveItemComplete. blink::WebScopedVirtualTimePauser virtual_time_pauser = - main_thread_scheduler_->CreateWebScopedVirtualTimePauser(); - virtual_time_pauser.PauseVirtualTime(true); + main_thread_scheduler_->CreateWebScopedVirtualTimePauser( + "DOMStorageCachedArea"); + virtual_time_pauser.PauseVirtualTime(); ignore_key_mutations_[key]++; proxy_->RemoveItem(connection_id, key, base::NullableString16(old_value, false), page_url, @@ -117,8 +119,9 @@ // Ignore all mutations until OnClearComplete time. blink::WebScopedVirtualTimePauser virtual_time_pauser = - main_thread_scheduler_->CreateWebScopedVirtualTimePauser(); - virtual_time_pauser.PauseVirtualTime(true); + main_thread_scheduler_->CreateWebScopedVirtualTimePauser( + "DOMStorageCachedArea"); + virtual_time_pauser.PauseVirtualTime(); ignore_all_mutations_ = true; proxy_->ClearArea(connection_id, page_url, base::BindOnce(&DOMStorageCachedArea::OnClearComplete,
diff --git a/content/renderer/dom_storage/local_storage_cached_area.cc b/content/renderer/dom_storage/local_storage_cached_area.cc index d079a6c..fc605cce 100644 --- a/content/renderer/dom_storage/local_storage_cached_area.cc +++ b/content/renderer/dom_storage/local_storage_cached_area.cc
@@ -162,8 +162,9 @@ String16ToUint8Vector(old_nullable_value.string(), is_session_storage); blink::WebScopedVirtualTimePauser virtual_time_pauser = - main_thread_scheduler_->CreateWebScopedVirtualTimePauser(); - virtual_time_pauser.PauseVirtualTime(true); + main_thread_scheduler_->CreateWebScopedVirtualTimePauser( + "LocalStorageCachedArea"); + virtual_time_pauser.PauseVirtualTime(); leveldb_->Put(String16ToUint8Vector(key, is_session_storage), String16ToUint8Vector(value, is_session_storage), optional_old_value, PackSource(page_url, storage_area_id), @@ -194,8 +195,9 @@ optional_old_value = String16ToUint8Vector(old_value, is_session_storage); blink::WebScopedVirtualTimePauser virtual_time_pauser = - main_thread_scheduler_->CreateWebScopedVirtualTimePauser(); - virtual_time_pauser.PauseVirtualTime(true); + main_thread_scheduler_->CreateWebScopedVirtualTimePauser( + "LocalStorageCachedArea"); + virtual_time_pauser.PauseVirtualTime(); leveldb_->Delete(String16ToUint8Vector(key, is_session_storage), optional_old_value, PackSource(page_url, storage_area_id), base::BindOnce(&LocalStorageCachedArea::OnRemoveItemComplete, @@ -211,8 +213,9 @@ ignore_all_mutations_ = true; blink::WebScopedVirtualTimePauser virtual_time_pauser = - main_thread_scheduler_->CreateWebScopedVirtualTimePauser(); - virtual_time_pauser.PauseVirtualTime(true); + main_thread_scheduler_->CreateWebScopedVirtualTimePauser( + "LocalStorageCachedArea"); + virtual_time_pauser.PauseVirtualTime(); leveldb_->DeleteAll(PackSource(page_url, storage_area_id), base::BindOnce(&LocalStorageCachedArea::OnClearComplete, weak_factory_.GetWeakPtr(),
diff --git a/content/renderer/media/webrtc/rtc_peer_connection_handler.cc b/content/renderer/media/webrtc/rtc_peer_connection_handler.cc index c4013c92..a7dde19 100644 --- a/content/renderer/media/webrtc/rtc_peer_connection_handler.cc +++ b/content/renderer/media/webrtc/rtc_peer_connection_handler.cc
@@ -766,6 +766,12 @@ static_cast<webrtc::KeyExchangeProtocolMedia>(counter), webrtc::kEnumCounterKeyProtocolMediaTypeMax); break; + case webrtc::kEnumCounterSdpFormatReceived: + UMA_HISTOGRAM_ENUMERATION( + "WebRTC.PeerConnection.SdpFormatReceived", + static_cast<webrtc::SdpFormatReceived>(counter), + webrtc::kSdpFormatReceivedMax); + break; default: // The default clause is expected to be reached when new enum types are // added.
diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 2a9520e..d7102e0 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc
@@ -1566,13 +1566,14 @@ RenderThreadImpl::current() ->GetWebMainThreadScheduler() ->CreateWebScopedVirtualTimePauser( + "NavigateBackForwardSoon", blink::WebScopedVirtualTimePauser::VirtualTaskDuration::kInstant); - history_navigation_virtual_time_pauser_.PauseVirtualTime(true); + history_navigation_virtual_time_pauser_.PauseVirtualTime(); Send(new ViewHostMsg_GoToEntryAtOffset(GetRoutingID(), offset)); } void RenderViewImpl::DidCommitProvisionalHistoryLoad() { - history_navigation_virtual_time_pauser_.PauseVirtualTime(false); + history_navigation_virtual_time_pauser_.UnpauseVirtualTime(); } int RenderViewImpl::HistoryBackListCount() {
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc index 47f6df7c..e4cedaf 100644 --- a/content/renderer/render_widget.cc +++ b/content/renderer/render_widget.cc
@@ -391,7 +391,6 @@ closing_(false), host_closing_(false), is_swapped_out_(swapped_out), - for_oopif_(false), text_input_type_(ui::TEXT_INPUT_TYPE_NONE), text_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT), text_input_flags_(0), @@ -408,6 +407,7 @@ has_host_context_menu_location_(false), has_added_input_handler_(false), has_focus_(false), + for_oopif_(false), #if defined(OS_MACOSX) text_input_client_observer_(new TextInputClientObserver(this)), #endif
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 94d077a..19740fc6 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -778,9 +778,6 @@ // swapped out, the process can exit. bool is_swapped_out_; - // Whether this RenderWidget is for an out-of-process iframe or not. - bool for_oopif_; - // Stores information about the current text input. blink::WebTextInputInfo text_input_info_; @@ -945,6 +942,9 @@ // Indicates whether this widget has focus. bool has_focus_; + // Whether this RenderWidget is for an out-of-process iframe or not. + bool for_oopif_; + // A callback into the creator/opener of this widget, to be executed when // WebWidgetClient::show() occurs. ShowCallback show_callback_;
diff --git a/content/shell/app/blink_test_platform_support_mac.mm b/content/shell/app/blink_test_platform_support_mac.mm index 7a16563..6ec3e9b 100644 --- a/content/shell/app/blink_test_platform_support_mac.mm +++ b/content/shell/app/blink_test_platform_support_mac.mm
@@ -42,6 +42,10 @@ forKey:@"NSScrollAnimationEnabled"]; [defaults setObject:@"Always" forKey:@"AppleShowScrollBars"]; + + // Disable AppNap since layout tests do not always meet the requirements to + // avoid "napping" which will cause test timeouts. http://crbug.com/811525. + [defaults setBool:YES forKey:@"NSAppSleepDisabled"]; } } // namespace
diff --git a/content/test/gpu/gpu_tests/pixel_expectations.py b/content/test/gpu/gpu_tests/pixel_expectations.py index bb117de8..63bdd9d 100644 --- a/content/test/gpu/gpu_tests/pixel_expectations.py +++ b/content/test/gpu/gpu_tests/pixel_expectations.py
@@ -139,3 +139,6 @@ self.Fail('Pixel_WebGLGreenTriangle_NoAA_NoAlpha', ['android'], bug=972546) self.Fail('Pixel_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear', ['android'], bug=972546) + + # TODO(hubbe): Temporary supression for rebaseline + self.Fail('Pixel_Video_VP9', bug=754986)
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py index 023d63b..6532afac 100644 --- a/content/test/gpu/gpu_tests/pixel_test_pages.py +++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -185,7 +185,7 @@ 'pixel_video_vp9.html', base_name + '_Video_VP9', test_rect=[0, 0, 300, 300], - revision=7), + revision=8), PixelTestPage( 'pixel_webgl_premultiplied_alpha_false.html',
diff --git a/device/BUILD.gn b/device/BUILD.gn index 81d675d..c8d8df92 100644 --- a/device/BUILD.gn +++ b/device/BUILD.gn
@@ -277,6 +277,7 @@ "//device/vr/public/mojom", "//services/device/public/cpp/generic_sensor", "//ui/display", + "//ui/display:test_support", ] } }
diff --git a/device/bluetooth/public/mojom/test/fake_bluetooth.mojom b/device/bluetooth/public/mojom/test/fake_bluetooth.mojom index 6596473..8bd0d334 100644 --- a/device/bluetooth/public/mojom/test/fake_bluetooth.mojom +++ b/device/bluetooth/public/mojom/test/fake_bluetooth.mojom
@@ -288,6 +288,28 @@ string service_id, string peripheral_address) => (bool success); + // Sets the next unsubscribe from notifications response for characteristic + // with |characteristic_id| in |service_id| and in |peripheral_address| to + // |code|. |code| could be a GATT Error Response from BT 4.2 Vol 3 + // Part F 3.4.1.1 Error Response or a number outside that range returned by + // specific platforms e.g. Android returns 0x101 to signal a GATT failure. + // https://developer.android.com/reference/android/bluetooth/BluetoothGatt.html#GATT_FAILURE + // Calls callback with false if there was any error when simulating the next + // response. + SetNextUnsubscribeFromNotificationsResponse( + uint16 gatt_code, + string characteristic_id, + string service_id, + string peripheral_address) => (bool success); + + // Returns whether or not a client has subscribed to notifications for a + // characteristic with |characteristic_id| in |service_id| in + // |peripheral_address|. If the value can't be retrieved, calls its callback + // with false. + IsNotifying(string characteristic_id, + string service_id, + string peripheral_address) => (bool success, bool is_notifying); + // Gets the last successfully written value to the characteristic with // |characteristics_id| in |service_id| and in |peripheral_address|. // If the value can't be retrieved calls its callback with false. Calls its
diff --git a/device/bluetooth/test/fake_central.cc b/device/bluetooth/test/fake_central.cc index 1b5fdc0..151e931 100644 --- a/device/bluetooth/test/fake_central.cc +++ b/device/bluetooth/test/fake_central.cc
@@ -317,6 +317,38 @@ std::move(callback).Run(true); } +void FakeCentral::SetNextUnsubscribeFromNotificationsResponse( + uint16_t gatt_code, + const std::string& characteristic_id, + const std::string& service_id, + const std::string& peripheral_address, + SetNextUnsubscribeFromNotificationsResponseCallback callback) { + FakeRemoteGattCharacteristic* fake_remote_gatt_characteristic = + GetFakeRemoteGattCharacteristic(peripheral_address, service_id, + characteristic_id); + if (fake_remote_gatt_characteristic == nullptr) { + std::move(callback).Run(false); + } + + fake_remote_gatt_characteristic->SetNextUnsubscribeFromNotificationsResponse( + gatt_code); + std::move(callback).Run(true); +} + +void FakeCentral::IsNotifying(const std::string& characteristic_id, + const std::string& service_id, + const std::string& peripheral_address, + IsNotifyingCallback callback) { + FakeRemoteGattCharacteristic* fake_remote_gatt_characteristic = + GetFakeRemoteGattCharacteristic(peripheral_address, service_id, + characteristic_id); + if (!fake_remote_gatt_characteristic) { + std::move(callback).Run(false, false); + } + + std::move(callback).Run(true, fake_remote_gatt_characteristic->IsNotifying()); +} + void FakeCentral::GetLastWrittenCharacteristicValue( const std::string& characteristic_id, const std::string& service_id,
diff --git a/device/bluetooth/test/fake_central.h b/device/bluetooth/test/fake_central.h index 18a35ea6..a584e347 100644 --- a/device/bluetooth/test/fake_central.h +++ b/device/bluetooth/test/fake_central.h
@@ -98,7 +98,17 @@ const std::string& characteristic_id, const std::string& service_id, const std::string& peripheral_address, - SetNextWriteCharacteristicResponseCallback callback) override; + SetNextSubscribeToNotificationsResponseCallback callback) override; + void SetNextUnsubscribeFromNotificationsResponse( + uint16_t gatt_code, + const std::string& characteristic_id, + const std::string& service_id, + const std::string& peripheral_address, + SetNextUnsubscribeFromNotificationsResponseCallback callback) override; + void IsNotifying(const std::string& characteristic_id, + const std::string& service_id, + const std::string& peripheral_address, + IsNotifyingCallback callback) override; void GetLastWrittenCharacteristicValue( const std::string& characteristic_id, const std::string& service_id,
diff --git a/device/bluetooth/test/fake_remote_gatt_characteristic.cc b/device/bluetooth/test/fake_remote_gatt_characteristic.cc index 8e0a8077..31acc78 100644 --- a/device/bluetooth/test/fake_remote_gatt_characteristic.cc +++ b/device/bluetooth/test/fake_remote_gatt_characteristic.cc
@@ -91,6 +91,12 @@ next_subscribe_to_notifications_response_.emplace(gatt_code); } +void FakeRemoteGattCharacteristic::SetNextUnsubscribeFromNotificationsResponse( + uint16_t gatt_code) { + DCHECK(!next_unsubscribe_from_notifications_response_); + next_unsubscribe_from_notifications_response_.emplace(gatt_code); +} + bool FakeRemoteGattCharacteristic::AllResponsesConsumed() { // TODO(crbug.com/569709): Update this when // SetNextUnsubscribeFromNotificationsResponse is implemented. @@ -192,7 +198,11 @@ device::BluetoothRemoteGattDescriptor* ccc_descriptor, const base::Closure& callback, const ErrorCallback& error_callback) { - NOTREACHED(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&FakeRemoteGattCharacteristic:: + DispatchUnsubscribeFromNotificationsResponse, + weak_ptr_factory_.GetWeakPtr(), callback, error_callback)); } void FakeRemoteGattCharacteristic::DispatchReadResponse( @@ -258,4 +268,23 @@ } } +void FakeRemoteGattCharacteristic::DispatchUnsubscribeFromNotificationsResponse( + const base::Closure& callback, + const ErrorCallback& error_callback) { + DCHECK(next_unsubscribe_from_notifications_response_); + uint16_t gatt_code = next_unsubscribe_from_notifications_response_.value(); + next_unsubscribe_from_notifications_response_.reset(); + + switch (gatt_code) { + case mojom::kGATTSuccess: + callback.Run(); + break; + case mojom::kGATTInvalidHandle: + error_callback.Run(device::BluetoothGattService::GATT_ERROR_FAILED); + break; + default: + NOTREACHED(); + } +} + } // namespace bluetooth
diff --git a/device/bluetooth/test/fake_remote_gatt_characteristic.h b/device/bluetooth/test/fake_remote_gatt_characteristic.h index 48ce0e6d..a4b0cc0b 100644 --- a/device/bluetooth/test/fake_remote_gatt_characteristic.h +++ b/device/bluetooth/test/fake_remote_gatt_characteristic.h
@@ -59,6 +59,11 @@ // call its error callback. void SetNextSubscribeToNotificationsResponse(uint16_t gatt_code); + // If |gatt_code| is mojom::kGATTSuccess the next unsubscribe to notifications + // with response request will call its success callback. Otherwise it will + // call its error callback. + void SetNextUnsubscribeFromNotificationsResponse(uint16_t gatt_code); + // Returns true if there are no pending responses for this characteristc or // any of its descriptors. bool AllResponsesConsumed(); @@ -108,6 +113,9 @@ void DispatchSubscribeToNotificationsResponse( const base::Closure& callback, const ErrorCallback& error_callback); + void DispatchUnsubscribeFromNotificationsResponse( + const base::Closure& callback, + const ErrorCallback& error_callback); const std::string characteristic_id_; const device::BluetoothUUID characteristic_uuid_; @@ -130,6 +138,10 @@ // SubscribeToNotifications is called. base::Optional<uint16_t> next_subscribe_to_notifications_response_; + // Used to decide which callback should be called when + // UnsubscribeFromNotifications is called. + base::Optional<uint16_t> next_unsubscribe_from_notifications_response_; + size_t last_descriptor_id_; using FakeDescriptorMap =
diff --git a/device/fido/attested_credential_data.cc b/device/fido/attested_credential_data.cc index efada48b..77ae660 100644 --- a/device/fido/attested_credential_data.cc +++ b/device/fido/attested_credential_data.cc
@@ -4,8 +4,7 @@ #include "device/fido/attested_credential_data.h" -#include <stddef.h> - +#include <algorithm> #include <utility> #include "base/numerics/safe_math.h" @@ -15,15 +14,6 @@ namespace device { -namespace { - -constexpr size_t kAaguidLength = 16; - -// Number of bytes used to represent length of credential ID. -constexpr size_t kCredentialIdLengthLength = 2; - -} // namespace - // static base::Optional<AttestedCredentialData> AttestedCredentialData::DecodeFromCtapResponse( @@ -31,16 +21,20 @@ if (buffer.size() < kAaguidLength + kCredentialIdLengthLength) return base::nullopt; - auto aaguid = u2f_parsing_utils::Extract(buffer, 0, kAaguidLength); - auto credential_id_length_span = u2f_parsing_utils::ExtractSpan( - buffer, kAaguidLength, kCredentialIdLengthLength); - - if (aaguid.empty() || credential_id_length_span.empty()) + std::array<uint8_t, kAaguidLength> aaguid; + if (!u2f_parsing_utils::ExtractArray(buffer, 0, &aaguid)) return base::nullopt; + std::array<uint8_t, kCredentialIdLengthLength> credential_id_length_array; + if (!u2f_parsing_utils::ExtractArray(buffer, kAaguidLength, + &credential_id_length_array)) { + return base::nullopt; + } + static_assert(kCredentialIdLengthLength == 2u, "L must be 2 bytes"); const size_t credential_id_length = - credential_id_length_span[0] << 8 | credential_id_length_span[1]; + (base::strict_cast<size_t>(credential_id_length_array[0]) << 8) | + base::strict_cast<size_t>(credential_id_length_array[1]); auto credential_id = u2f_parsing_utils::Extract( buffer, kAaguidLength + kCredentialIdLengthLength, credential_id_length); @@ -54,9 +48,7 @@ kAaguidLength + kCredentialIdLengthLength + credential_id_length)); return AttestedCredentialData( - std::move(aaguid), - std::vector<uint8_t>(credential_id_length_span.begin(), - credential_id_length_span.end()), + std::move(aaguid), std::move(credential_id_length_array), std::move(credential_id), std::move(credential_public_key_data)); } @@ -64,7 +56,6 @@ base::Optional<AttestedCredentialData> AttestedCredentialData::CreateFromU2fRegisterResponse( base::span<const uint8_t> u2f_data, - std::vector<uint8_t> aaguid, std::unique_ptr<PublicKey> public_key) { // TODO(crbug/799075): Introduce a CredentialID class to do this extraction. // Extract the length of the credential (i.e. of the U2FResponse key @@ -76,8 +67,13 @@ return base::nullopt; } + // For U2F register request, device AAGUID is set to zeros. + std::array<uint8_t, kAaguidLength> aaguid; + aaguid.fill(0); + // Note that U2F responses only use one byte for length. - std::vector<uint8_t> credential_id_length = {0, extracted_length[0]}; + std::array<uint8_t, kCredentialIdLengthLength> credential_id_length = { + 0, extracted_length[0]}; // Extract the credential id (i.e. key handle). std::vector<uint8_t> credential_id = u2f_parsing_utils::Extract( @@ -93,16 +89,6 @@ std::move(credential_id), std::move(public_key)); } -AttestedCredentialData::AttestedCredentialData( - std::vector<uint8_t> aaguid, - std::vector<uint8_t> length, - std::vector<uint8_t> credential_id, - std::unique_ptr<PublicKey> public_key) - : aaguid_(std::move(aaguid)), - credential_id_length_(std::move(length)), - credential_id_(std::move(credential_id)), - public_key_(std::move(public_key)) {} - AttestedCredentialData::AttestedCredentialData(AttestedCredentialData&& other) = default; @@ -112,16 +98,29 @@ AttestedCredentialData::~AttestedCredentialData() = default; void AttestedCredentialData::DeleteAaguid() { - aaguid_ = std::vector<uint8_t>(kAaguidLength, 0); + std::fill(aaguid_.begin(), aaguid_.end(), 0); } std::vector<uint8_t> AttestedCredentialData::SerializeAsBytes() const { std::vector<uint8_t> attestation_data; - u2f_parsing_utils::Append(&attestation_data, aaguid_); - u2f_parsing_utils::Append(&attestation_data, credential_id_length_); + u2f_parsing_utils::Append(&attestation_data, + base::make_span(aaguid_.data(), kAaguidLength)); + u2f_parsing_utils::Append( + &attestation_data, + base::make_span(credential_id_length_.data(), kCredentialIdLengthLength)); u2f_parsing_utils::Append(&attestation_data, credential_id_); u2f_parsing_utils::Append(&attestation_data, public_key_->EncodeAsCOSEKey()); return attestation_data; } +AttestedCredentialData::AttestedCredentialData( + std::array<uint8_t, kAaguidLength> aaguid, + std::array<uint8_t, kCredentialIdLengthLength> credential_id_length, + std::vector<uint8_t> credential_id, + std::unique_ptr<PublicKey> public_key) + : aaguid_(std::move(aaguid)), + credential_id_length_(std::move(credential_id_length)), + credential_id_(std::move(credential_id)), + public_key_(std::move(public_key)) {} + } // namespace device
diff --git a/device/fido/attested_credential_data.h b/device/fido/attested_credential_data.h index 323e1e5..c33dccb 100644 --- a/device/fido/attested_credential_data.h +++ b/device/fido/attested_credential_data.h
@@ -5,6 +5,7 @@ #ifndef DEVICE_FIDO_ATTESTED_CREDENTIAL_DATA_H_ #define DEVICE_FIDO_ATTESTED_CREDENTIAL_DATA_H_ +#include <stddef.h> #include <stdint.h> #include <memory> #include <vector> @@ -26,14 +27,8 @@ static base::Optional<AttestedCredentialData> CreateFromU2fRegisterResponse( base::span<const uint8_t> u2f_data, - std::vector<uint8_t> aaguid, std::unique_ptr<PublicKey> public_key); - AttestedCredentialData(std::vector<uint8_t> aaguid, - std::vector<uint8_t> length, - std::vector<uint8_t> credential_id, - std::unique_ptr<PublicKey> public_key); - // Moveable. AttestedCredentialData(AttestedCredentialData&& other); AttestedCredentialData& operator=(AttestedCredentialData&& other); @@ -54,11 +49,22 @@ std::vector<uint8_t> SerializeAsBytes() const; private: + static constexpr size_t kAaguidLength = 16; + // Number of bytes used to represent length of credential ID. + static constexpr size_t kCredentialIdLengthLength = 2; + + AttestedCredentialData( + std::array<uint8_t, kAaguidLength> aaguid, + std::array<uint8_t, kCredentialIdLengthLength> credential_id_length, + std::vector<uint8_t> credential_id, + std::unique_ptr<PublicKey> public_key); + // The 16-byte AAGUID of the authenticator. - std::vector<uint8_t> aaguid_; + std::array<uint8_t, kAaguidLength> aaguid_; // Big-endian length of the credential (i.e. key handle). - std::vector<uint8_t> credential_id_length_; + std::array<uint8_t, kCredentialIdLengthLength> credential_id_length_; + std::vector<uint8_t> credential_id_; std::unique_ptr<PublicKey> public_key_;
diff --git a/device/fido/authenticator_make_credential_response.cc b/device/fido/authenticator_make_credential_response.cc index a6e4a8df..4b41a70 100644 --- a/device/fido/authenticator_make_credential_response.cc +++ b/device/fido/authenticator_make_credential_response.cc
@@ -25,12 +25,9 @@ if (!public_key) return base::nullopt; - // AAGUID is zeroed out for U2F responses. - std::vector<uint8_t> aaguid(16u); - auto attested_credential_data = AttestedCredentialData::CreateFromU2fRegisterResponse( - u2f_data, std::move(aaguid), std::move(public_key)); + u2f_data, std::move(public_key)); if (!attested_credential_data) return base::nullopt;
diff --git a/device/fido/u2f_parsing_utils.h b/device/fido/u2f_parsing_utils.h index 8676514..4c561530 100644 --- a/device/fido/u2f_parsing_utils.h +++ b/device/fido/u2f_parsing_utils.h
@@ -7,6 +7,8 @@ #include <stddef.h> #include <stdint.h> +#include <algorithm> +#include <array> #include <vector> #include "base/component_export.h" @@ -59,6 +61,18 @@ base::span<const uint8_t> ExtractSuffixSpan(base::span<const uint8_t> span, size_t pos); +template <size_t N> +bool ExtractArray(base::span<const uint8_t> span, + size_t pos, + std::array<uint8_t, N>* array) { + const auto extracted_span = ExtractSpan(span, pos, N); + if (extracted_span.size() != N) + return false; + + std::copy(extracted_span.begin(), extracted_span.end(), array->begin()); + return true; +} + } // namespace u2f_parsing_utils } // namespace device
diff --git a/device/fido/u2f_parsing_utils_unittest.cc b/device/fido/u2f_parsing_utils_unittest.cc index af1688464..4965febd 100644 --- a/device/fido/u2f_parsing_utils_unittest.cc +++ b/device/fido/u2f_parsing_utils_unittest.cc
@@ -117,5 +117,21 @@ EXPECT_THAT(ExtractSuffix(kOneTwoThree, 4), ::testing::IsEmpty()); } +TEST(U2fParsingUtils, ExtractArray) { + const std::vector<uint8_t> empty; + std::array<uint8_t, 0> array_empty; + EXPECT_TRUE(ExtractArray(empty, 0, &array_empty)); + + std::array<uint8_t, 2> array_two_three; + EXPECT_TRUE(ExtractArray(kTwoThree, 0, &array_two_three)); + EXPECT_THAT(array_two_three, ::testing::ElementsAreArray(kTwoThree)); + + EXPECT_FALSE(ExtractArray(kOneTwoThree, 2, &array_two_three)); + + std::array<uint8_t, 1> array_three; + EXPECT_TRUE(ExtractArray(kOneTwoThree, 2, &array_three)); + EXPECT_THAT(array_three, ::testing::ElementsAreArray(kThree)); +} + } // namespace u2f_parsing_utils } // namespace device
diff --git a/device/fido/u2f_register_unittest.cc b/device/fido/u2f_register_unittest.cc index b0bd8e1..cf6aef2a 100644 --- a/device/fido/u2f_register_unittest.cc +++ b/device/fido/u2f_register_unittest.cc
@@ -729,8 +729,7 @@ u2f_parsing_utils::kEs256, GetTestRegisterResponse()); base::Optional<AttestedCredentialData> attested_data = AttestedCredentialData::CreateFromU2fRegisterResponse( - GetTestRegisterResponse(), std::vector<uint8_t>(16) /* aaguid */, - std::move(public_key)); + GetTestRegisterResponse(), std::move(public_key)); EXPECT_EQ(GetTestAttestedCredentialDataBytes(), attested_data->SerializeAsBytes()); @@ -743,8 +742,7 @@ u2f_parsing_utils::kEs256, GetTestRegisterResponse()); base::Optional<AttestedCredentialData> attested_data = AttestedCredentialData::CreateFromU2fRegisterResponse( - GetTestRegisterResponse(), std::vector<uint8_t>(16) /* aaguid */, - std::move(public_key)); + GetTestRegisterResponse(), std::move(public_key)); constexpr uint8_t flags = static_cast<uint8_t>(AuthenticatorData::Flag::kTestOfUserPresence) | @@ -766,8 +764,7 @@ u2f_parsing_utils::kEs256, GetTestRegisterResponse()); base::Optional<AttestedCredentialData> attested_data = AttestedCredentialData::CreateFromU2fRegisterResponse( - GetTestRegisterResponse(), std::vector<uint8_t>(16) /* aaguid */, - std::move(public_key)); + GetTestRegisterResponse(), std::move(public_key)); constexpr uint8_t flags = static_cast<uint8_t>(AuthenticatorData::Flag::kTestOfUserPresence) |
diff --git a/device/fido/virtual_fido_device.cc b/device/fido/virtual_fido_device.cc index 6f006cf..dc8cb9d 100644 --- a/device/fido/virtual_fido_device.cc +++ b/device/fido/virtual_fido_device.cc
@@ -92,6 +92,28 @@ : attestation_cert_common_name("Batch Certificate"), individual_attestation_cert_common_name("Individual Certificate") {} VirtualFidoDevice::State::~State() = default; + +bool VirtualFidoDevice::State::InjectRegistration( + const std::vector<uint8_t>& credential_id, + const std::string& relying_party_id) { + std::vector<uint8_t> application_parameter(crypto::kSHA256Length); + crypto::SHA256HashString(relying_party_id, application_parameter.data(), + application_parameter.size()); + + auto private_key = crypto::ECPrivateKey::Create(); + if (!private_key) { + return false; + } + RegistrationData registration(std::move(private_key), + std::move(application_parameter), + 0 /* signature counter */); + + bool was_inserted; + std::tie(std::ignore, was_inserted) = + registrations.emplace(credential_id, std::move(registration)); + return was_inserted; +} + VirtualFidoDevice::VirtualFidoDevice() : state_(new State), weak_factory_(this) {}
diff --git a/device/fido/virtual_fido_device.h b/device/fido/virtual_fido_device.h index 0504281e..b651e70 100644 --- a/device/fido/virtual_fido_device.h +++ b/device/fido/virtual_fido_device.h
@@ -64,6 +64,15 @@ // Registered keys. Keyed on key handle (a.k.a. "credential ID"). std::map<std::vector<uint8_t>, RegistrationData> registrations; + // Adds a registration for the specified credential ID with the application + // parameter set to be valid for the given relying party ID (which would + // typically be a domain, e.g. "example.com"). + // + // Returns true on success. Will fail if there already exists a credential + // with the given ID. + bool InjectRegistration(const std::vector<uint8_t>& credential_id, + const std::string& relying_party_id); + private: friend class base::RefCounted<State>; ~State();
diff --git a/device/geolocation/BUILD.gn b/device/geolocation/BUILD.gn index 1769208..a69729c 100644 --- a/device/geolocation/BUILD.gn +++ b/device/geolocation/BUILD.gn
@@ -53,6 +53,7 @@ "wifi_data_provider_manager.h", "wifi_data_provider_win.cc", "wifi_data_provider_win.h", + "wifi_polling_policy.cc", "wifi_polling_policy.h", ] @@ -172,6 +173,7 @@ "wifi_data_provider_common_unittest.cc", "wifi_data_provider_linux_unittest.cc", "wifi_data_provider_win_unittest.cc", + "wifi_polling_policy_unittest.cc", ] public_deps = [ ":geolocation",
diff --git a/device/geolocation/location_arbitrator.cc b/device/geolocation/location_arbitrator.cc index fa0ffb01..61370c6 100644 --- a/device/geolocation/location_arbitrator.cc +++ b/device/geolocation/location_arbitrator.cc
@@ -14,6 +14,7 @@ #include "build/build_config.h" #include "device/geolocation/network_location_provider.h" #include "device/geolocation/public/cpp/geoposition.h" +#include "device/geolocation/wifi_polling_policy.h" namespace device { @@ -33,7 +34,10 @@ is_permission_granted_(false), is_running_(false) {} -LocationArbitrator::~LocationArbitrator() = default; +LocationArbitrator::~LocationArbitrator() { + // Release the global wifi polling policy state. + WifiPollingPolicy::Shutdown(); +} bool LocationArbitrator::HasPermissionBeenGrantedForTest() const { return is_permission_granted_; @@ -45,6 +49,15 @@ provider->OnPermissionGranted(); } +void LocationArbitrator::SetLastNetworkPosition( + const mojom::Geoposition& position) { + last_network_position_ = position; +} + +const mojom::Geoposition& LocationArbitrator::GetLastNetworkPosition() { + return last_network_position_; +} + void LocationArbitrator::StartProvider(bool enable_high_accuracy) { is_running_ = true; enable_high_accuracy_ = enable_high_accuracy; @@ -156,7 +169,8 @@ // Android uses its own SystemLocationProvider. return nullptr; #else - return std::make_unique<NetworkLocationProvider>(std::move(context), api_key); + return std::make_unique<NetworkLocationProvider>(std::move(context), api_key, + this); #endif }
diff --git a/device/geolocation/location_arbitrator.h b/device/geolocation/location_arbitrator.h index 61c3f0cb..8e1e9ec 100644 --- a/device/geolocation/location_arbitrator.h +++ b/device/geolocation/location_arbitrator.h
@@ -16,6 +16,7 @@ #include "base/time/time.h" #include "device/geolocation/geolocation_export.h" #include "device/geolocation/geolocation_provider_impl.h" +#include "device/geolocation/network_location_provider.h" #include "device/geolocation/public/cpp/location_provider.h" #include "net/url_request/url_request_context_getter.h" #include "services/device/public/mojom/geoposition.mojom.h" @@ -30,7 +31,9 @@ // This class is responsible for handling updates from multiple underlying // providers and resolving them to a single 'best' location fix at any given // moment. -class DEVICE_GEOLOCATION_EXPORT LocationArbitrator : public LocationProvider { +class DEVICE_GEOLOCATION_EXPORT LocationArbitrator + : public LocationProvider, + public NetworkLocationProvider::LastPositionCache { public: // The TimeDelta newer a location provider has to be that it's worth // switching to this location provider on the basis of it being fresher @@ -57,6 +60,10 @@ const mojom::Geoposition& GetPosition() override; void OnPermissionGranted() override; + // NetworkLocationProvider::LastPositionCache implementation. + void SetLastNetworkPosition(const mojom::Geoposition& position) override; + const mojom::Geoposition& GetLastNetworkPosition() override; + protected: // These functions are useful for injection of dependencies in derived // testing classes. @@ -114,6 +121,11 @@ // The current best estimate of our position. mojom::Geoposition position_; + // The most recent position estimate returned by the network location + // provider. This must be preserved by LocationArbitrator so it is not lost + // when the provider is destroyed in StopProvider. + mojom::Geoposition last_network_position_; + // Tracks whether providers should be running. bool is_running_;
diff --git a/device/geolocation/network_location_provider.cc b/device/geolocation/network_location_provider.cc index 61f00f2..00032cab 100644 --- a/device/geolocation/network_location_provider.cc +++ b/device/geolocation/network_location_provider.cc
@@ -21,6 +21,11 @@ // The maximum period of time we'll wait for a complete set of wifi data // before sending the request. const int kDataCompleteWaitSeconds = 2; + +// The maximum age of a cached network location estimate before it can no longer +// be returned as a fresh estimate. This should be at least as long as the +// longest polling interval used by the WifiDataProvider. +const int kLastPositionMaxAgeSeconds = 10 * 60; // 10 minutes } // namespace // static @@ -97,12 +102,14 @@ // NetworkLocationProvider NetworkLocationProvider::NetworkLocationProvider( scoped_refptr<net::URLRequestContextGetter> url_context_getter, - const std::string& api_key) + const std::string& api_key, + LastPositionCache* last_position_cache) : wifi_data_provider_manager_(nullptr), wifi_data_update_callback_( base::Bind(&NetworkLocationProvider::OnWifiDataUpdate, base::Unretained(this))), is_wifi_data_complete_(false), + last_position_delegate_(last_position_cache), is_permission_granted_(false), is_new_data_available_(false), request_(new NetworkLocationRequest( @@ -111,7 +118,9 @@ base::Bind(&NetworkLocationProvider::OnLocationResponse, base::Unretained(this)))), position_cache_(new PositionCache), - weak_factory_(this) {} + weak_factory_(this) { + DCHECK(last_position_delegate_); +} NetworkLocationProvider::~NetworkLocationProvider() { DCHECK(thread_checker_.CalledOnValidThread()); @@ -150,13 +159,15 @@ const WifiData& wifi_data) { DCHECK(thread_checker_.CalledOnValidThread()); // Record the position and update our cache. - position_ = position; + last_position_delegate_->SetLastNetworkPosition(position); if (ValidateGeoposition(position)) position_cache_->CachePosition(wifi_data, position); // Let listeners know that we now have a position available. - if (!location_provider_update_callback_.is_null()) - location_provider_update_callback_.Run(this, position_); + if (!location_provider_update_callback_.is_null()) { + location_provider_update_callback_.Run( + this, last_position_delegate_->GetLastNetworkPosition()); + } } void NetworkLocationProvider::StartProvider(bool high_accuracy) { @@ -188,12 +199,36 @@ } const mojom::Geoposition& NetworkLocationProvider::GetPosition() { - return position_; + return last_position_delegate_->GetLastNetworkPosition(); } void NetworkLocationProvider::RequestPosition() { DCHECK(thread_checker_.CalledOnValidThread()); + // The wifi polling policy may require us to wait for several minutes before + // fresh wifi data is available. To ensure we can return a position estimate + // quickly when the network location provider is the primary provider, allow + // a cached value to be returned under certain conditions. + // + // If we have a sufficiently recent network location estimate and we do not + // expect to receive a new one soon (i.e., no new wifi data is available and + // there is no pending network request), report the last network position + // estimate as if it were a fresh estimate. + const mojom::Geoposition& last_position = + last_position_delegate_->GetLastNetworkPosition(); + if (!is_new_data_available_ && !request_->is_request_pending() && + ValidateGeoposition(last_position)) { + base::Time now = base::Time::Now(); + base::TimeDelta last_position_age = now - last_position.timestamp; + if (last_position_age.InSeconds() < kLastPositionMaxAgeSeconds && + !location_provider_update_callback_.is_null()) { + // Update the timestamp to the current time. + mojom::Geoposition position = last_position; + position.timestamp = now; + location_provider_update_callback_.Run(this, position); + } + } + if (!is_new_data_available_ || !is_wifi_data_complete_) return; DCHECK(!wifi_timestamp_.is_null()) @@ -202,19 +237,20 @@ const mojom::Geoposition* cached_position = position_cache_->FindPosition(wifi_data_); if (cached_position) { - DCHECK(ValidateGeoposition(*cached_position)); - // Record the position and update its timestamp. - position_ = *cached_position; - + mojom::Geoposition position(*cached_position); + DCHECK(ValidateGeoposition(position)); // The timestamp of a position fix is determined by the timestamp - // of the source data update. (The value of position_.timestamp from + // of the source data update. (The value of position.timestamp from // the cache could be from weeks ago!) - position_.timestamp = wifi_timestamp_; + position.timestamp = wifi_timestamp_; is_new_data_available_ = false; + // Record the position. + last_position_delegate_->SetLastNetworkPosition(position); + // Let listeners know that we now have a position available. if (!location_provider_update_callback_.is_null()) - location_provider_update_callback_.Run(this, position_); + location_provider_update_callback_.Run(this, position); return; } // Don't send network requests until authorized. http://crbug.com/39171
diff --git a/device/geolocation/network_location_provider.h b/device/geolocation/network_location_provider.h index 59c1cd4..45058788 100644 --- a/device/geolocation/network_location_provider.h +++ b/device/geolocation/network_location_provider.h
@@ -27,7 +27,19 @@ class NetworkLocationProvider : public LocationProvider { public: - // Cache of recently resolved locations. Public for tests. + // To ensure the last-used position estimate can be preserved when the network + // location provider is torn down, a delegate manages the state of the cached + // position estimate outside of this provider. + class LastPositionCache { + public: + virtual ~LastPositionCache() = default; + virtual void SetLastNetworkPosition( + const mojom::Geoposition& new_position) = 0; + virtual const mojom::Geoposition& GetLastNetworkPosition() = 0; + }; + + // Cache of recently resolved locations, keyed by the set of unique WiFi APs + // used in the network query. Public for tests. class DEVICE_GEOLOCATION_EXPORT PositionCache { public: // The maximum size of the cache of positions. @@ -64,7 +76,8 @@ DEVICE_GEOLOCATION_EXPORT NetworkLocationProvider( scoped_refptr<net::URLRequestContextGetter> context, - const std::string& api_key); + const std::string& api_key, + LastPositionCache* last_position_cache); ~NetworkLocationProvider() override; // LocationProvider implementation @@ -101,8 +114,9 @@ // The timestamp for the latest wifi data update. base::Time wifi_timestamp_; - // The current best position estimate. - mojom::Geoposition position_; + // A delegate to manage the current best network position estimate. Must not + // be nullptr. + LastPositionCache* const last_position_delegate_; LocationProvider::LocationProviderUpdateCallback location_provider_update_callback_;
diff --git a/device/geolocation/network_location_provider_unittest.cc b/device/geolocation/network_location_provider_unittest.cc index ed62e571..56f8832 100644 --- a/device/geolocation/network_location_provider_unittest.cc +++ b/device/geolocation/network_location_provider_unittest.cc
@@ -8,13 +8,11 @@ #include <memory> #include <string> -#include <utility> #include <vector> #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/macros.h" -#include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -31,23 +29,22 @@ namespace device { -// Stops the specified (nested) message loop when the listener is called back. -class MessageLoopQuitListener { - public: - MessageLoopQuitListener() - : client_message_loop_(base::MessageLoop::current()), - updated_provider_(nullptr) { - CHECK(client_message_loop_); - } +// Records the most recent position update and counts the number of times +// OnLocationUpdate is called. +struct LocationUpdateListener { + LocationUpdateListener() + : callback(base::BindRepeating(&LocationUpdateListener::OnLocationUpdate, + base::Unretained(this))) {} void OnLocationUpdate(const LocationProvider* provider, const mojom::Geoposition& position) { - EXPECT_EQ(client_message_loop_, base::MessageLoop::current()); - updated_provider_ = provider; + last_position = position; + update_count++; } - base::MessageLoop* client_message_loop_; - const LocationProvider* updated_provider_; + const LocationProvider::LocationProviderUpdateCallback callback; + mojom::Geoposition last_position; + int update_count = 0; }; // A mock implementation of WifiDataProvider for testing. Adapted from @@ -105,6 +102,21 @@ DISALLOW_COPY_AND_ASSIGN(MockWifiDataProvider); }; +// An implementation of LastPositionCache. +class TestLastPositionCache + : public NetworkLocationProvider::LastPositionCache { + public: + void SetLastNetworkPosition(const mojom::Geoposition& position) override { + last_network_position_ = position; + } + const mojom::Geoposition& GetLastNetworkPosition() override { + return last_network_position_; + } + + private: + mojom::Geoposition last_network_position_; +}; + MockWifiDataProvider* MockWifiDataProvider::instance_ = nullptr; // Main test fixture @@ -118,7 +130,8 @@ const std::string& api_key = std::string()) { // No URLContextGetter needed: The request within the provider is tested // directly using TestURLFetcherFactory. - LocationProvider* provider = new NetworkLocationProvider(nullptr, api_key); + LocationProvider* provider = new NetworkLocationProvider( + nullptr, api_key, last_position_cache_.get()); if (set_permission_granted) provider->OnPermissionGranted(); return provider; @@ -126,7 +139,8 @@ protected: GeolocationNetworkProviderTest() - : wifi_data_provider_(MockWifiDataProvider::CreateInstance()) { + : wifi_data_provider_(MockWifiDataProvider::CreateInstance()), + last_position_cache_(std::make_unique<TestLastPositionCache>()) { // TODO(joth): Really these should be in SetUp, not here, but they take no // effect on Mac OS Release builds if done there. I kid not. Figure out why. WifiDataProviderManager::SetFactoryForTesting( @@ -183,6 +197,7 @@ pos.latitude = id; pos.longitude = -(id + 1); pos.altitude = 2 * id; + pos.accuracy = 3 * id; pos.timestamp = base::Time::Now(); return pos; } @@ -275,6 +290,8 @@ const base::MessageLoop main_message_loop_; const net::TestURLFetcherFactory url_fetcher_factory_; const scoped_refptr<MockWifiDataProvider> wifi_data_provider_; + std::unique_ptr<NetworkLocationProvider::LastPositionCache> + last_position_cache_; }; // Tests that fixture members were SetUp correctly. @@ -443,13 +460,12 @@ // Tests that, if no Wifi scan data is available at startup, the provider // doesn't initiate a request, until Wifi data later becomes available. TEST_F(GeolocationNetworkProviderTest, NoRequestOnStartupUntilWifiData) { - MessageLoopQuitListener listener; + LocationUpdateListener listener; wifi_data_provider_->set_got_data(false); // No initial Wifi data. std::unique_ptr<LocationProvider> provider(CreateProvider(true)); provider->StartProvider(false); - provider->SetUpdateCallback(base::Bind( - &MessageLoopQuitListener::OnLocationUpdate, base::Unretained(&listener))); + provider->SetUpdateCallback(listener.callback); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(get_url_fetcher_and_advance_id()) @@ -542,4 +558,209 @@ } } +// Tests that the provider's last position cache delegate is correctly used to +// cache the most recent network position estimate, and that this estimate is +// not lost when the provider is torn down and recreated. +TEST_F(GeolocationNetworkProviderTest, LastPositionCache) { + std::unique_ptr<LocationProvider> provider(CreateProvider(true)); + provider->StartProvider(false); + + // Check that the provider is initialized with an invalid position. + mojom::Geoposition position = provider->GetPosition(); + EXPECT_FALSE(ValidateGeoposition(position)); + + // Check that the cached value is also invalid. + position = last_position_cache_->GetLastNetworkPosition(); + EXPECT_FALSE(ValidateGeoposition(position)); + + // Now wifi data arrives -- SetData will notify listeners. + const int kFirstScanAps = 6; + wifi_data_provider_->SetData(CreateReferenceWifiScanData(kFirstScanAps)); + base::RunLoop().RunUntilIdle(); + net::TestURLFetcher* fetcher = get_url_fetcher_and_advance_id(); + ASSERT_TRUE(fetcher); + // The request should have the wifi data. + CheckRequestIsValid(*fetcher, kFirstScanAps, 0); + + // Send a reply with good position fix. + const char* kReferenceNetworkResponse = + "{" + " \"accuracy\": 1200.4," + " \"location\": {" + " \"lat\": 51.0," + " \"lng\": -0.1" + " }" + "}"; + fetcher->set_status(net::URLRequestStatus()); + fetcher->set_response_code(200); // OK + fetcher->SetResponseString(kReferenceNetworkResponse); + fetcher->delegate()->OnURLFetchComplete(fetcher); + + // The provider should return the position as the current best estimate. + position = provider->GetPosition(); + EXPECT_EQ(51.0, position.latitude); + EXPECT_EQ(-0.1, position.longitude); + EXPECT_EQ(1200.4, position.accuracy); + EXPECT_FALSE(position.timestamp.is_null()); + EXPECT_TRUE(ValidateGeoposition(position)); + + // Shut down the provider. This typically happens whenever there are no active + // Geolocation API calls. + provider->StopProvider(); + provider = nullptr; + + // The cache preserves the last estimate while the provider is inactive. + position = last_position_cache_->GetLastNetworkPosition(); + EXPECT_EQ(51.0, position.latitude); + EXPECT_EQ(-0.1, position.longitude); + EXPECT_EQ(1200.4, position.accuracy); + EXPECT_FALSE(position.timestamp.is_null()); + EXPECT_TRUE(ValidateGeoposition(position)); + + // Restart the provider. + provider.reset(CreateProvider(true)); + provider->StartProvider(false); + + // Check that the most recent position estimate is retained. + position = provider->GetPosition(); + EXPECT_EQ(51.0, position.latitude); + EXPECT_EQ(-0.1, position.longitude); + EXPECT_EQ(1200.4, position.accuracy); + EXPECT_FALSE(position.timestamp.is_null()); + EXPECT_TRUE(ValidateGeoposition(position)); +} + +// Tests that when the last network position estimate is sufficiently recent and +// we do not expect to receive a fresh estimate soon (no new wifi data available +// and no pending geolocation service request) then the provider may return the +// last position instead of waiting to acquire a fresh estimate. +TEST_F(GeolocationNetworkProviderTest, LastPositionCacheUsed) { + LocationUpdateListener listener; + + // Seed the last position cache with a valid geoposition value and the + // timestamp set to the current time. + mojom::Geoposition last_position = CreateReferencePosition(0); + EXPECT_TRUE(ValidateGeoposition(last_position)); + last_position_cache_->SetLastNetworkPosition(last_position); + + // Simulate no initial wifi data. + wifi_data_provider_->set_got_data(false); + + // Start the provider without geolocation permission. + std::unique_ptr<LocationProvider> provider(CreateProvider(false)); + provider->StartProvider(false); + + // Register a location update callback. The listener will count how many times + // OnLocationUpdate is called. + provider->SetUpdateCallback(listener.callback); + + // Under normal circumstances, when there is no initial wifi data + // RequestPosition is not called until a few seconds after the provider is + // started to allow time for the wifi scan to complete. To avoid waiting, + // grant permissions once the provider is running to cause RequestPosition to + // be called immediately. + provider->OnPermissionGranted(); + + base::RunLoop().RunUntilIdle(); + + // Check that the listener received the position update and that the position + // is the same as the seeded value except for the timestamp, which should be + // newer. + EXPECT_EQ(1, listener.update_count); + EXPECT_TRUE(ValidateGeoposition(listener.last_position)); + EXPECT_EQ(last_position.latitude, listener.last_position.latitude); + EXPECT_EQ(last_position.longitude, listener.last_position.longitude); + EXPECT_EQ(last_position.accuracy, listener.last_position.accuracy); + EXPECT_LT(last_position.timestamp, listener.last_position.timestamp); +} + +// Tests that the last network position estimate is not returned if the +// estimate is too old. +TEST_F(GeolocationNetworkProviderTest, LastPositionNotUsedTooOld) { + LocationUpdateListener listener; + + // Seed the last position cache with a geoposition value with the timestamp + // set to 20 minutes ago. + mojom::Geoposition last_position = CreateReferencePosition(0); + last_position.timestamp = + base::Time::Now() - base::TimeDelta::FromMinutes(20); + EXPECT_TRUE(ValidateGeoposition(last_position)); + last_position_cache_->SetLastNetworkPosition(last_position); + + // Simulate no initial wifi data. + wifi_data_provider_->set_got_data(false); + + // Start the provider without geolocation permission. + std::unique_ptr<LocationProvider> provider(CreateProvider(false)); + provider->StartProvider(false); + + // Register a location update callback. The listener will count how many times + // OnLocationUpdate is called. + provider->SetUpdateCallback(listener.callback); + + // Under normal circumstances, when there is no initial wifi data + // RequestPosition is not called until a few seconds after the provider is + // started to allow time for the wifi scan to complete. To avoid waiting, + // grant permissions once the provider is running to cause RequestPosition to + // be called immediately. + provider->OnPermissionGranted(); + + base::RunLoop().RunUntilIdle(); + + // Check that the listener received no updates. + EXPECT_EQ(0, listener.update_count); + EXPECT_FALSE(ValidateGeoposition(listener.last_position)); +} + +// Tests that the last network position estimate is not returned if there is +// new wifi data or a pending geolocation service request. +TEST_F(GeolocationNetworkProviderTest, LastPositionNotUsedNewData) { + LocationUpdateListener listener; + + // Seed the last position cache with a valid geoposition value. The timestamp + // of the cached position is set to the current time. + mojom::Geoposition last_position = CreateReferencePosition(0); + EXPECT_TRUE(ValidateGeoposition(last_position)); + last_position_cache_->SetLastNetworkPosition(last_position); + + // Simulate a completed wifi scan. + const int kFirstScanAps = 6; + wifi_data_provider_->SetData(CreateReferenceWifiScanData(kFirstScanAps)); + + // Create the provider without permissions enabled. + std::unique_ptr<LocationProvider> provider(CreateProvider(false)); + + // Register a location update callback. The callback will count how many times + // OnLocationUpdate is called. + provider->SetUpdateCallback(listener.callback); + + // Start the provider. + provider->StartProvider(false); + base::RunLoop().RunUntilIdle(); + + // The listener should not receive any updates. There is a valid cached value + // but it should not be sent while we have pending wifi data. + EXPECT_EQ(0, listener.update_count); + EXPECT_FALSE(ValidateGeoposition(listener.last_position)); + + // Check that there is no pending network request. + EXPECT_FALSE(get_url_fetcher_and_advance_id()); + + // Simulate no new wifi data. + wifi_data_provider_->set_got_data(false); + + // Grant permission to allow the network request to proceed. + provider->OnPermissionGranted(); + base::RunLoop().RunUntilIdle(); + + // The listener should still not receive any updates. There is a valid cached + // value and no new wifi data, but the cached value should not be sent while + // we have a pending request to the geolocation service. + EXPECT_EQ(0, listener.update_count); + EXPECT_FALSE(ValidateGeoposition(listener.last_position)); + + // Check that a network request is pending. + EXPECT_TRUE(get_url_fetcher_and_advance_id()); +} + } // namespace device
diff --git a/device/geolocation/wifi_data_provider_common.cc b/device/geolocation/wifi_data_provider_common.cc index 615b53c..64102d56 100644 --- a/device/geolocation/wifi_data_provider_common.cc +++ b/device/geolocation/wifi_data_provider_common.cc
@@ -35,18 +35,15 @@ return; } - DCHECK(!polling_policy_); - polling_policy_ = CreatePollingPolicy(); - DCHECK(polling_policy_); + if (!WifiPollingPolicy::IsInitialized()) + WifiPollingPolicy::Initialize(CreatePollingPolicy()); + DCHECK(WifiPollingPolicy::IsInitialized()); - // Perform first scan ASAP regardless of the polling policy. If this scan - // fails we'll retry at a rate in line with the polling policy. - ScheduleNextScan(0); + ScheduleNextScan(WifiPollingPolicy::Get()->InitialInterval()); } void WifiDataProviderCommon::StopDataProvider() { wlan_api_.reset(); - polling_policy_.reset(); } bool WifiDataProviderCommon::GetData(WifiData* data) { @@ -64,12 +61,12 @@ bool update_available = false; WifiData new_data; if (!wlan_api_->GetAccessPointData(&new_data.access_point_data)) { - ScheduleNextScan(polling_policy_->NoWifiInterval()); + ScheduleNextScan(WifiPollingPolicy::Get()->NoWifiInterval()); } else { update_available = wifi_data_.DiffersSignificantly(new_data); wifi_data_ = new_data; - polling_policy_->UpdatePollingInterval(update_available); - ScheduleNextScan(polling_policy_->PollingInterval()); + WifiPollingPolicy::Get()->UpdatePollingInterval(update_available); + ScheduleNextScan(WifiPollingPolicy::Get()->PollingInterval()); } if (update_available || !is_first_scan_complete_) { is_first_scan_complete_ = true;
diff --git a/device/geolocation/wifi_data_provider_common.h b/device/geolocation/wifi_data_provider_common.h index 44a312c..ad39a54e 100644 --- a/device/geolocation/wifi_data_provider_common.h +++ b/device/geolocation/wifi_data_provider_common.h
@@ -72,9 +72,6 @@ // Underlying OS wifi API. std::unique_ptr<WlanApiInterface> wlan_api_; - // Controls the polling update interval. - std::unique_ptr<WifiPollingPolicy> polling_policy_; - // Holder for delayed tasks; takes care of cleanup. base::WeakPtrFactory<WifiDataProviderCommon> weak_factory_;
diff --git a/device/geolocation/wifi_data_provider_common_unittest.cc b/device/geolocation/wifi_data_provider_common_unittest.cc index a1cbb62..5f126ee 100644 --- a/device/geolocation/wifi_data_provider_common_unittest.cc +++ b/device/geolocation/wifi_data_provider_common_unittest.cc
@@ -46,6 +46,7 @@ class MockPollingPolicy : public WifiPollingPolicy { public: MockPollingPolicy() { + ON_CALL(*this, InitialInterval()).WillByDefault(Return(0)); ON_CALL(*this, PollingInterval()).WillByDefault(Return(1)); ON_CALL(*this, NoWifiInterval()).WillByDefault(Return(1)); // We are not interested in calls to UpdatePollingInterval() method. @@ -54,25 +55,28 @@ // WifiPollingPolicy implementation. MOCK_METHOD1(UpdatePollingInterval, void(bool)); + MOCK_METHOD0(InitialInterval, int()); MOCK_METHOD0(PollingInterval, int()); MOCK_METHOD0(NoWifiInterval, int()); }; class WifiDataProviderCommonWithMock : public WifiDataProviderCommon { public: - WifiDataProviderCommonWithMock() - : wlan_api_(new MockWlanApi), polling_policy_(new MockPollingPolicy) {} + WifiDataProviderCommonWithMock() : wlan_api_(new MockWlanApi) {} // WifiDataProviderCommon std::unique_ptr<WlanApiInterface> CreateWlanApi() override { return std::move(wlan_api_); } std::unique_ptr<WifiPollingPolicy> CreatePollingPolicy() override { - return std::move(polling_policy_); + auto policy = std::make_unique<MockPollingPolicy>(); + // Save a pointer to the MockPollingPolicy. + polling_policy_ = policy.get(); + return std::move(policy); } std::unique_ptr<MockWlanApi> wlan_api_; - std::unique_ptr<MockPollingPolicy> polling_policy_; + MockPollingPolicy* polling_policy_ = nullptr; private: ~WifiDataProviderCommonWithMock() override = default; @@ -88,16 +92,22 @@ base::test::ScopedTaskEnvironment::MainThreadType::UI), wifi_data_callback_(base::DoNothing()), provider_(new WifiDataProviderCommonWithMock), - wlan_api_(provider_->wlan_api_.get()), - polling_policy_(provider_->polling_policy_.get()) {} + wlan_api_(provider_->wlan_api_.get()) {} void SetUp() override { + // Initialize WifiPollingPolicy early so we can watch for calls to mocked + // functions. + WifiPollingPolicy::Initialize(provider_->CreatePollingPolicy()); + if (WifiPollingPolicy::IsInitialized()) + polling_policy_ = provider_->polling_policy_; + provider_->AddCallback(&wifi_data_callback_); } void TearDown() override { provider_->RemoveCallback(&wifi_data_callback_); provider_->StopDataProvider(); + WifiPollingPolicy::Shutdown(); } protected: @@ -106,7 +116,7 @@ const scoped_refptr<WifiDataProviderCommonWithMock> provider_; MockWlanApi* const wlan_api_; - MockPollingPolicy* const polling_policy_; + MockPollingPolicy* polling_policy_ = nullptr; }; TEST_F(GeolocationWifiDataProviderCommonTest, CreateDestroy) { @@ -118,6 +128,7 @@ TEST_F(GeolocationWifiDataProviderCommonTest, NoWifi) { base::RunLoop run_loop; + EXPECT_CALL(*polling_policy_, InitialInterval()).Times(1); EXPECT_CALL(*polling_policy_, NoWifiInterval()).Times(AtLeast(1)); EXPECT_CALL(*wlan_api_, GetAccessPointData(_)) .WillOnce(InvokeWithoutArgs([&run_loop]() { @@ -131,6 +142,7 @@ TEST_F(GeolocationWifiDataProviderCommonTest, IntermittentWifi) { base::RunLoop run_loop; + EXPECT_CALL(*polling_policy_, InitialInterval()).Times(1); EXPECT_CALL(*polling_policy_, PollingInterval()).Times(AtLeast(1)); EXPECT_CALL(*polling_policy_, NoWifiInterval()).Times(1); EXPECT_CALL(*wlan_api_, GetAccessPointData(_)) @@ -149,6 +161,7 @@ TEST_F(GeolocationWifiDataProviderCommonTest, DoAnEmptyScan) { base::RunLoop run_loop; + EXPECT_CALL(*polling_policy_, InitialInterval()).Times(1); EXPECT_CALL(*polling_policy_, PollingInterval()).Times(AtLeast(1)); EXPECT_CALL(*wlan_api_, GetAccessPointData(_)) .WillOnce(InvokeWithoutArgs([&run_loop]() { @@ -169,6 +182,7 @@ TEST_F(GeolocationWifiDataProviderCommonTest, DoScanWithResults) { base::RunLoop run_loop; + EXPECT_CALL(*polling_policy_, InitialInterval()).Times(1); EXPECT_CALL(*polling_policy_, PollingInterval()).Times(AtLeast(1)); AccessPointData single_access_point; single_access_point.channel = 2;
diff --git a/device/geolocation/wifi_polling_policy.cc b/device/geolocation/wifi_polling_policy.cc new file mode 100644 index 0000000..8c3b3f53 --- /dev/null +++ b/device/geolocation/wifi_polling_policy.cc
@@ -0,0 +1,37 @@ +// Copyright 2018 The Chromium Authors. 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/geolocation/wifi_polling_policy.h" + +namespace device { + +namespace { +WifiPollingPolicy* g_wifi_polling_policy; +} // namespace + +// static +void WifiPollingPolicy::Initialize(std::unique_ptr<WifiPollingPolicy> policy) { + DCHECK(!g_wifi_polling_policy); + g_wifi_polling_policy = policy.release(); +} + +// static +void WifiPollingPolicy::Shutdown() { + if (g_wifi_polling_policy) + delete g_wifi_polling_policy; + g_wifi_polling_policy = nullptr; +} + +// static +WifiPollingPolicy* WifiPollingPolicy::Get() { + DCHECK(g_wifi_polling_policy); + return g_wifi_polling_policy; +} + +// static +bool WifiPollingPolicy::IsInitialized() { + return g_wifi_polling_policy != nullptr; +} + +} // namespace device
diff --git a/device/geolocation/wifi_polling_policy.h b/device/geolocation/wifi_polling_policy.h index 0ac9203..8463f3e 100644 --- a/device/geolocation/wifi_polling_policy.h +++ b/device/geolocation/wifi_polling_policy.h
@@ -5,21 +5,54 @@ #ifndef DEVICE_GEOLOCATION_WIFI_POLLING_POLICY_H_ #define DEVICE_GEOLOCATION_WIFI_POLLING_POLICY_H_ +#include <memory> + #include "base/macros.h" +#include "base/time/time.h" +#include "device/geolocation/geolocation_export.h" namespace device { // Allows sharing and mocking of the update polling policy function. -class WifiPollingPolicy { +class DEVICE_GEOLOCATION_EXPORT WifiPollingPolicy { public: - WifiPollingPolicy() {} - virtual ~WifiPollingPolicy() {} - // Calculates the new polling interval for wiFi scans, given the previous + virtual ~WifiPollingPolicy() = default; + + // Methods for managing the single instance of WifiPollingPolicy. The WiFi + // policy is global so it can outlive the WifiDataProvider instance, which is + // shut down and destroyed when no WiFi scanning is active. + static void Initialize(std::unique_ptr<WifiPollingPolicy>); + static void Shutdown(); + static WifiPollingPolicy* Get(); + static bool IsInitialized(); + + // Calculates the new polling interval for wifi scans, given the previous // interval and whether the last scan produced new results. virtual void UpdatePollingInterval(bool scan_results_differ) = 0; + + // Use InitialInterval to schedule the initial scan when the wifi data + // provider is first started. Returns the number of milliseconds before the + // initial scan should be performed. May return zero if the policy allows a + // scan to be performed immediately. + virtual int InitialInterval() = 0; + + // Use PollingInterval to schedule a new scan after the previous scan results + // are available. Only use PollingInterval if WLAN hardware is available and + // can perform scans for nearby access points. If the current interval is + // complete, PollingInterval returns the duration for a new interval starting + // at the current time. virtual int PollingInterval() = 0; + + // Use NoWifiInterval to schedule a new scan after the previous scan results + // are available. NoWifiInterval is typically shorter than PollingInterval + // and should not be used if wifi scanning is available in order to conserve + // power. If the current interval is complete, NoWifiInterval returns the + // duration for a new interval starting at the current time. virtual int NoWifiInterval() = 0; + protected: + WifiPollingPolicy() = default; + private: DISALLOW_COPY_AND_ASSIGN(WifiPollingPolicy); }; @@ -32,7 +65,8 @@ int NO_WIFI_INTERVAL> class GenericWifiPollingPolicy : public WifiPollingPolicy { public: - GenericWifiPollingPolicy() : polling_interval_(DEFAULT_INTERVAL) {} + GenericWifiPollingPolicy() = default; + // WifiPollingPolicy void UpdatePollingInterval(bool scan_results_differ) override { if (scan_results_differ) { @@ -45,11 +79,57 @@ polling_interval_ = TWO_NO_CHANGE_INTERVAL; } } - int PollingInterval() override { return polling_interval_; } - int NoWifiInterval() override { return NO_WIFI_INTERVAL; } + int InitialInterval() override { return ComputeInterval(polling_interval_); } + int PollingInterval() override { + int interval = ComputeInterval(polling_interval_); + return interval <= 0 ? polling_interval_ : interval; + } + int NoWifiInterval() override { + int interval = ComputeInterval(NO_WIFI_INTERVAL); + return interval <= 0 ? NO_WIFI_INTERVAL : interval; + } private: - int polling_interval_; + int ComputeInterval(int polling_interval) { + base::Time now = base::Time::Now(); + + int64_t remaining_millis = 0; + if (!interval_start_.is_null()) { + // If the new interval duration differs from the initial duration, use the + // shorter duration. + if (polling_interval < interval_duration_) + interval_duration_ = polling_interval; + + // Compute the remaining duration of the current interval. If the interval + // is not yet complete, we will schedule a scan to occur once it is. + base::TimeDelta remaining = + interval_start_ + + base::TimeDelta::FromMilliseconds(interval_duration_) - now; + remaining_millis = remaining.InMilliseconds(); + } + + // If the current interval is complete (or if this is our first scan), + // start a new interval beginning now. + if (remaining_millis <= 0) { + interval_start_ = now; + interval_duration_ = polling_interval; + remaining_millis = 0; + } + + return remaining_millis; + } + + // The current duration of the polling interval. When wifi data is + // substantially the same from one scan to the next, this may be increased to + // reduce the frequency of wifi scanning. + int polling_interval_ = DEFAULT_INTERVAL; + + // The start time for the most recent interval. Initialized to the "null" time + // value. + base::Time interval_start_; + + // Duration for the interval starting at |interval_start_|. + int interval_duration_ = DEFAULT_INTERVAL; }; } // namespace device
diff --git a/device/geolocation/wifi_polling_policy_unittest.cc b/device/geolocation/wifi_polling_policy_unittest.cc new file mode 100644 index 0000000..18c364f --- /dev/null +++ b/device/geolocation/wifi_polling_policy_unittest.cc
@@ -0,0 +1,145 @@ +// Copyright 2018 The Chromium Authors. 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/geolocation/wifi_polling_policy.h" + +#include <memory> + +#include "testing/gtest/include/gtest/gtest.h" + +namespace device { + +namespace { + +const int kDefaultIntervalMillis = 200; +const int kNoChangeIntervalMillis = 300; +const int kTwoNoChangeIntervalMillis = 400; +const int kNoWifiIntervalMillis = 100; + +} // namespace + +// Main test fixture +class GeolocationWifiPollingPolicyTest : public testing::Test { + public: + void SetUp() override { + WifiPollingPolicy::Initialize( + std::make_unique<GenericWifiPollingPolicy< + kDefaultIntervalMillis, kNoChangeIntervalMillis, + kTwoNoChangeIntervalMillis, kNoWifiIntervalMillis>>()); + polling_policy_ = WifiPollingPolicy::Get(); + } + + void TearDown() override { + polling_policy_ = nullptr; + WifiPollingPolicy::Shutdown(); + } + + protected: + WifiPollingPolicy* polling_policy_ = nullptr; +}; + +TEST_F(GeolocationWifiPollingPolicyTest, CreateDestroy) { + // Test fixture members were SetUp correctly. + EXPECT_TRUE(polling_policy_); +} + +// Tests that the InitialInterval is zero when the policy is first created. +TEST_F(GeolocationWifiPollingPolicyTest, InitialIntervalZero) { + // The first call should return zero, indicating we may scan immediately. + // Internally, the policy starts a new interval at the current time. + EXPECT_EQ(0, polling_policy_->InitialInterval()); + + // The second call should return the non-zero remainder of the interval + // created by the first call. + int interval = polling_policy_->InitialInterval(); + EXPECT_GT(interval, 0); + EXPECT_LE(interval, kDefaultIntervalMillis); +} + +// Tests that the PollingInterval is equal to the default polling interval when +// the policy is first created. +TEST_F(GeolocationWifiPollingPolicyTest, PollingIntervalNonZero) { + // PollingInterval assumes it is only called immediately following a wifi + // scan. The first call should start a new interval at the current time and + // return the full duration of the new interval. + EXPECT_EQ(kDefaultIntervalMillis, polling_policy_->PollingInterval()); + + // The second call should return the non-zero remainder of the interval + // created by the first call. + int interval = polling_policy_->PollingInterval(); + EXPECT_GT(interval, 0); + EXPECT_LE(interval, kDefaultIntervalMillis); +} + +// Tests that the NoWifiInterval is equal to the default no-wifi interval when +// the policy is first created. +TEST_F(GeolocationWifiPollingPolicyTest, NoWifiIntervalNonZero) { + // NoWifiInterval assumes it is only called immediately following a failed + // attempt at a wifi scan. The first call should start a new interval at the + // current time and return the full duration of the new interval. + EXPECT_EQ(kNoWifiIntervalMillis, polling_policy_->NoWifiInterval()); + + // The second call should return the non-zero remainder of the interval + // created by the first call. + int interval = polling_policy_->NoWifiInterval(); + EXPECT_GT(interval, 0); + EXPECT_LE(interval, kNoWifiIntervalMillis); +} + +// Calls UpdatePollingInterval once with unchanged scan results. Verifies that +// the no-change interval is used. +TEST_F(GeolocationWifiPollingPolicyTest, UpdatePollingIntervalOnce) { + polling_policy_->UpdatePollingInterval(false); + EXPECT_EQ(kNoChangeIntervalMillis, polling_policy_->PollingInterval()); +} + +// Calls UpdatePollingInterval twice with unchanged scan results. Verifies that +// the two-no-change interval is used. +TEST_F(GeolocationWifiPollingPolicyTest, UpdatePollingIntervalTwice) { + polling_policy_->UpdatePollingInterval(false); + polling_policy_->UpdatePollingInterval(false); + EXPECT_EQ(kTwoNoChangeIntervalMillis, polling_policy_->PollingInterval()); +} + +// Calls UpdatePollingInterval three times with unchanged scan results. This +// should have the same effect as calling it twice. +TEST_F(GeolocationWifiPollingPolicyTest, UpdatePollingIntervalThrice) { + polling_policy_->UpdatePollingInterval(false); + polling_policy_->UpdatePollingInterval(false); + polling_policy_->UpdatePollingInterval(false); + EXPECT_EQ(kTwoNoChangeIntervalMillis, polling_policy_->PollingInterval()); +} + +// Calls UpdatePollingInterval twice with unchanged scan results and then once +// with differing results. Verifies that the default interval is used. +TEST_F(GeolocationWifiPollingPolicyTest, UpdatePollingIntervalResultsDiffer) { + polling_policy_->UpdatePollingInterval(false); + polling_policy_->UpdatePollingInterval(false); + polling_policy_->UpdatePollingInterval(true); + EXPECT_EQ(kDefaultIntervalMillis, polling_policy_->PollingInterval()); +} + +TEST_F(GeolocationWifiPollingPolicyTest, ShorterInterval) { + // Ask for a polling interval. + EXPECT_EQ(kDefaultIntervalMillis, polling_policy_->PollingInterval()); + + // Now ask for a no-wifi interval, which is shorter. The returned interval + // must be no longer than the shorter of the two intervals. + int interval = polling_policy_->NoWifiInterval(); + EXPECT_GT(interval, 0); + EXPECT_LE(interval, kNoWifiIntervalMillis); +} + +TEST_F(GeolocationWifiPollingPolicyTest, LongerInterval) { + // Ask for a no-wifi interval. + EXPECT_EQ(kNoWifiIntervalMillis, polling_policy_->NoWifiInterval()); + + // Now ask for a polling interval, which is longer. The returned interval + // must be no longer than the shorter of the two intervals. + int interval = polling_policy_->PollingInterval(); + EXPECT_GT(interval, 0); + EXPECT_LE(interval, kNoWifiIntervalMillis); +} + +} // namespace device
diff --git a/device/vr/orientation/orientation_device_unittest.cc b/device/vr/orientation/orientation_device_unittest.cc index d360d89d..4bbde60 100644 --- a/device/vr/orientation/orientation_device_unittest.cc +++ b/device/vr/orientation/orientation_device_unittest.cc
@@ -22,10 +22,13 @@ #include "testing/gmock/include/gmock/gmock.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/display/test/scoped_screen_override.h" #include "ui/gfx/geometry/quaternion.h" namespace device { +using display::test::ScopedScreenOverride; + namespace { class FakeScreen : public display::Screen { @@ -88,7 +91,8 @@ fake_screen_ = std::make_unique<FakeScreen>(); - display::Screen::SetScreenInstance(fake_screen_.get()); + scoped_screen_override_ = + std::make_unique<ScopedScreenOverride>(fake_screen_.get()); scoped_task_environment_.RunUntilIdle(); } @@ -198,6 +202,7 @@ mojom::SensorClientPtr sensor_client_ptr_; std::unique_ptr<FakeScreen> fake_screen_; + std::unique_ptr<ScopedScreenOverride> scoped_screen_override_; DISALLOW_COPY_AND_ASSIGN(VROrientationDeviceTest); };
diff --git a/docs/memory/tools.md b/docs/memory/tools.md index e1f923aa..8b3d2c0 100644 --- a/docs/memory/tools.md +++ b/docs/memory/tools.md
@@ -123,7 +123,7 @@ Heap dumps provide extremely detailed data about object allocations and is useful for finding code locations that are generating a large number of live allocations. Data is tracked and recorded using the [Out-of-process Heap -Profiler (OOPHP)](../../src/chrome/profiling/README.md). +Profiler (OOPHP)](../../src/components/services/heap_profiling/README.md). For the Browser and GPU process, this often quickly finds objects that leak over time. @@ -138,10 +138,11 @@ `VirtualAlloc()`) will not be tracked. * Utility processes are currently not profiled. * Allocations are only recorded after the - [ProfilingService](../../src/chrome/profiling/profiling_service.h) has spun up the - profiling process and created a connection to the target process. The ProfilingService - is a mojo service that can be configured to start early in browser startup - but it still takes time to spin up and early allocations are thus lost. + [HeapProfilingService](../../src/components/services/heap_profiling/heap_profiling_service.h) + has spun up the profiling process and created a connection to the target + process. The HeapProfilingService is a mojo service that can be configured to + start early in browser startup but it still takes time to spin up and early + allocations are thus lost. ### Instructions #### <a name="configure-oophp"></a>Configuration and setup
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn index 92386f4..e85606eb 100644 --- a/extensions/browser/BUILD.gn +++ b/extensions/browser/BUILD.gn
@@ -467,6 +467,7 @@ "//services/device/public/cpp/hid", "//services/device/public/mojom", "//services/service_manager/public/cpp", + "//ui/display:test_support", ] if (is_mac) {
diff --git a/extensions/browser/api/declarative/declarative_api.cc b/extensions/browser/api/declarative/declarative_api.cc index 6ca2658d..6614174 100644 --- a/extensions/browser/api/declarative/declarative_api.cc +++ b/extensions/browser/api/declarative/declarative_api.cc
@@ -139,29 +139,23 @@ RulesFunction::~RulesFunction() {} -bool RulesFunction::HasPermission() { +ExtensionFunction::ResponseAction RulesFunction::Run() { + EXTENSION_FUNCTION_VALIDATE(CreateParams()); + std::string event_name; EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name)); + int web_view_instance_id = 0; EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &web_view_instance_id)); // <webview> embedders use the declarativeWebRequest API via // <webview>.onRequest. - if (web_view_instance_id && extension_->permissions_data()->HasAPIPermission( + if (web_view_instance_id && !extension_->permissions_data()->HasAPIPermission( APIPermission::kWebView)) { - return true; + return RespondNow(Error("Missing webview permission")); } - return ExtensionFunction::HasPermission(); -} -bool RulesFunction::RunAsync() { - std::string event_name; - EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name)); - - int web_view_instance_id = 0; - EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(1, &web_view_instance_id)); int embedder_process_id = render_frame_host()->GetProcess()->GetID(); - RecordUMA(event_name); bool from_web_view = web_view_instance_id != 0; @@ -189,43 +183,50 @@ // there should never be a request for a nonexisting rules registry. EXTENSION_FUNCTION_VALIDATE(rules_registry_.get()); - if (content::BrowserThread::CurrentlyOn(rules_registry_->owner_thread())) { - bool success = RunAsyncOnCorrectThread(); - SendResponse(success); - } else { - scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner = - content::BrowserThread::GetTaskRunnerForThread( - rules_registry_->owner_thread()); - base::PostTaskAndReplyWithResult( - thread_task_runner.get(), FROM_HERE, - base::Bind(&RulesFunction::RunAsyncOnCorrectThread, this), - base::Bind(&RulesFunction::SendResponse, this)); - } + if (content::BrowserThread::CurrentlyOn(rules_registry_->owner_thread())) + return RespondNow(RunAsyncOnCorrectThread()); - return true; + scoped_refptr<base::SingleThreadTaskRunner> thread_task_runner = + content::BrowserThread::GetTaskRunnerForThread( + rules_registry_->owner_thread()); + base::PostTaskAndReplyWithResult( + thread_task_runner.get(), FROM_HERE, + base::BindOnce(&RulesFunction::RunAsyncOnCorrectThread, this), + base::BindOnce(&RulesFunction::SendResponse, this)); + return RespondLater(); } -bool EventsEventAddRulesFunction::RunAsyncOnCorrectThread() { +void RulesFunction::SendResponse(ResponseValue response) { + Respond(std::move(response)); +} + +EventsEventAddRulesFunction::EventsEventAddRulesFunction() = default; + +EventsEventAddRulesFunction::~EventsEventAddRulesFunction() = default; + +bool EventsEventAddRulesFunction::CreateParams() { + params_ = AddRules::Params::Create(*args_); + return params_ != nullptr; +} + +ExtensionFunction::ResponseValue +EventsEventAddRulesFunction::RunAsyncOnCorrectThread() { ConvertBinaryListElementsToBase64(args_.get()); - std::unique_ptr<AddRules::Params> params(AddRules::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); // TODO(devlin): Remove the dependency on linked_ptr here. std::vector<linked_ptr<api::events::Rule>> linked_rules; - for (api::events::Rule& rule : params->rules) { + for (api::events::Rule& rule : params_->rules) { linked_rules.push_back( make_linked_ptr(new api::events::Rule(std::move(rule)))); } - error_ = rules_registry_->AddRules(extension_id(), linked_rules); + std::string error = rules_registry_->AddRules(extension_id(), linked_rules); + if (!error.empty()) + return Error(error); - if (error_.empty()) { - std::unique_ptr<base::ListValue> rules_value(new base::ListValue()); - for (const auto& rule : linked_rules) - rules_value->Append(rule->ToValue()); - SetResult(std::move(rules_value)); - } - - return error_.empty(); + auto rules_value = std::make_unique<base::ListValue>(); + for (const auto& rule : linked_rules) + rules_value->Append(rule->ToValue()); + return OneArgument(std::move(rules_value)); } void EventsEventAddRulesFunction::RecordUMA( @@ -248,19 +249,26 @@ RecordUMAHelper(type); } -bool EventsEventRemoveRulesFunction::RunAsyncOnCorrectThread() { - std::unique_ptr<RemoveRules::Params> params( - RemoveRules::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); +EventsEventRemoveRulesFunction::EventsEventRemoveRulesFunction() = default; - if (params->rule_identifiers.get()) { - error_ = rules_registry_->RemoveRules(extension_id(), - *params->rule_identifiers); +EventsEventRemoveRulesFunction::~EventsEventRemoveRulesFunction() = default; + +bool EventsEventRemoveRulesFunction::CreateParams() { + params_ = RemoveRules::Params::Create(*args_); + return params_ != nullptr; +} + +ExtensionFunction::ResponseValue +EventsEventRemoveRulesFunction::RunAsyncOnCorrectThread() { + std::string error; + if (params_->rule_identifiers.get()) { + error = rules_registry_->RemoveRules(extension_id(), + *params_->rule_identifiers); } else { - error_ = rules_registry_->RemoveAllRules(extension_id()); + error = rules_registry_->RemoveAllRules(extension_id()); } - return error_.empty(); + return error.empty() ? NoArguments() : Error(error); } void EventsEventRemoveRulesFunction::RecordUMA( @@ -283,24 +291,29 @@ RecordUMAHelper(type); } -bool EventsEventGetRulesFunction::RunAsyncOnCorrectThread() { - std::unique_ptr<GetRules::Params> params(GetRules::Params::Create(*args_)); - EXTENSION_FUNCTION_VALIDATE(params.get()); +EventsEventGetRulesFunction::EventsEventGetRulesFunction() = default; +EventsEventGetRulesFunction::~EventsEventGetRulesFunction() = default; + +bool EventsEventGetRulesFunction::CreateParams() { + params_ = GetRules::Params::Create(*args_); + return params_ != nullptr; +} + +ExtensionFunction::ResponseValue +EventsEventGetRulesFunction::RunAsyncOnCorrectThread() { std::vector<linked_ptr<Rule> > rules; - if (params->rule_identifiers.get()) { - rules_registry_->GetRules( - extension_id(), *params->rule_identifiers, &rules); + if (params_->rule_identifiers.get()) { + rules_registry_->GetRules(extension_id(), *params_->rule_identifiers, + &rules); } else { rules_registry_->GetAllRules(extension_id(), &rules); } - std::unique_ptr<base::ListValue> rules_value(new base::ListValue()); + auto rules_value = std::make_unique<base::ListValue>(); for (const auto& rule : rules) rules_value->Append(rule->ToValue()); - SetResult(std::move(rules_value)); - - return true; + return OneArgument(std::move(rules_value)); } void EventsEventGetRulesFunction::RecordUMA(
diff --git a/extensions/browser/api/declarative/declarative_api.h b/extensions/browser/api/declarative/declarative_api.h index 781e5c7..ceaa341 100644 --- a/extensions/browser/api/declarative/declarative_api.h +++ b/extensions/browser/api/declarative/declarative_api.h
@@ -13,7 +13,23 @@ namespace extensions { -class RulesFunction : public AsyncExtensionFunction { +namespace api { +namespace events { +namespace Event { +namespace AddRules { +struct Params; +} // namespace AddRules +namespace GetRules { +struct Params; +} // namespace GetRules +namespace RemoveRules { +struct Params; +} // namespace RemoveRules +} // namespace Event +} // namespace events +} // namespace api + +class RulesFunction : public UIThreadExtensionFunction { public: RulesFunction(); @@ -21,54 +37,80 @@ ~RulesFunction() override; // ExtensionFunction: - bool HasPermission() override; - bool RunAsync() override; + ResponseAction Run() override; + + // Returns whether or not params creation succeeded, the result is used to + // validate params. + virtual bool CreateParams() = 0; // Concrete implementation of the RulesFunction that is being called // on the thread on which the respective RulesRegistry lives. // Returns false in case of errors. - virtual bool RunAsyncOnCorrectThread() = 0; + virtual ResponseValue RunAsyncOnCorrectThread() = 0; // Records UMA metrics for the kind of declarative API call. virtual void RecordUMA(const std::string& event_name) const = 0; scoped_refptr<RulesRegistry> rules_registry_; + + private: + void SendResponse(ResponseValue response); + + DISALLOW_COPY_AND_ASSIGN(RulesFunction); }; class EventsEventAddRulesFunction : public RulesFunction { public: DECLARE_EXTENSION_FUNCTION("events.addRules", EVENTS_ADDRULES) + EventsEventAddRulesFunction(); + protected: - ~EventsEventAddRulesFunction() override {} + ~EventsEventAddRulesFunction() override; // RulesFunction: - bool RunAsyncOnCorrectThread() override; + bool CreateParams() override; + ResponseValue RunAsyncOnCorrectThread() override; void RecordUMA(const std::string& event_name) const override; + + private: + std::unique_ptr<api::events::Event::AddRules::Params> params_; }; class EventsEventRemoveRulesFunction : public RulesFunction { public: DECLARE_EXTENSION_FUNCTION("events.removeRules", EVENTS_REMOVERULES) + EventsEventRemoveRulesFunction(); + protected: - ~EventsEventRemoveRulesFunction() override {} + ~EventsEventRemoveRulesFunction() override; // RulesFunction: - bool RunAsyncOnCorrectThread() override; + bool CreateParams() override; + ResponseValue RunAsyncOnCorrectThread() override; void RecordUMA(const std::string& event_name) const override; + + private: + std::unique_ptr<api::events::Event::RemoveRules::Params> params_; }; class EventsEventGetRulesFunction : public RulesFunction { public: DECLARE_EXTENSION_FUNCTION("events.getRules", EVENTS_GETRULES) + EventsEventGetRulesFunction(); + protected: - ~EventsEventGetRulesFunction() override {} + ~EventsEventGetRulesFunction() override; // RulesFunction: - bool RunAsyncOnCorrectThread() override; + bool CreateParams() override; + ResponseValue RunAsyncOnCorrectThread() override; void RecordUMA(const std::string& event_name) const override; + + private: + std::unique_ptr<api::events::Event::GetRules::Params> params_; }; } // namespace extensions
diff --git a/extensions/browser/api/system_display/system_display_apitest.cc b/extensions/browser/api/system_display/system_display_apitest.cc index 524a95a0..03a4194 100644 --- a/extensions/browser/api/system_display/system_display_apitest.cc +++ b/extensions/browser/api/system_display/system_display_apitest.cc
@@ -21,12 +21,14 @@ #include "extensions/test/result_catcher.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/display/test/scoped_screen_override.h" namespace extensions { using api::system_display::Bounds; using api::system_display::DisplayUnitInfo; using display::Screen; +using display::test::ScopedScreenOverride; class MockScreen : public Screen { public: @@ -216,7 +218,8 @@ void SetUpOnMainThread() override { ShellApiTest::SetUpOnMainThread(); ANNOTATE_LEAKING_OBJECT_PTR(display::Screen::GetScreen()); - display::Screen::SetScreenInstance(screen_.get()); + scoped_screen_override_ = + std::make_unique<ScopedScreenOverride>(screen_.get()); DisplayInfoProvider::InitializeForTesting(provider_.get()); } @@ -229,6 +232,7 @@ } std::unique_ptr<MockDisplayInfoProvider> provider_; std::unique_ptr<display::Screen> screen_; + std::unique_ptr<ScopedScreenOverride> scoped_screen_override_; private: DISALLOW_COPY_AND_ASSIGN(SystemDisplayApiTest);
diff --git a/extensions/browser/api/web_request/web_request_permissions.cc b/extensions/browser/api/web_request/web_request_permissions.cc index cbdec3b..320cd7e 100644 --- a/extensions/browser/api/web_request/web_request_permissions.cc +++ b/extensions/browser/api/web_request/web_request_permissions.cc
@@ -84,18 +84,7 @@ // modified/canceled by extensions, e.g. because it is targeted to the webstore // to check for updates, extension blacklisting, etc. bool IsSensitiveURL(const GURL& url, - bool is_request_from_browser, - bool is_request_from_webui_renderer) { - const bool is_request_from_sensitive_source = - is_request_from_browser || is_request_from_webui_renderer; - - // WebUI renderers should never be making network requests. We assert that - // here just to be sure. - const bool is_network_request = - url.SchemeIsHTTPOrHTTPS() || url.SchemeIsWSOrWSS(); - DCHECK(!is_network_request || !is_request_from_webui_renderer) - << "Unsupported network request from WebUI for " << url.spec(); - + bool is_request_from_browser_or_webui_renderer) { // TODO(battre) Merge this, CanExtensionAccessURL and // PermissionsData::CanAccessPage into one function. bool sensitive_chrome_url = false; @@ -114,7 +103,7 @@ // These URLs are only protected for requests from the browser and webui // renderers, not for requests from common renderers, because // clients*.google.com are also used by websites. - if (is_request_from_sensitive_source) { + if (is_request_from_browser_or_webui_renderer) { base::StringPiece::size_type pos = host.rfind(kClient); if (pos != base::StringPiece::npos) { bool match = true; @@ -143,7 +132,7 @@ base::CompareCase::SENSITIVE)); } - if (is_request_from_sensitive_source) { + if (is_request_from_browser_or_webui_renderer) { sensitive_chrome_url = sensitive_chrome_url || extensions::ExtensionsAPIClient::Get()->ShouldHideBrowserNetworkRequest( @@ -196,8 +185,8 @@ request.render_process_id); } - return IsSensitiveURL(request.url, is_request_from_browser, - is_request_from_webui_renderer) || + return IsSensitiveURL(request.url, is_request_from_browser || + is_request_from_webui_renderer) || !HasWebRequestScheme(request.url); }
diff --git a/extensions/browser/api/web_request/web_request_permissions.h b/extensions/browser/api/web_request/web_request_permissions.h index b04712a8..7283a430 100644 --- a/extensions/browser/api/web_request/web_request_permissions.h +++ b/extensions/browser/api/web_request/web_request_permissions.h
@@ -22,8 +22,7 @@ // Exposed for unit testing. bool IsSensitiveURL(const GURL& url, - bool is_request_from_browser, - bool is_request_from_webui_renderer); + bool is_request_from_browser_or_webui_renderer); // This class is used to test whether extensions may modify web requests. class WebRequestPermissions {
diff --git a/extensions/browser/api/web_request/web_request_permissions_unittest.cc b/extensions/browser/api/web_request/web_request_permissions_unittest.cc index 9efa392..1bb7db6b 100644 --- a/extensions/browser/api/web_request/web_request_permissions_unittest.cc +++ b/extensions/browser/api/web_request/web_request_permissions_unittest.cc
@@ -58,14 +58,12 @@ GURL url(test.url); EXPECT_TRUE(url.is_valid()) << test.url; EXPECT_EQ(test.is_sensitive_if_request_from_common_renderer, - IsSensitiveURL(url, false /* is_request_from_browser */, - false /* is_request_from_web_ui_renderer */)) + IsSensitiveURL( + url, false /* is_request_from_browser_or_webui_renderer */)) << test.url; - - const bool supported_in_webui_renderers = !url.SchemeIsHTTPOrHTTPS(); EXPECT_EQ(test.is_sensitive_if_request_from_browser_or_webui_renderer, - IsSensitiveURL(url, true /* is_request_from_browser */, - supported_in_webui_renderers)) + IsSensitiveURL( + url, true /* is_request_from_browser_or_webui_renderer */)) << test.url; } }
diff --git a/google_apis/gaia/oauth2_api_call_flow_unittest.cc b/google_apis/gaia/oauth2_api_call_flow_unittest.cc index c95a14a..04666db9 100644 --- a/google_apis/gaia/oauth2_api_call_flow_unittest.cc +++ b/google_apis/gaia/oauth2_api_call_flow_unittest.cc
@@ -8,7 +8,7 @@ #include <memory> #include <string> -#include <vector> +#include <utility> #include "base/message_loop/message_loop.h" #include "base/time/time.h" @@ -39,6 +39,7 @@ using net::URLRequestContextGetter; using net::URLRequestStatus; using testing::_; +using testing::ByMove; using testing::Return; using testing::StrictMock; @@ -64,13 +65,13 @@ } virtual ~MockUrlFetcherFactory() {} - MOCK_METHOD5( - CreateURLFetcherMock, - URLFetcher*(int id, - const GURL& url, - URLFetcher::RequestType request_type, - URLFetcherDelegate* d, - net::NetworkTrafficAnnotationTag traffic_annotation)); + MOCK_METHOD5(CreateURLFetcherMock, + std::unique_ptr<URLFetcher>( + int id, + const GURL& url, + URLFetcher::RequestType request_type, + URLFetcherDelegate* d, + net::NetworkTrafficAnnotationTag traffic_annotation)); std::unique_ptr<URLFetcher> CreateURLFetcher( int id, @@ -78,8 +79,7 @@ URLFetcher::RequestType request_type, URLFetcherDelegate* d, net::NetworkTrafficAnnotationTag traffic_annotation) override { - return std::unique_ptr<URLFetcher>( - CreateURLFetcherMock(id, url, request_type, d, traffic_annotation)); + return CreateURLFetcherMock(id, url, request_type, d, traffic_annotation); } }; @@ -88,16 +88,13 @@ MockApiCallFlow() {} ~MockApiCallFlow() {} - MOCK_METHOD0(CreateApiCallUrl, GURL ()); - MOCK_METHOD0(CreateApiCallBody, std::string ()); - MOCK_METHOD1(ProcessApiCallSuccess, - void (const URLFetcher* source)); - MOCK_METHOD1(ProcessApiCallFailure, - void (const URLFetcher* source)); - MOCK_METHOD1(ProcessNewAccessToken, - void (const std::string& access_token)); + MOCK_METHOD0(CreateApiCallUrl, GURL()); + MOCK_METHOD0(CreateApiCallBody, std::string()); + MOCK_METHOD1(ProcessApiCallSuccess, void(const URLFetcher* source)); + MOCK_METHOD1(ProcessApiCallFailure, void(const URLFetcher* source)); + MOCK_METHOD1(ProcessNewAccessToken, void(const std::string& access_token)); MOCK_METHOD1(ProcessMintAccessTokenFailure, - void (const GoogleServiceAuthError& error)); + void(const GoogleServiceAuthError& error)); net::PartialNetworkTrafficAnnotationTag GetNetworkTrafficAnnotationTag() { return PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS; @@ -109,13 +106,15 @@ class OAuth2ApiCallFlowTest : public testing::Test { protected: OAuth2ApiCallFlowTest() - : request_context_getter_(new net::TestURLRequestContextGetter( - message_loop_.task_runner())) {} + : request_context_getter_( + base::MakeRefCounted<net::TestURLRequestContextGetter>( + message_loop_.task_runner())) {} - TestURLFetcher* CreateURLFetcher( - const GURL& url, bool fetch_succeeds, - int response_code, const std::string& body) { - TestURLFetcher* url_fetcher = new TestURLFetcher(0, url, &flow_); + std::unique_ptr<TestURLFetcher> CreateURLFetcher(const GURL& url, + bool fetch_succeeds, + int response_code, + const std::string& body) { + auto url_fetcher = std::make_unique<TestURLFetcher>(0, url, &flow_); net::Error error = fetch_succeeds ? net::OK : net::ERR_FAILED; url_fetcher->set_status(URLRequestStatus::FromError(error)); @@ -133,11 +132,12 @@ GURL url(CreateApiUrl()); EXPECT_CALL(flow_, CreateApiCallBody()).WillOnce(Return(body)); EXPECT_CALL(flow_, CreateApiCallUrl()).WillOnce(Return(url)); - TestURLFetcher* url_fetcher = + std::unique_ptr<TestURLFetcher> url_fetcher = CreateURLFetcher(url, succeeds, status, std::string()); + TestURLFetcher* url_fetcher_ptr = url_fetcher.get(); EXPECT_CALL(factory_, CreateURLFetcherMock(_, url, _, _, _)) - .WillOnce(Return(url_fetcher)); - return url_fetcher; + .WillOnce(Return(ByMove(std::move(url_fetcher)))); + return url_fetcher_ptr; } base::MessageLoop message_loop_;
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc index eba31b6..41b41c0c 100644 --- a/headless/lib/browser/headless_content_browser_client.cc +++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -15,6 +15,7 @@ #include "base/strings/string_number_conversions.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" +#include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/resource_dispatcher_host.h" @@ -30,6 +31,7 @@ #include "headless/lib/browser/headless_quota_permission_context.h" #include "headless/lib/headless_macros.h" #include "net/base/url_util.h" +#include "net/ssl/client_cert_identity.h" #include "storage/browser/quota/quota_settings.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/ui_base_switches.h" @@ -321,6 +323,14 @@ } } +void HeadlessContentBrowserClient::SelectClientCertificate( + content::WebContents* web_contents, + net::SSLCertRequestInfo* cert_request_info, + net::ClientCertIdentityList client_certs, + std::unique_ptr<content::ClientCertificateDelegate> delegate) { + delegate->ContinueWithCertificate(nullptr, nullptr); +} + void HeadlessContentBrowserClient::ResourceDispatcherHostCreated() { resource_dispatcher_host_delegate_.reset( new HeadlessResourceDispatcherHostDelegate);
diff --git a/headless/lib/browser/headless_content_browser_client.h b/headless/lib/browser/headless_content_browser_client.h index e05bd02..6980a87 100644 --- a/headless/lib/browser/headless_content_browser_client.h +++ b/headless/lib/browser/headless_content_browser_client.h
@@ -52,6 +52,12 @@ const base::Callback<void(content::CertificateRequestResultType)>& callback) override; + void SelectClientCertificate( + content::WebContents* web_contents, + net::SSLCertRequestInfo* cert_request_info, + net::ClientCertIdentityList client_certs, + std::unique_ptr<content::ClientCertificateDelegate> delegate) override; + void ResourceDispatcherHostCreated() override; net::NetLog* GetNetLog() override;
diff --git a/headless/lib/headless_browser_browsertest.cc b/headless/lib/headless_browser_browsertest.cc index 63142ec..735e470 100644 --- a/headless/lib/headless_browser_browsertest.cc +++ b/headless/lib/headless_browser_browsertest.cc
@@ -971,4 +971,23 @@ (void)web_contents; } +IN_PROC_BROWSER_TEST_F(HeadlessBrowserTest, ServerWantsClientCertificate) { + net::SpawnedTestServer::SSLOptions ssl_options; + ssl_options.request_client_certificate = true; + + net::SpawnedTestServer server( + net::SpawnedTestServer::TYPE_HTTPS, ssl_options, + base::FilePath(FILE_PATH_LITERAL("headless/test/data"))); + EXPECT_TRUE(server.Start()); + + HeadlessBrowserContext* browser_context = + browser()->CreateBrowserContextBuilder().Build(); + + HeadlessWebContents* web_contents = + browser_context->CreateWebContentsBuilder() + .SetInitialURL(server.GetURL("/hello.html")) + .Build(); + EXPECT_TRUE(WaitForLoad(web_contents)); +} + } // namespace headless
diff --git a/infra/config/global/cr-buildbucket.cfg b/infra/config/global/cr-buildbucket.cfg index db672e2..cceda1d 100644 --- a/infra/config/global/cr-buildbucket.cfg +++ b/infra/config/global/cr-buildbucket.cfg
@@ -1113,6 +1113,18 @@ mixins: "goma-j150" name: "linux_chromium_rel_ng" } + builders { + mixins: "linux-try" + mixins: "goma-j150" + name: "linux_chromium_rel_ng_patch_on_gclient" + dimensions: "builder:linux_chromium_rel_ng" + experimental: YES + auto_builder_dimension: NO + recipe { + properties: "buildername:linux_chromium_rel_ng" + properties_j: "$depot_tools/bot_update:{\"apply_patch_on_gclient\":true}" + } + } builders { mixins: "linux-try" name: "linux_chromium_tsan_rel_ng" } builders { mixins: "linux-try" name: "linux_chromium_tsan_variable" } builders { mixins: "linux-try" name: "linux_chromium_ubsan_rel_ng" }
diff --git a/infra/config/global/luci-milo-dev.cfg b/infra/config/global/luci-milo-dev.cfg index ec73a6b..abf2911f4 100644 --- a/infra/config/global/luci-milo-dev.cfg +++ b/infra/config/global/luci-milo-dev.cfg
@@ -2983,18 +2983,22 @@ header_id: "chromium" builders: { - name: "buildbot/chromium.perf.fyi/Android Builder FYI" + name: "buildbot/chromium.perf.fyi/Android Builder Perf FYI" category: "android" } builders: { - name: "buildbot/chromium.perf.fyi/Android arm64 Builder FYI" + name: "buildbot/chromium.perf.fyi/Android arm64 Builder Perf FYI" category: "android" } builders: { - name: "buildbot/chromium.perf.fyi/Linux Compile FYI" + name: "buildbot/chromium.perf.fyi/Linux Compile Perf FYI" category: "linux" } builders: { + name: "buildbot/chromium.perf.fyi/Mac Builder Perf FYI" + category: "mac" + } + builders: { name: "buildbot/chromium.perf.fyi/Android Nexus 5X Perf FYI" category: "android" } @@ -3031,10 +3035,6 @@ category: "mac" } builders: { - name: "buildbot/chromium.perf.fyi/Mac Builder FYI" - category: "mac" - } - builders: { name: "buildbot/chromium.perf.fyi/Android Go" category: "android" }
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index 5308d2f..a9a83a1 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -281,6 +281,9 @@ {"unified-consent", flag_descriptions::kUnifiedConsentName, flag_descriptions::kUnifiedConsentDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(signin::kUnifiedConsent)}, + {"autofill-dynamic-forms", flag_descriptions::kAutofillDynamicFormsName, + flag_descriptions::kAutofillDynamicFormsDescription, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(autofill::features::kAutofillDynamicForms)}, }; // Add all switches from experimental flags to |command_line|.
diff --git a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm index 278d5c9..d752fa33 100644 --- a/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm +++ b/ios/chrome/browser/autofill/form_input_accessory_view_controller.mm
@@ -460,7 +460,8 @@ return; } - if ((params.type == "blur" || params.type == "change")) { + if (params.type == "blur" || params.type == "change" || + params.type == "form_changed") { return; }
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc index 51737b4..c9011c7 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -16,6 +16,10 @@ "Delay between the different fields of a form being autofilled. In " "milliseconds."; +const char kAutofillDynamicFormsName[] = "Autofill dynamic forms"; +const char kAutofillDynamicFormsDescription[] = + "Refills forms that dynamically change after an initial fill"; + const char kBrowserTaskScheduler[] = "Task Scheduler"; const char kBrowserTaskSchedulerDescription[] = "Enables redirection of some task posting APIs to the task scheduler.";
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h index 22ae52d..c8b1a63e3 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -11,6 +11,10 @@ extern const char kAutofillIOSDelayBetweenFieldsName[]; extern const char kAutofillIOSDelayBetweenFieldsDescription[]; +// Title and description for the flag to controll the dynamic autofill. +extern const char kAutofillDynamicFormsName[]; +extern const char kAutofillDynamicFormsDescription[]; + // Title and description for the flag to control redirection to the task // scheduler. extern const char kBrowserTaskScheduler[];
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm index 92227cb..97c4181e 100644 --- a/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm +++ b/ios/chrome/browser/metrics/ios_chrome_metrics_service_client.mm
@@ -176,8 +176,13 @@ metrics_service_ = std::make_unique<metrics::MetricsService>( metrics_state_manager_, this, local_state); + // Always restrict on iOS. + // TODO(crbug.com/828878): Use the flag to set this. + bool restrict_to_whitelist_entries = true; + if (base::FeatureList::IsEnabled(ukm::kUkmFeature)) - ukm_service_ = std::make_unique<ukm::UkmService>(local_state, this); + ukm_service_ = std::make_unique<ukm::UkmService>( + local_state, this, restrict_to_whitelist_entries); // Register metrics providers. metrics_service_->RegisterMetricsProvider(
diff --git a/ios/chrome/browser/passwords/js_password_manager.h b/ios/chrome/browser/passwords/js_password_manager.h index 93a429fa..a2dc1af 100644 --- a/ios/chrome/browser/passwords/js_password_manager.h +++ b/ios/chrome/browser/passwords/js_password_manager.h
@@ -6,16 +6,14 @@ #define IOS_CHROME_BROWSER_PASSWORDS_JS_PASSWORD_MANAGER_H_ #include "base/ios/block_types.h" -#import "ios/web/public/web_state/js/crw_js_injection_manager.h" - -@class CRWJSInjectionReceiver; +#import "ios/web/public/web_state/js/crw_js_injection_receiver.h" // Loads the JavaScript file, password_controller.js, which contains password // form parsing and autofill functions. It will be evaluated on a page that // is known to have at least one password form (see hasPasswordField_ in // password_controller.js) It returns contents of those password forms and also // registers functions that are later used to autofill them. -@interface JsPasswordManager : CRWJSInjectionManager +@interface JsPasswordManager : NSObject // Finds any password forms on the web page. // |completionHandler| is then called with the JSON string result (which can @@ -48,6 +46,12 @@ password:(NSString*)password completionHandler:(void (^)(BOOL))completionHandler; +// Designated initializer. |receiver| should not be nil. +- (instancetype)initWithReceiver:(CRWJSInjectionReceiver*)receiver + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + @end #endif // IOS_CHROME_BROWSER_PASSWORDS_JS_PASSWORD_MANAGER_H_
diff --git a/ios/chrome/browser/passwords/js_password_manager.mm b/ios/chrome/browser/passwords/js_password_manager.mm index 371ab3b..31f7d88 100644 --- a/ios/chrome/browser/passwords/js_password_manager.mm +++ b/ios/chrome/browser/passwords/js_password_manager.mm
@@ -22,32 +22,39 @@ } } // namespace -@interface JsPasswordManager () -// Injects a script that does two things: -// 1. Injects password controller JavaScript in the page. -// 2. Extracts the _submitted_ password form data from the DOM on the page. -// The result is returned in |completionHandler|. -// |completionHandler| cannot be nil. -- (void)evaluateExtraScript:(NSString*)script - completionHandler:(void (^)(NSString*))completionHandler; -@end +@implementation JsPasswordManager { + // The injection receiver used to evaluate JavaScript. + CRWJSInjectionReceiver* _receiver; +} -@implementation JsPasswordManager +- (instancetype)initWithReceiver:(CRWJSInjectionReceiver*)receiver { + DCHECK(receiver); + self = [super init]; + if (self) { + _receiver = receiver; + } + return self; +} - (void)findPasswordFormsWithCompletionHandler: (void (^)(NSString*))completionHandler { DCHECK(completionHandler); - [self evaluateExtraScript:@"__gCrWeb.findPasswordForms()" - completionHandler:completionHandler]; + [_receiver executeJavaScript:@"__gCrWeb.passwords.findPasswordForms()" + completionHandler:^(id result, NSError*) { + completionHandler(base::mac::ObjCCastStrict<NSString>(result)); + }]; } - (void)extractForm:(NSString*)formName completionHandler:(void (^)(NSString*))completionHandler { DCHECK(completionHandler); - NSString* extra = - [NSString stringWithFormat:@"__gCrWeb.getPasswordFormDataAsString(%@)", - JSONEscape(formName)]; - [self evaluateExtraScript:extra completionHandler:completionHandler]; + NSString* extra = [NSString + stringWithFormat:@"__gCrWeb.passwords.getPasswordFormDataAsString(%@)", + JSONEscape(formName)]; + [_receiver executeJavaScript:extra + completionHandler:^(id result, NSError*) { + completionHandler(base::mac::ObjCCastStrict<NSString>(result)); + }]; } - (void)fillPasswordForm:(NSString*)JSONString @@ -56,30 +63,13 @@ completionHandler:(void (^)(BOOL))completionHandler { DCHECK(completionHandler); NSString* script = [NSString - stringWithFormat:@"__gCrWeb.fillPasswordForm(%@, %@, %@)", JSONString, - JSONEscape(username), JSONEscape(password)]; - [self executeJavaScript:script completionHandler:^(id result, NSError*) { - completionHandler([result isEqual:@YES]); - }]; + stringWithFormat:@"__gCrWeb.passwords.fillPasswordForm(%@, %@, %@)", + JSONString, JSONEscape(username), JSONEscape(password)]; + [_receiver executeJavaScript:script + completionHandler:^(id result, NSError*) { + completionHandler([result isEqual:@YES]); + }]; } -#pragma mark - -#pragma mark ProtectedMethods - -- (NSString*)scriptPath { - return @"password_controller"; -} - -#pragma mark - -#pragma mark Private - -- (void)evaluateExtraScript:(NSString*)script - completionHandler:(void (^)(NSString*))completionHandler { - DCHECK(completionHandler); - NSString* JS = [[self injectionContent] stringByAppendingString:script]; - [self executeJavaScript:JS completionHandler:^(id result, NSError*) { - completionHandler(base::mac::ObjCCastStrict<NSString>(result)); - }]; -} @end
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm index 99e44d2..b840e949 100644 --- a/ios/chrome/browser/passwords/password_controller.mm +++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -268,7 +268,7 @@ std::unique_ptr<PasswordManagerDriver> passwordManagerDriver_; std::unique_ptr<CredentialManager> credentialManager_; - __weak JsPasswordManager* passwordJsManager_; + JsPasswordManager* passwordJsManager_; AccountSelectFillData fillData_; @@ -327,12 +327,11 @@ passwordManager_.reset(new PasswordManager(passwordManagerClient_.get())); passwordManagerDriver_.reset(new IOSChromePasswordManagerDriver(self)); - passwordJsManager_ = base::mac::ObjCCastStrict<JsPasswordManager>( - [webState_->GetJSInjectionReceiver() - instanceOfClass:[JsPasswordManager class]]); webStateObserverBridge_ = std::make_unique<web::WebStateObserverBridge>(self); webState_->AddObserver(webStateObserverBridge_.get()); + passwordJsManager_ = [[JsPasswordManager alloc] + initWithReceiver:webState_->GetJSInjectionReceiver()]; sentRequestToStore_ = NO; if (base::FeatureList::IsEnabled(features::kCredentialManager)) {
diff --git a/ios/chrome/browser/passwords/password_controller_js_unittest.mm b/ios/chrome/browser/passwords/password_controller_js_unittest.mm index 600c3bc..c411a354 100644 --- a/ios/chrome/browser/passwords/password_controller_js_unittest.mm +++ b/ios/chrome/browser/passwords/password_controller_js_unittest.mm
@@ -22,10 +22,8 @@ : public web::WebJsTest<web::WebTestWithWebState> { public: PasswordControllerJsTest() - : web::WebJsTest<web::WebTestWithWebState>(@[ - @"chrome_bundle_all_frames", @"chrome_bundle_main_frame", - @"password_controller" - ]) {} + : web::WebJsTest<web::WebTestWithWebState>( + @[ @"chrome_bundle_all_frames", @"chrome_bundle_main_frame" ]) {} }; // IDs used in the Username and Password <input> elements. @@ -77,10 +75,11 @@ NSString* const username = @"john.doe@gmail.com"; NSString* const password = @"super!secret"; LoadHtmlAndInject(GAIASignInForm(formAction, username, YES)); - EXPECT_NSEQ(@YES, ExecuteJavaScriptWithFormat( - @"__gCrWeb.fillPasswordForm(%@, '%@', '%@', '%@')", - GAIASignInFormData(formAction), username, password, - formAction)); + EXPECT_NSEQ( + @YES, + ExecuteJavaScriptWithFormat( + @"__gCrWeb.passwords.fillPasswordForm(%@, '%@', '%@', '%@')", + GAIASignInFormData(formAction), username, password, formAction)); // Verifies that the sign-in form has been filled with username/password. ExecuteJavaScriptOnElementsAndCheck(@"document.getElementById('%@').value", @[ kEmailInputID, kPasswordInputID ], @@ -97,10 +96,11 @@ NSString* const username2 = @"jean.dubois@gmail.com"; NSString* const password = @"super!secret"; LoadHtmlAndInject(GAIASignInForm(formAction, username1, YES)); - EXPECT_NSEQ(@NO, ExecuteJavaScriptWithFormat( - @"__gCrWeb.fillPasswordForm(%@, '%@', '%@', '%@')", - GAIASignInFormData(formAction), username2, password, - formAction)); + EXPECT_NSEQ( + @NO, + ExecuteJavaScriptWithFormat( + @"__gCrWeb.passwords.fillPasswordForm(%@, '%@', '%@', '%@')", + GAIASignInFormData(formAction), username2, password, formAction)); // Verifies that the sign-in form has not been filled. ExecuteJavaScriptOnElementsAndCheck(@"document.getElementById('%@').value", @[ kEmailInputID, kPasswordInputID ], @@ -117,10 +117,11 @@ NSString* const username2 = @"jane.doe@gmail.com"; NSString* const password = @"super!secret"; LoadHtmlAndInject(GAIASignInForm(formAction, username1, NO)); - EXPECT_NSEQ(@YES, ExecuteJavaScriptWithFormat( - @"__gCrWeb.fillPasswordForm(%@, '%@', '%@', '%@')", - GAIASignInFormData(formAction), username2, password, - formAction)); + EXPECT_NSEQ( + @YES, + ExecuteJavaScriptWithFormat( + @"__gCrWeb.passwords.fillPasswordForm(%@, '%@', '%@', '%@')", + GAIASignInFormData(formAction), username2, password, formAction)); // Verifies that the sign-in form has been filled with the new username // and password. ExecuteJavaScriptOnElementsAndCheck(@"document.getElementById('%@').value", @@ -154,8 +155,8 @@ @"\"max_length\":524288,\"is_checkable\":false,\"value\":\"\"," @"\"label\":\"Password:\"}]}]", base_url.c_str()]; - EXPECT_NSEQ(result, - ExecuteJavaScriptWithFormat(@"__gCrWeb.findPasswordForms()")); + EXPECT_NSEQ(result, ExecuteJavaScriptWithFormat( + @"__gCrWeb.passwords.findPasswordForms()")); }; // Check that multiple password forms are identified and serialized correctly. @@ -198,8 +199,8 @@ @"\"label\":\"Password:\"}]}]", base_url.c_str(), base_url.c_str()]; - EXPECT_NSEQ(result, - ExecuteJavaScriptWithFormat(@"__gCrWeb.findPasswordForms()")); + EXPECT_NSEQ(result, ExecuteJavaScriptWithFormat( + @"__gCrWeb.passwords.findPasswordForms()")); }; // Test serializing of password forms. @@ -231,7 +232,8 @@ EXPECT_NSEQ( result, ExecuteJavaScriptWithFormat( - @"__gCrWeb.stringify(__gCrWeb.getPasswordFormData(%@))", parameter)); + @"__gCrWeb.stringify(__gCrWeb.passwords.getPasswordFormData(%@))", + parameter)); }; // Check that if a form action is not set then the action is parsed to the @@ -258,8 +260,8 @@ @"autocomplete\":true,\"is_focusable\":true,\"max_length\":524288," @"\"is_checkable\":false,\"value\":\"\",\"label\":\"Password:\"}]}]", base_url.c_str(), base_url.c_str()]; - EXPECT_NSEQ(result, - ExecuteJavaScriptWithFormat(@"__gCrWeb.findPasswordForms()")); + EXPECT_NSEQ(result, ExecuteJavaScriptWithFormat( + @"__gCrWeb.passwords.findPasswordForms()")); }; // Checks that a touchend event from a button which contains in a password form @@ -274,9 +276,9 @@ "</form>" "</body></html>"); - // Call __gCrWeb.findPasswordForms in order to set an event handler on the - // button touchend event. - ExecuteJavaScriptWithFormat(@"__gCrWeb.findPasswordForms()"); + // Call __gCrWeb.passwords.findPasswordForms in order to set an event handler + // on the button touchend event. + ExecuteJavaScriptWithFormat(@"__gCrWeb.passwords.findPasswordForms()"); // Replace __gCrWeb.message.invokeOnHost with mock method for checking of call // arguments. @@ -348,7 +350,7 @@ page_origin.c_str(), form_fill_data_origin.c_str()]; EXPECT_NSEQ(@YES, ExecuteJavaScriptWithFormat( - @"__gCrWeb.fillPasswordForm(%@, '%@', '%@', '%s')", + @"__gCrWeb.passwords.fillPasswordForm(%@, '%@', '%@', '%s')", form_fill_data, username, password, page_origin.c_str())); // Verifies that the sign-in form has been filled with username/password. ExecuteJavaScriptOnElementsAndCheck(@"document.getElementById('%@').value",
diff --git a/ios/chrome/browser/passwords/password_controller_unittest.mm b/ios/chrome/browser/passwords/password_controller_unittest.mm index e21bcf4e..de326c8 100644 --- a/ios/chrome/browser/passwords/password_controller_unittest.mm +++ b/ios/chrome/browser/passwords/password_controller_unittest.mm
@@ -1127,6 +1127,11 @@ TestChromeBrowserState::Builder builder; std::unique_ptr<TestChromeBrowserState> browser_state(builder.Build()); MockWebState web_state; + id mock_js_injection_receiver = + [OCMockObject mockForClass:[CRWJSInjectionReceiver class]]; + [[mock_js_injection_receiver expect] executeJavaScript:[OCMArg any] + completionHandler:[OCMArg any]]; + web_state.SetJSInjectionReceiver(mock_js_injection_receiver); ON_CALL(web_state, GetBrowserState()) .WillByDefault(testing::Return(browser_state.get()));
diff --git a/ios/chrome/browser/passwords/resources/password_controller.js b/ios/chrome/browser/passwords/resources/password_controller.js index 6cb85d1..25eade0 100644 --- a/ios/chrome/browser/passwords/resources/password_controller.js +++ b/ios/chrome/browser/passwords/resources/password_controller.js
@@ -2,301 +2,312 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This file adheres to closure-compiler conventions in order to enable -// compilation with ADVANCED_OPTIMIZATIONS. See http://goo.gl/FwOgy -// -// Installs password management functions on the |__gCrWeb| object. -// -// Finds all password forms in the current document and extracts -// their attributes and elements using the same logic as -// third_party/WebKit/Source/WebCore/html/HTMLFormElement.cpp -// -// Returns a JSON string representing an array of objects, -// where each object represents a password form with the discovered -// elements and their values. -// -// The search for password form fields follows the same algorithm -// as the WebKit implementation, see http://goo.gl/4hwh6 +/** + * @fileoverview Installs Passwords management functions on the __gCrWeb object. + * + * It scans the DOM, extracting and storing password forms and returns a JSON + * string representing an array of objects, each of which represents an Passord + * form with information about a form to be filled and/or submitted and it can + * be translated to struct FormData for further processing. + */ -// Only install the password management functions once. -if (__gCrWeb && !__gCrWeb['fillPasswordForm']) { - /** - * Finds all password forms in the window and returns form data as a JSON - * string. - * @return {string} Form data as a JSON string. - */ - __gCrWeb['findPasswordForms'] = function() { - var formDataList = []; - if (hasPasswordField_(window)) { - getPasswordFormDataList_(formDataList, window); +goog.provide('__crWeb.passwords'); + +/* Beginning of anonymous object. */ +(function() { + +/** + * Namespace for this file. It depends on |__gCrWeb| having already been + * injected. + */ +__gCrWeb.passwords = {}; +__gCrWeb['passwords'] = __gCrWeb.passwords; + +/** + * Finds all password forms in the window and returns form data as a JSON + * string. + * @return {string} Form data as a JSON string. + */ +__gCrWeb.passwords['findPasswordForms'] = function() { + var formDataList = []; + if (hasPasswordField_(window)) { + getPasswordFormDataList_(formDataList, window); + } + return __gCrWeb.stringify(formDataList); +}; + +/** Returns true if the supplied window or any frames inside contain an input + * field of type 'password'. + * @private + * @param {Window} win Whether the supplied window or any frames inside + * contain an input field of type 'password'. + * @return {boolean} + */ +var hasPasswordField_ = function(win) { + var doc = win.document; + + // We may will not be allowed to read the 'document' property from a frame + // that is in a different domain. + if (!doc) { + return false; + } + + if (doc.querySelector('input[type=password]')) { + return true; + } + + return getSameOriginFrames_(win).some(hasPasswordField_); +}; + +/** + * Returns the contentWindow of all iframes that are from the the same origin + * as the containing window. + * @param {Window} win The window in which to look for frames. + * @return {Array.<Window>} Array of the same-origin frames found. + */ +var getSameOriginFrames_ = function(win) { + var frames = win.document.getElementsByTagName('iframe'); + var result = []; + for (var i = 0; i < frames.length; i++) { + if (!frames[i].src || + __gCrWeb.common.isSameOrigin(win.location.href, frames[i].src)) { + result.push(frames[i].contentWindow); } - return __gCrWeb.stringify(formDataList); - }; + } + return result; +}; - /** Returns true if the supplied window or any frames inside contain an input - * field of type 'password'. - * @private - * @param {Window} win Whether the supplied window or any frames inside - * contain an input field of type 'password'. - * @return {boolean} - */ - var hasPasswordField_ = function(win) { - var doc = win.document; +/** + * If |form| has no submit elements and exactly 1 button that button + * is assumed to be a submit button. This function adds onSubmitButtonClick_ + * as a handler for touchend event of this button. Touchend event is used as + * a proxy for onclick event because onclick handling might be prevented by + * the site JavaScript. + */ +var addSubmitButtonTouchEndHandler_ = function(form) { + if (form.querySelector('input[type=submit]')) + return; + // Try to find buttons of type submit at first. + var buttons = form.querySelectorAll('button[type="submit"]'); + if (buttons.length == 0) { + // Try to check all buttons. If there is only one button, assume that this + // is the submit button. + buttons = form.querySelectorAll('button'); + if (buttons.length != 1) + return; + } + for (var i = 0; i < buttons.length; ++i) + buttons[0].addEventListener('touchend', onSubmitButtonTouchEnd_); +}; - // We may will not be allowed to read the 'document' property from a frame - // that is in a different domain. - if (!doc) { - return false; +/** + * Click handler for the submit button. It sends to the host + * form.submitButtonClick command. + */ +var onSubmitButtonTouchEnd_ = function(evt) { + var form = evt.currentTarget.form; + var formData = __gCrWeb.passwords.getPasswordFormData(form); + if (!formData) + return; + formData['command'] = 'passwordForm.submitButtonClick'; + __gCrWeb.message.invokeOnHost(formData); +}; + +/** + * Returns the element from |inputs| which has the field identifier equal to + * |identifier| and null if there is no such element. + * @param {Array.<HTMLInputElement>} inputs + * @param {string} identifier + * @return {HTMLInputElement} + */ +var findInputByFieldIdentifier_ = function(inputs, identifier) { + for (var i = 0; i < inputs.length; ++i) { + if (identifier == __gCrWeb.form.getFieldIdentifier(inputs[i])) { + return inputs[i]; } + } + return null; +}; - if (doc.querySelector('input[type=password]')) { - return true; - } +/** + * Returns the password form with the given |identifier| as a JSON string + * from the frame |win| and all its same-origin subframes. + * @param {Window} win The window in which to look for forms. + * @param {string} identifier The name of the form to extract. + * @return {HTMLFormElement} The password form. + */ +var getPasswordFormElement_ = function(win, identifier) { + var el = win.__gCrWeb.form.getFormElementFromIdentifier(identifier); + if (el) + return el; + var frames = getSameOriginFrames_(win); + for (var i = 0; i < frames.length; ++i) { + el = getPasswordFormElement_(frames[i], identifier); + if (el) + return el; + } + return null; +}; - return getSameOriginFrames_(win).some(hasPasswordField_); - }; +/** + * Returns an array of input elements in a form. + * @param {HTMLFormElement} form A form element for which the input elements + * are returned. + * @return {Array<HTMLInputElement>} + */ +var getFormInputElements_ = function(form) { + return __gCrWeb.form.getFormControlElements(form).filter(function(element) { + return element.tagName === 'INPUT'; + }); +}; - /** - * Returns the contentWindow of all iframes that are from the the same origin - * as the containing window. - * @param {Window} win The window in which to look for frames. - * @return {Array.<Window>} Array of the same-origin frames found. - */ - var getSameOriginFrames_ = function(win) { - var frames = win.document.getElementsByTagName('iframe'); - var result = []; - for (var i = 0; i < frames.length; i++) { - if (!frames[i].src || - __gCrWeb.common.isSameOrigin(win.location.href, frames[i].src)) { - result.push(frames[i].contentWindow); - } - } - return result; - }; +/** + * Returns the password form with the given |identifier| as a JSON string. + * @param {string} identifier The identifier of the form to extract. + * @return {string} The password form. + */ +__gCrWeb.passwords['getPasswordFormDataAsString'] = function(identifier) { + var el = getPasswordFormElement_(window, identifier); + if (!el) + return '{}'; + var formData = __gCrWeb.passwords.getPasswordFormData(el); + if (!formData) + return '{}'; + return __gCrWeb.stringify(formData); +}; - /** - * If |form| has no submit elements and exactly 1 button that button - * is assumed to be a submit button. This function adds onSubmitButtonClick_ - * as a handler for touchend event of this button. Touchend event is used as - * a proxy for onclick event because onclick handling might be prevented by - * the site JavaScript. - */ - var addSubmitButtonTouchEndHandler_ = function(form) { - if (form.querySelector('input[type=submit]')) return; - // Try to find buttons of type submit at first. - var buttons = form.querySelectorAll('button[type="submit"]'); - if (buttons.length == 0) { - // Try to check all buttons. If there is only one button, assume that this - // is the submit button. - buttons = form.querySelectorAll('button'); - if (buttons.length != 1) return; - } - for (var i = 0; i < buttons.length; ++i) - buttons[0].addEventListener('touchend', onSubmitButtonTouchEnd_); - }; +/** + * Finds the form described by |formData| and fills in the + * username and password values. + * + * This is a public function invoked by Chrome. There is no information + * passed to this function that the page does not have access to anyway. + * + * @param {AutofillFormData} formData Form data. + * @param {string} username The username to fill. + * @param {string} password The password to fill. + * @param {string=} opt_normalizedOrigin The origin URL to compare to. + * @return {boolean} Whether a form field has been filled. + */ +__gCrWeb.passwords['fillPasswordForm'] = function( + formData, username, password, opt_normalizedOrigin) { + var normalizedOrigin = opt_normalizedOrigin || + __gCrWeb.common.removeQueryAndReferenceFromURL(window.location.href); + var origin = /** @type {string} */ (formData['origin']); + if (!__gCrWeb.common.isSameOrigin(origin, normalizedOrigin)) { + return false; + } + return fillPasswordFormWithData_( + formData, username, password, window, opt_normalizedOrigin); +}; - /** - * Click handler for the submit button. It sends to the host - * form.submitButtonClick command. - */ - var onSubmitButtonTouchEnd_ = function(evt) { - var form = evt.currentTarget.form; - var formData = __gCrWeb.getPasswordFormData(form); - if (!formData) return; - formData['command'] = 'passwordForm.submitButtonClick'; - __gCrWeb.message.invokeOnHost(formData); - }; +/** + * Given a description of a form (origin, action and input fields), + * finds that form on the page and fills in the specified username + * and password. + * + * @param {AutofillFormData} formData Form data. + * @param {string} username The username to fill. + * @param {string} password The password to fill. + * @param {Window} win A window or a frame containing formData. + * @param {string=} opt_normalizedOrigin The origin URL to compare to. + * @return {boolean} Whether a form field has been filled. + */ +var fillPasswordFormWithData_ = function( + formData, username, password, win, opt_normalizedOrigin) { + var doc = win.document; + var forms = doc.forms; + var filled = false; - /** - * Returns the element from |inputs| which has the field identifier equal to - * |identifier| and null if there is no such element. - * @param {Array.<HTMLInputElement>} inputs - * @param {string} identifier - * @return {HTMLInputElement} - */ - var findInputByFieldIdentifier_ = function(inputs, identifier) { - for (var i = 0; i < inputs.length; ++i) { - if (identifier == __gCrWeb.form.getFieldIdentifier(inputs[i])) { - return inputs[i]; - } - } - return null; - }; + for (var i = 0; i < forms.length; i++) { + var form = forms[i]; + var normalizedFormAction = + opt_normalizedOrigin || __gCrWeb.fill.getCanonicalActionForForm(form); + if (formData.action != normalizedFormAction) + continue; + var inputs = getFormInputElements_(form); + var usernameInput = + findInputByFieldIdentifier_(inputs, formData.fields[0].name); + if (usernameInput == null || !__gCrWeb.common.isTextField(usernameInput) || + usernameInput.disabled) + continue; + var passwordInput = + findInputByFieldIdentifier_(inputs, formData.fields[1].name); + if (passwordInput == null || passwordInput.type != 'password' || + passwordInput.readOnly || passwordInput.disabled) + continue; - /** - * Returns the password form with the given |identifier| as a JSON string - * from the frame |win| and all its same-origin subframes. - * @param {Window} win The window in which to look for forms. - * @param {string} identifier The name of the form to extract. - * @return {HTMLFormElement} The password form. - */ - var getPasswordFormElement_ = function(win, identifier) { - var el = win.__gCrWeb.form.getFormElementFromIdentifier(identifier); - if (el) return el; - var frames = getSameOriginFrames_(win); - for (var i = 0; i < frames.length; ++i) { - el = getPasswordFormElement_(frames[i], identifier); - if (el) return el; - } - return null; - }; - - /** - * Returns an array of input elements in a form. - * @param {HTMLFormElement} form A form element for which the input elements - * are returned. - * @return {Array<HTMLInputElement>} - */ - var getFormInputElements_ = function(form) { - return __gCrWeb.form.getFormControlElements(form).filter(function( - element) { - return element.tagName === 'INPUT'; - }); - }; - - /** - * Returns the password form with the given |identifier| as a JSON string. - * @param {string} identifier The identifier of the form to extract. - * @return {string} The password form. - */ - __gCrWeb['getPasswordFormDataAsString'] = function(identifier) { - var el = getPasswordFormElement_(window, identifier); - if (!el) return '{}'; - var formData = __gCrWeb.getPasswordFormData(el); - if (!formData) return '{}'; - return __gCrWeb.stringify(formData); - }; - - /** - * Finds the form described by |formData| and fills in the - * username and password values. - * - * This is a public function invoked by Chrome. There is no information - * passed to this function that the page does not have access to anyway. - * - * @param {AutofillFormData} formData Form data. - * @param {string} username The username to fill. - * @param {string} password The password to fill. - * @param {string=} opt_normalizedOrigin The origin URL to compare to. - * @return {boolean} Whether a form field has been filled. - */ - __gCrWeb['fillPasswordForm'] = function( - formData, username, password, opt_normalizedOrigin) { - var normalizedOrigin = opt_normalizedOrigin || - __gCrWeb.common.removeQueryAndReferenceFromURL(window.location.href); - var origin = /** @type {string} */ (formData['origin']); - if (!__gCrWeb.common.isSameOrigin(origin, normalizedOrigin)) { - return false; - } - return fillPasswordFormWithData_( - formData, username, password, window, opt_normalizedOrigin); - }; - - /** - * Given a description of a form (origin, action and input fields), - * finds that form on the page and fills in the specified username - * and password. - * - * @param {AutofillFormData} formData Form data. - * @param {string} username The username to fill. - * @param {string} password The password to fill. - * @param {Window} win A window or a frame containing formData. - * @param {string=} opt_normalizedOrigin The origin URL to compare to. - * @return {boolean} Whether a form field has been filled. - */ - var fillPasswordFormWithData_ = function( - formData, username, password, win, opt_normalizedOrigin) { - var doc = win.document; - var forms = doc.forms; - var filled = false; - - for (var i = 0; i < forms.length; i++) { - var form = forms[i]; - var normalizedFormAction = opt_normalizedOrigin || - __gCrWeb.fill.getCanonicalActionForForm(form); - if (formData.action != normalizedFormAction) continue; - var inputs = getFormInputElements_(form); - var usernameInput = - findInputByFieldIdentifier_(inputs, formData.fields[0].name); - if (usernameInput == null || - !__gCrWeb.common.isTextField(usernameInput) || usernameInput.disabled) - continue; - var passwordInput = - findInputByFieldIdentifier_(inputs, formData.fields[1].name); - if (passwordInput == null || passwordInput.type != 'password' || - passwordInput.readOnly || passwordInput.disabled) - continue; - - // If username was provided on a read-only field and it matches the - // requested username, fill the form. - if (usernameInput.readOnly) { - if (usernameInput.value == username) { - passwordInput.value = password; - filled = true; - } - } else { - // Setting input fields via .value assignment does not trigger all - // the events that a web site can observe. This has the effect of - // certain web sites rejecting an autofilled sign in form as not - // signed in because the user didn't actually "typed" into the field. - // Adding the .focus() works around this problems. - usernameInput.focus(); - usernameInput.value = username; - passwordInput.focus(); + // If username was provided on a read-only field and it matches the + // requested username, fill the form. + if (usernameInput.readOnly) { + if (usernameInput.value == username) { passwordInput.value = password; filled = true; } + } else { + // Setting input fields via .value assignment does not trigger all + // the events that a web site can observe. This has the effect of + // certain web sites rejecting an autofilled sign in form as not + // signed in because the user didn't actually "typed" into the field. + // Adding the .focus() works around this problems. + usernameInput.focus(); + usernameInput.value = username; + passwordInput.focus(); + passwordInput.value = password; + filled = true; } + } - // Recursively invoke for all iframes. - var frames = getSameOriginFrames_(win); - for (var i = 0; i < frames.length; i++) { - if (fillPasswordFormWithData_( - formData, username, password, frames[i], opt_normalizedOrigin)) { - filled = true; - } + // Recursively invoke for all iframes. + var frames = getSameOriginFrames_(win); + for (var i = 0; i < frames.length; i++) { + if (fillPasswordFormWithData_( + formData, username, password, frames[i], opt_normalizedOrigin)) { + filled = true; } + } - return filled; - }; + return filled; +}; - /** - * Finds all forms with passwords in the supplied window or frame and appends - * JS objects containing the form data to |formDataList|. - * @param {!Array.<Object>} formDataList A list that this function populates - * with descriptions of discovered forms. - * @param {Window} win A window (or frame) in which the function should - * look for password forms. - */ - var getPasswordFormDataList_ = function(formDataList, win) { - var doc = win.document; - var forms = doc.forms; - for (var i = 0; i < forms.length; i++) { - var formData = __gCrWeb.getPasswordFormData(forms[i]); - if (formData) { - formDataList.push(formData); - addSubmitButtonTouchEndHandler_(forms[i]); - } +/** + * Finds all forms with passwords in the supplied window or frame and appends + * JS objects containing the form data to |formDataList|. + * @param {!Array.<Object>} formDataList A list that this function populates + * with descriptions of discovered forms. + * @param {Window} win A window (or frame) in which the function should + * look for password forms. + */ +var getPasswordFormDataList_ = function(formDataList, win) { + var doc = win.document; + var forms = doc.forms; + for (var i = 0; i < forms.length; i++) { + var formData = __gCrWeb.passwords.getPasswordFormData(forms[i]); + if (formData) { + formDataList.push(formData); + addSubmitButtonTouchEndHandler_(forms[i]); } + } - // Recursively invoke for all iframes. - var frames = getSameOriginFrames_(win); - for (var i = 0; i < frames.length; i++) { - getPasswordFormDataList_(formDataList, frames[i]); - } - }; + // Recursively invoke for all iframes. + var frames = getSameOriginFrames_(win); + for (var i = 0; i < frames.length; i++) { + getPasswordFormDataList_(formDataList, frames[i]); + } +}; - /** - * Returns a JS object containing the data from |formElement|. - * @param {HTMLFormElement} formElement An HTML Form element. - * @return {Object} Object of data from formElement. - */ - __gCrWeb.getPasswordFormData = function(formElement) { - var extractMask = __gCrWeb.fill.EXTRACT_MASK_VALUE; - var formData = {} - var ok = __gCrWeb.fill.webFormElementToFormData( - window, formElement, null /* formControlElement */, - extractMask, formData, null /* field */); - return ok ? formData : null; - }; -} +/** + * Returns a JS object containing the data from |formElement|. + * @param {HTMLFormElement} formElement An HTML Form element. + * @return {Object} Object of data from formElement. + */ +__gCrWeb.passwords.getPasswordFormData = function(formElement) { + var extractMask = __gCrWeb.fill.EXTRACT_MASK_VALUE; + var formData = {}; + var ok = __gCrWeb.fill.webFormElementToFormData( + window, formElement, null /* formControlElement */, extractMask, formData, + null /* field */); + return ok ? formData : null; +}; + +}()); // End of anonymous object
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 d5bd390..794b6d5 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
@@ -29,6 +29,7 @@ #include "ios/chrome/browser/services/gcm/ios_chrome_gcm_profile_service_factory.h" #include "ios/chrome/browser/sessions/ios_chrome_tab_restore_service_factory.h" #include "ios/chrome/browser/signin/about_signin_internals_factory.h" +#include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/signin/oauth2_token_service_factory.h" #include "ios/chrome/browser/signin/signin_client_factory.h" #include "ios/chrome/browser/signin/signin_manager_factory.h" @@ -105,6 +106,7 @@ DependsOn(ios::SigninManagerFactory::GetInstance()); DependsOn(ios::TemplateURLServiceFactory::GetInstance()); DependsOn(ios::WebDataServiceFactory::GetInstance()); + DependsOn(IdentityManagerFactory::GetInstance()); DependsOn(IOSChromeGCMProfileServiceFactory::GetInstance()); DependsOn(IOSChromePasswordStoreFactory::GetInstance()); DependsOn(IOSChromeProfileInvalidationProviderFactory::GetInstance()); @@ -121,11 +123,6 @@ ios::ChromeBrowserState* browser_state = ios::ChromeBrowserState::FromBrowserState(context); - SigninManagerBase* signin = - ios::SigninManagerFactory::GetForBrowserState(browser_state); - SigninClient* signin_client = - SigninClientFactory::GetForBrowserState(browser_state); - // Always create the GCMProfileService instance such that we can listen to // the profile notifications and purge the GCM store when the profile is // being signed out. @@ -136,9 +133,12 @@ ios::AboutSigninInternalsFactory::GetForBrowserState(browser_state); ProfileSyncService::InitParams init_params; - init_params.signin_wrapper = std::make_unique<SigninManagerWrapper>(signin); + init_params.signin_wrapper = std::make_unique<SigninManagerWrapper>( + IdentityManagerFactory::GetForBrowserState(browser_state), + ios::SigninManagerFactory::GetForBrowserState(browser_state)); init_params.signin_scoped_device_id_callback = base::BindRepeating( - &SigninClient::GetSigninScopedDeviceId, base::Unretained(signin_client)); + &SigninClient::GetSigninScopedDeviceId, + base::Unretained(SigninClientFactory::GetForBrowserState(browser_state))); init_params.oauth2_token_service = OAuth2TokenServiceFactory::GetForBrowserState(browser_state); init_params.start_behavior = ProfileSyncService::MANUAL_START;
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 c5373bd..02d9207 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
@@ -15,6 +15,7 @@ #include "components/signin/core/browser/signin_manager.h" #include "components/sync/driver/signin_manager_wrapper.h" #include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/signin/oauth2_token_service_factory.h" #include "ios/chrome/browser/signin/signin_manager_factory.h" #include "ios/chrome/browser/sync/ios_chrome_sync_client.h" @@ -27,6 +28,7 @@ browser_sync::ProfileSyncService::InitParams init_params; init_params.signin_wrapper = std::make_unique<SigninManagerWrapper>( + IdentityManagerFactory::GetForBrowserState(browser_state), ios::SigninManagerFactory::GetForBrowserState(browser_state)); init_params.signin_scoped_device_id_callback = base::BindRepeating([]() { return std::string(); });
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm index 04902648..15c38bd 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils_unittest.mm
@@ -20,6 +20,21 @@ class ContentSuggestionsCollectionUtilsTest : public PlatformTest { public: void SetAsIPad() { + UITraitCollection* horizontalRegular = [UITraitCollection + traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular]; + UITraitCollection* verticalRegular = [UITraitCollection + traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassRegular]; + customTraitCollection_ = + [UITraitCollection traitCollectionWithTraitsFromCollections:@[ + verticalRegular, horizontalRegular + ]]; + + trait_swizzler_ = std::make_unique<ScopedBlockSwizzler>( + [UIWindow class], @selector(traitCollection), + ^UITraitCollection*(id self) { + return customTraitCollection_; + }); + device_type_swizzler_ = std::make_unique<ScopedBlockSwizzler>( [UIDevice class], @selector(userInterfaceIdiom), ^UIUserInterfaceIdiom(id self) { @@ -27,6 +42,21 @@ }); } void SetAsIPhone() { + UITraitCollection* horizontalCompact = [UITraitCollection + traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact]; + UITraitCollection* verticalCompact = [UITraitCollection + traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact]; + customTraitCollection_ = + [UITraitCollection traitCollectionWithTraitsFromCollections:@[ + verticalCompact, horizontalCompact + ]]; + + trait_swizzler_ = std::make_unique<ScopedBlockSwizzler>( + [UIWindow class], @selector(traitCollection), + ^UITraitCollection*(id self) { + return customTraitCollection_; + }); + device_type_swizzler_ = std::make_unique<ScopedBlockSwizzler>( [UIDevice class], @selector(userInterfaceIdiom), ^UIUserInterfaceIdiom(id self) { @@ -49,6 +79,8 @@ } private: + UITraitCollection* customTraitCollection_; + std::unique_ptr<ScopedBlockSwizzler> trait_swizzler_; std::unique_ptr<ScopedBlockSwizzler> device_type_swizzler_; std::unique_ptr<ScopedBlockSwizzler> orientation_swizzler_; }; @@ -57,22 +89,26 @@ // Setup. SetAsIPhone(); - // Action. - CGFloat result = centeredTilesMarginForWidth(374); - - // Tests. - EXPECT_EQ(17, result); + if (IsUIRefreshPhase1Enabled()) { + CGFloat result = centeredTilesMarginForWidth(375); + EXPECT_EQ(28, result); + } else { + CGFloat result = centeredTilesMarginForWidth(374); + EXPECT_EQ(17, result); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, centeredTilesMarginIPad) { // Setup. SetAsIPad(); - // Action. - CGFloat result = centeredTilesMarginForWidth(700); - - // Tests. - EXPECT_EQ(168, result); + if (IsUIRefreshPhase1Enabled()) { + CGFloat result = centeredTilesMarginForWidth(767); + EXPECT_EQ(209, result); + } else { + CGFloat result = centeredTilesMarginForWidth(700); + EXPECT_EQ(168, result); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, doodleFrameIPad) { @@ -86,8 +122,8 @@ // Test. if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(68, height); - EXPECT_EQ(48, topMargin); + EXPECT_EQ(120, height); + EXPECT_EQ(162, topMargin); } else { EXPECT_EQ(120, height); EXPECT_EQ(82, topMargin); @@ -108,7 +144,7 @@ // Test. if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(68, heightLogo); + EXPECT_EQ(120, heightLogo); EXPECT_EQ(60, heightNoLogo); EXPECT_EQ(48, topMargin); } else { @@ -132,7 +168,7 @@ // Test. if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(68, heightLogo); + EXPECT_EQ(120, heightLogo); EXPECT_EQ(60, heightNoLogo); EXPECT_EQ(48, topMargin); } else { @@ -158,8 +194,8 @@ // Test. if (IsUIRefreshPhase1Enabled()) { EXPECT_EQ(32, topMargin); - EXPECT_EQ(343, resultWidth); - EXPECT_EQ(343, resultWidthLargeIPad); + EXPECT_EQ(432, resultWidth); + EXPECT_EQ(432, resultWidthLargeIPad); } else { EXPECT_EQ(82, topMargin); EXPECT_EQ(width - 2 * margin, resultWidth); @@ -215,10 +251,10 @@ // Action, tests. if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(214, heightForLogoHeader(YES, YES, YES)); - EXPECT_EQ(238, heightForLogoHeader(YES, NO, YES)); - EXPECT_EQ(214, heightForLogoHeader(YES, YES, NO)); - EXPECT_EQ(238, heightForLogoHeader(YES, NO, NO)); + EXPECT_EQ(380, heightForLogoHeader(YES, YES, YES)); + EXPECT_EQ(404, heightForLogoHeader(YES, NO, YES)); + EXPECT_EQ(380, heightForLogoHeader(YES, YES, NO)); + EXPECT_EQ(404, heightForLogoHeader(YES, NO, NO)); } else { EXPECT_EQ(350, heightForLogoHeader(YES, YES, YES)); EXPECT_EQ(374, heightForLogoHeader(YES, NO, YES)); @@ -233,10 +269,10 @@ // Action, tests. if (IsUIRefreshPhase1Enabled()) { - EXPECT_EQ(214, heightForLogoHeader(YES, YES, YES)); - EXPECT_EQ(214, heightForLogoHeader(YES, NO, YES)); - EXPECT_EQ(214, heightForLogoHeader(YES, YES, NO)); - EXPECT_EQ(214, heightForLogoHeader(YES, NO, NO)); + EXPECT_EQ(266, heightForLogoHeader(YES, YES, YES)); + EXPECT_EQ(266, heightForLogoHeader(YES, NO, YES)); + EXPECT_EQ(266, heightForLogoHeader(YES, YES, NO)); + EXPECT_EQ(266, heightForLogoHeader(YES, NO, NO)); } else { EXPECT_EQ(274, heightForLogoHeader(YES, YES, YES)); EXPECT_EQ(274, heightForLogoHeader(YES, NO, YES));
diff --git a/ios/chrome/browser/ui/download/download_manager_view_controller.mm b/ios/chrome/browser/ui/download/download_manager_view_controller.mm index cccedfd..beda02c 100644 --- a/ios/chrome/browser/ui/download/download_manager_view_controller.mm +++ b/ios/chrome/browser/ui/download/download_manager_view_controller.mm
@@ -633,8 +633,8 @@ : self.actionButton; self.statusLabelTrailingConstraint = [self.statusLabel.trailingAnchor - constraintEqualToAnchor:secondAnchorElement.leadingAnchor - constant:-kElementMargin]; + constraintLessThanOrEqualToAnchor:secondAnchorElement.leadingAnchor + constant:-kElementMargin]; self.statusLabelTrailingConstraint.active = YES; }
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.mm b/ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.mm index 15ef410c..fc63817 100644 --- a/ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.mm +++ b/ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.mm
@@ -8,7 +8,6 @@ #include <memory> #include "base/logging.h" -#include "base/metrics/field_trial.h" #include "base/strings/utf_string_conversions.h" #include "components/sync/driver/sync_service.h" #include "components/sync_sessions/open_tabs_ui_delegate.h" @@ -95,23 +94,11 @@ modified_time = synced_session->modified_time; device_type = synced_session->device_type; - const std::string group_name = - base::FieldTrialList::FindFullName("TabSyncByRecency"); - if (group_name == "Enabled") { - // Order tabs by recency. - std::vector<const sessions::SessionTab*> session_tabs; - open_tabs->GetForeignSessionTabs(synced_session->session_tag, - &session_tabs); - for (const auto* session_tab : session_tabs) { + // Order tabs by their visual position within window. + for (const auto& kv : synced_session->windows) { + for (const auto& session_tab : kv.second->wrapped_window.tabs) { AddTabToDistantSession(*session_tab, synced_session->session_tag, this); } - } else { - // Order tabs by their visual position within window. - for (const auto& kv : synced_session->windows) { - for (const auto& session_tab : kv.second->wrapped_window.tabs) { - AddTabToDistantSession(*session_tab, synced_session->session_tag, this); - } - } } }
diff --git a/ios/chrome/browser/ui/popup_menu/BUILD.gn b/ios/chrome/browser/ui/popup_menu/BUILD.gn index 003b8271..4a14b4c 100644 --- a/ios/chrome/browser/ui/popup_menu/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/BUILD.gn
@@ -65,7 +65,6 @@ "resources:popup_menu_request_desktop_site", "resources:popup_menu_request_mobile_site", "resources:popup_menu_settings", - "resources:popup_menu_shadow", "resources:popup_menu_site_information", "resources:popup_menu_stop", "//base", @@ -75,6 +74,7 @@ "//ios/chrome/browser/ui/image_util", "//ios/chrome/browser/ui/popup_menu/cells", "//ios/chrome/browser/ui/presenters", + "//ios/chrome/browser/ui/resources:menu_shadow", "//ios/chrome/browser/ui/table_view", "//ios/chrome/browser/ui/table_view:styler", "//ios/chrome/browser/ui/util",
diff --git a/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn b/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn index 76200de..9aeb4a3 100644 --- a/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/cells/BUILD.gn
@@ -15,6 +15,7 @@ ] deps = [ "//base", + "//ios/chrome/browser/ui", "//ios/chrome/browser/ui/reading_list:reading_list_ui", "//ios/chrome/browser/ui/table_view:styler", "//ios/chrome/browser/ui/table_view/cells",
diff --git a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm b/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm index 27ed98a..220bb3c 100644 --- a/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm +++ b/ios/chrome/browser/ui/popup_menu/cells/popup_menu_tools_item.mm
@@ -10,6 +10,7 @@ #import "ios/chrome/browser/ui/reading_list/number_badge_view.h" #import "ios/chrome/browser/ui/reading_list/text_badge_view.h" #import "ios/chrome/browser/ui/table_view/chrome_table_view_styler.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/util/constraints_ui_util.h" #import "ios/chrome/common/material_timing.h" @@ -18,13 +19,14 @@ #endif namespace { +const int kEnabledColor = 0x1A73E8; const CGFloat kImageLength = 28; const CGFloat kCellHeight = 44; const CGFloat kInnerMargin = 11; const CGFloat kMargin = 15; const CGFloat kTopMargin = 8; const CGFloat kTopMarginBadge = 14; -} +} // namespace @implementation PopupMenuToolsItem @@ -236,8 +238,8 @@ - (void)setUserInteractionEnabled:(BOOL)userInteractionEnabled { [super setUserInteractionEnabled:userInteractionEnabled]; if (userInteractionEnabled) { - self.titleLabel.textColor = self.tintColor; - self.imageView.tintColor = self.tintColor; + self.titleLabel.textColor = UIColorFromRGB(kEnabledColor); + self.imageView.tintColor = UIColorFromRGB(kEnabledColor); } else { self.titleLabel.textColor = [[self class] disabledColor]; self.imageView.tintColor = [[self class] disabledColor];
diff --git a/ios/chrome/browser/ui/popup_menu/popup_menu_view_controller.mm b/ios/chrome/browser/ui/popup_menu/popup_menu_view_controller.mm index d6b28f9e8..f36ff1e 100644 --- a/ios/chrome/browser/ui/popup_menu/popup_menu_view_controller.mm +++ b/ios/chrome/browser/ui/popup_menu/popup_menu_view_controller.mm
@@ -60,8 +60,8 @@ _contentContainer.backgroundColor = [UIColor colorWithWhite:kBackgroundGreyScale alpha:1]; - UIImageView* shadow = [[UIImageView alloc] - initWithImage:StretchableImageNamed(@"popup_menu_shadow")]; + UIImageView* shadow = + [[UIImageView alloc] initWithImage:StretchableImageNamed(@"menu_shadow")]; [_contentContainer addSubview:shadow]; shadow.translatesAutoresizingMaskIntoConstraints = NO; AddSameConstraintsToSidesWithInsets(
diff --git a/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn b/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn index 36375a6f..a93df83 100644 --- a/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn +++ b/ios/chrome/browser/ui/popup_menu/resources/BUILD.gn
@@ -58,15 +58,6 @@ ] } -imageset("popup_menu_shadow") { - sources = [ - "popup_menu_shadow.imageset/Contents.json", - "popup_menu_shadow.imageset/popup_menu_shadow.png", - "popup_menu_shadow.imageset/popup_menu_shadow@2x.png", - "popup_menu_shadow.imageset/popup_menu_shadow@3x.png", - ] -} - imageset("popup_menu_new_incognito_tab") { sources = [ "popup_menu_new_incognito_tab.imageset/Contents.json",
diff --git a/ios/chrome/browser/ui/resources/BUILD.gn b/ios/chrome/browser/ui/resources/BUILD.gn index 8e14b77..408fe06 100644 --- a/ios/chrome/browser/ui/resources/BUILD.gn +++ b/ios/chrome/browser/ui/resources/BUILD.gn
@@ -61,3 +61,12 @@ "keyboard_button.imageset/keyboard_button~ipad.png", ] } + +imageset("menu_shadow") { + sources = [ + "menu_shadow.imageset/Contents.json", + "menu_shadow.imageset/menu_shadow.png", + "menu_shadow.imageset/menu_shadow@2x.png", + "menu_shadow.imageset/menu_shadow@3x.png", + ] +}
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_shadow.imageset/Contents.json b/ios/chrome/browser/ui/resources/menu_shadow.imageset/Contents.json similarity index 69% rename from ios/chrome/browser/ui/popup_menu/resources/popup_menu_shadow.imageset/Contents.json rename to ios/chrome/browser/ui/resources/menu_shadow.imageset/Contents.json index 2f7a347..c07c84b 100644 --- a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_shadow.imageset/Contents.json +++ b/ios/chrome/browser/ui/resources/menu_shadow.imageset/Contents.json
@@ -3,17 +3,17 @@ { "idiom": "universal", "scale": "1x", - "filename": "popup_menu_shadow.png" + "filename": "menu_shadow.png" }, { "idiom": "universal", "scale": "2x", - "filename": "popup_menu_shadow@2x.png" + "filename": "menu_shadow@2x.png" }, { "idiom": "universal", "scale": "3x", - "filename": "popup_menu_shadow@3x.png" + "filename": "menu_shadow@3x.png" } ], "info": {
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_shadow.imageset/popup_menu_shadow.png b/ios/chrome/browser/ui/resources/menu_shadow.imageset/menu_shadow.png similarity index 100% rename from ios/chrome/browser/ui/popup_menu/resources/popup_menu_shadow.imageset/popup_menu_shadow.png rename to ios/chrome/browser/ui/resources/menu_shadow.imageset/menu_shadow.png Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_shadow.imageset/popup_menu_shadow@2x.png b/ios/chrome/browser/ui/resources/menu_shadow.imageset/menu_shadow@2x.png similarity index 100% rename from ios/chrome/browser/ui/popup_menu/resources/popup_menu_shadow.imageset/popup_menu_shadow@2x.png rename to ios/chrome/browser/ui/resources/menu_shadow.imageset/menu_shadow@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/popup_menu/resources/popup_menu_shadow.imageset/popup_menu_shadow@3x.png b/ios/chrome/browser/ui/resources/menu_shadow.imageset/menu_shadow@3x.png similarity index 100% rename from ios/chrome/browser/ui/popup_menu/resources/popup_menu_shadow.imageset/popup_menu_shadow@3x.png rename to ios/chrome/browser/ui/resources/menu_shadow.imageset/menu_shadow@3x.png Binary files differ
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm index 7ca9748..d6e3b78 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.mm
@@ -29,6 +29,14 @@ TabGridConfigurationBottomToolbar = 1, TabGridConfigurationFloatingButton, }; + +// Computes the page from the offset and width of |scrollView|. +TabGridPage GetPageFromScrollView(UIScrollView* scrollView) { + // TODO(crbug.com/822328) : Fix for RTL. + CGFloat pageWidth = scrollView.frame.size.width; + float fractionalPage = scrollView.contentOffset.x / pageWidth; + return static_cast<TabGridPage>(lround(fractionalPage)); +} } // namespace @interface TabGridViewController ()<GridViewControllerDelegate, @@ -169,19 +177,20 @@ self.scrollView.contentSize.width - self.scrollView.frame.size.width; CGFloat offset = scrollView.contentOffset.x / offsetWidth; self.topToolbar.pageControl.sliderPosition = offset; - } - // Bookkeeping for the current page. - // TODO(crbug.com/822328) : Fix for RTL. - CGFloat pageWidth = scrollView.frame.size.width; - float fractionalPage = scrollView.contentOffset.x / pageWidth; - NSUInteger page = lround(fractionalPage); - if (page != self.currentPage) { - _currentPage = static_cast<TabGridPage>(page); - [self configureButtonsForOriginalAndCurrentPage]; + TabGridPage page = GetPageFromScrollView(scrollView); + if (page != _currentPage) { + _currentPage = page; + [self configureButtonsForOriginalAndCurrentPage]; + } } } +- (void)scrollViewDidEndScrollingAnimation:(UIScrollView*)scrollView { + _currentPage = GetPageFromScrollView(scrollView); + [self configureButtonsForOriginalAndCurrentPage]; +} + #pragma mark - UIScrollViewAccessibilityDelegate - (NSString*)accessibilityScrollStatusForScrollView:(UIScrollView*)scrollView { @@ -280,7 +289,7 @@ _currentPage = currentPage; } else { [self.scrollView setContentOffset:offset animated:YES]; - // _currentPage is set in scrollViewDidScroll: + // _currentPage is set in scrollViewDidEndScrollingAnimation: } }
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn index cb2d34ea..12ff25a 100644 --- a/ios/chrome/browser/web/BUILD.gn +++ b/ios/chrome/browser/web/BUILD.gn
@@ -121,6 +121,7 @@ sources = [ "//components/autofill/ios/browser/resources/autofill_controller.js", "//components/autofill/ios/fill/resources/fill.js", + "//ios/chrome/browser/passwords/resources/password_controller.js", "resources/chrome_bundle_main_frame.js", "resources/print.js", ]
diff --git a/ios/chrome/browser/web/resources/chrome_bundle_main_frame.js b/ios/chrome/browser/web/resources/chrome_bundle_main_frame.js index e5a9caf..23cee10 100644 --- a/ios/chrome/browser/web/resources/chrome_bundle_main_frame.js +++ b/ios/chrome/browser/web/resources/chrome_bundle_main_frame.js
@@ -7,4 +7,5 @@ goog.require('__crWeb.autofill'); goog.require('__crWeb.fill'); +goog.require('__crWeb.passwords'); goog.require('__crWeb.print');
diff --git a/ios/web/web_state/ui/crw_context_menu_controller.mm b/ios/web/web_state/ui/crw_context_menu_controller.mm index 893e5ba99..f565051c 100644 --- a/ios/web/web_state/ui/crw_context_menu_controller.mm +++ b/ios/web/web_state/ui/crw_context_menu_controller.mm
@@ -388,7 +388,10 @@ - (void)cancelContextMenuDisplay { _contextMenuNeedsDisplay = NO; - [_pendingElementFetchRequests removeAllObjects]; + for (HTMLElementFetchRequest* fetchRequest in _pendingElementFetchRequests + .allValues) { + [fetchRequest invalidate]; + } } #pragma mark -
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 6493b5e..00d73c17 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -2012,7 +2012,11 @@ // nothing if the document has already loaded. if (_loadPhase == web::PAGE_LOADED) return; - [self loadCompleteWithSuccess:YES forNavigation:navigation]; + + web::NavigationContextImpl* context = + [_navigationStates contextForNavigation:navigation]; + BOOL success = !context || !context->GetError(); + [self loadCompleteWithSuccess:success forNavigation:navigation]; } - (void)loadCompleteWithSuccess:(BOOL)loadSuccess @@ -4697,7 +4701,7 @@ // of session restoration. It is now safe to update the navigation // item URL to the original app-specific URL. item->SetURL(originalURL); - } else if (item->GetURL() != originalURL) { + } else if (item->GetVirtualURL() != originalURL) { // The |didFinishNavigation| callback can arrive after another // navigation has started. Abort in this case. return; @@ -4731,29 +4735,34 @@ } } - // Handle state transitions for retrying a previously failed navigation. - switch (errorRetryState) { - case web::ErrorRetryState::kDisplayingErrorForFailedNavigation: - DCHECK(context->GetPageTransition() & ui::PAGE_TRANSITION_FORWARD_BACK); - if (item->GetURL() == webViewURL) { - // Shortcut: if WebView already has the original URL (can happen when - // WebKit renders page from cache after after repeated back/forward - // navigations), skip kNavigatingToFailedNavigationItem state and just - // reload the page. + // Handle state transitions for retrying a previously failed navigation to a + // web URL. App-specific URLs should never fail to load so should not change + // the error retry state. + if (!web::GetWebClient()->IsAppSpecificURL(item->GetURL())) { + switch (errorRetryState) { + case web::ErrorRetryState::kDisplayingErrorForFailedNavigation: + DCHECK(context->GetPageTransition() & + ui::PAGE_TRANSITION_FORWARD_BACK); + if (item->GetURL() == webViewURL) { + // Shortcut: if WebView already has the original URL (can happen + // when WebKit renders page from cache after after repeated + // back/forward navigations), skip kNavigatingToFailedNavigationItem + // state and just reload the page. + [self handleRetryFailedNavigationItem:item]; + } else { + [self handleNavigationToFailedNavigationItem:item]; + } + break; + case web::ErrorRetryState::kNavigatingToFailedNavigationItem: [self handleRetryFailedNavigationItem:item]; - } else { - [self handleNavigationToFailedNavigationItem:item]; - } - break; - case web::ErrorRetryState::kNavigatingToFailedNavigationItem: - [self handleRetryFailedNavigationItem:item]; - break; - case web::ErrorRetryState::kRetryFailedNavigationItem: - item->SetErrorRetryState(web::ErrorRetryState::kNoNavigationError); - break; - case web::ErrorRetryState::kNoNavigationError: - case web::ErrorRetryState::kReadyToDisplayErrorForFailedNavigation: - break; + break; + case web::ErrorRetryState::kRetryFailedNavigationItem: + item->SetErrorRetryState(web::ErrorRetryState::kNoNavigationError); + break; + case web::ErrorRetryState::kNoNavigationError: + case web::ErrorRetryState::kReadyToDisplayErrorForFailedNavigation: + break; + } } }
diff --git a/ios/web/web_state/ui/html_element_fetch_request.h b/ios/web/web_state/ui/html_element_fetch_request.h index 4571948..9aa02d35 100644 --- a/ios/web/web_state/ui/html_element_fetch_request.h +++ b/ios/web/web_state/ui/html_element_fetch_request.h
@@ -24,8 +24,12 @@ (void (^)(NSDictionary*))foundElementHandler NS_DESIGNATED_INITIALIZER; // Calls the |foundElementHandler| from the receiver's initializer with -// |response| as the parameter. +// |response| as the parameter. This method has no effect if |invalidate| has +// been called. - (void)runHandlerWithResponse:(NSDictionary*)response; +// Removes the stored |foundElementHandler| from the receiver's initializer. +// |runHandlerWithResponse:| will have no effect if called after |invalidate|. +- (void)invalidate; @end
diff --git a/ios/web/web_state/ui/html_element_fetch_request.mm b/ios/web/web_state/ui/html_element_fetch_request.mm index 89861e70..0835371 100644 --- a/ios/web/web_state/ui/html_element_fetch_request.mm +++ b/ios/web/web_state/ui/html_element_fetch_request.mm
@@ -31,7 +31,13 @@ } - (void)runHandlerWithResponse:(NSDictionary*)response { - _foundElementHandler(response); + if (_foundElementHandler) { + _foundElementHandler(response); + } +} + +- (void)invalidate { + _foundElementHandler = nullptr; } @end
diff --git a/ios/web/web_state/ui/html_element_fetch_request_unittest.mm b/ios/web/web_state/ui/html_element_fetch_request_unittest.mm index bfd5731a..58b4b563 100644 --- a/ios/web/web_state/ui/html_element_fetch_request_unittest.mm +++ b/ios/web/web_state/ui/html_element_fetch_request_unittest.mm
@@ -45,4 +45,18 @@ EXPECT_NSEQ(response, received_response); } +// Tests that |runHandlerWithResponse:| does not run the handler from the +// object's initializer if |invalidate| has been called. +TEST_F(HtmlElementFetchRequestTest, Invalidate) { + __block bool handler_called = false; + void (^handler)(NSDictionary*) = ^(NSDictionary* response) { + handler_called = true; + }; + HTMLElementFetchRequest* request = + [[HTMLElementFetchRequest alloc] initWithFoundElementHandler:handler]; + [request invalidate]; + [request runHandlerWithResponse:nil]; + EXPECT_FALSE(handler_called); +} + } // namespace web
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn index 57d006f..900e3c0 100644 --- a/ios/web_view/BUILD.gn +++ b/ios/web_view/BUILD.gn
@@ -313,6 +313,7 @@ "//components/autofill/ios/browser/resources/autofill_controller.js", "//components/autofill/ios/fill/resources/fill.js", "//components/autofill/ios/fill/resources/form.js", + "//ios/chrome/browser/passwords/resources/password_controller.js", "resources/web_view_bundle.js", ] }
diff --git a/ios/web_view/resources/web_view_bundle.js b/ios/web_view/resources/web_view_bundle.js index 0eec4949..acb4dac 100644 --- a/ios/web_view/resources/web_view_bundle.js +++ b/ios/web_view/resources/web_view_bundle.js
@@ -8,3 +8,4 @@ goog.require('__crWeb.autofill'); goog.require('__crWeb.fill'); goog.require('__crWeb.form'); +goog.require('__crWeb.passwords');
diff --git a/ios/web_view/tools/build.py b/ios/web_view/tools/build.py index c6511ff..c4aa03a 100755 --- a/ios/web_view/tools/build.py +++ b/ios/web_view/tools/build.py
@@ -19,7 +19,7 @@ build_config: A string describing the build configuration. Ex: 'Debug' target_device: A string describing the target device. Ex: 'simulator' """ - return '%s-iphone%s' % (build_config, target_device) + return '%s-%s' % (build_config, target_device) def build(build_config, target_device, extra_gn_options, extra_ninja_options): """Generates and builds ChromeWebView.framework. @@ -36,7 +36,7 @@ The return code of generating ninja if it is non-zero, else the return code of the ninja build command. """ - if target_device == 'os': + if target_device == 'iphoneos': target_cpu = 'arm' additional_cpu = 'arm64' else: @@ -133,7 +133,7 @@ return 0 def package_all_frameworks(out_dir, output_name, extra_gn_options, - extra_ninja_options): + build_configs, target_devices, extra_ninja_options): """Builds ChromeWebView.framework. Builds Release and Debug versions of ChromeWebView.framework for both @@ -143,6 +143,8 @@ out_dir: A string to the path which all build products will be copied. extra_gn_options: A string of gn args (space separated key=value items) to be appended to the gn gen command. + build_configs: A list of configs to build. + target_devices: A list of devices to target. extra_ninja_options: A string of gn options to be appended to the ninja command. @@ -154,11 +156,8 @@ # Package all builds in the output directory os.makedirs(out_dir) - configurations = [('Debug', 'simulator'), - ('Debug', 'os'), - ('Release', 'simulator'), - ('Release', 'os')] - for build_config, target_device in configurations: + configs_and_devices = [(a,b) for a in build_configs for b in target_devices] + for build_config, target_device in configs_and_devices: if package_framework(build_config, target_device, out_dir, @@ -192,6 +191,14 @@ help='Combines Cronet and ChromeWebView as 1 framework.') parser.add_argument('--enable_sync', action='store_true', help='Enables public API for ChromeSync.') + build_configs = ['Debug', 'Release'] + target_devices = ['iphonesimulator', 'iphoneos'] + parser.add_argument('--build_configs', nargs='+', default=build_configs, + choices=build_configs, + help='Specify which configs to build.') + parser.add_argument('--target_devices', nargs='+', default=target_devices, + choices=target_devices, + help='Specify which devices to target.') options, extra_options = parser.parse_known_args() print 'Options:', options @@ -222,6 +229,8 @@ extra_gn_options += 'ios_web_view_output_name="%s" ' % output_name return package_all_frameworks(out_dir, output_name, extra_gn_options, + set(options.build_configs), + set(options.target_devices), options.ninja_args) if __name__ == '__main__':
diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc index acc04df..0e47699 100644 --- a/media/filters/vpx_video_decoder.cc +++ b/media/filters/vpx_video_decoder.cc
@@ -374,7 +374,7 @@ ->metadata() ->SetInteger(VideoFrameMetadata::COLOR_SPACE, color_space); - if (config_.color_space_info() != VideoColorSpace()) { + if (config_.color_space_info().IsSpecified()) { // config_.color_space_info() comes from the color tag which is // more expressive than the bitstream, so prefer it over the // bitstream data below.
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc index b716573bb..3e288d1e 100644 --- a/media/gpu/vaapi/vaapi_wrapper.cc +++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -746,19 +746,25 @@ } // And create a context associated with them. - va_res = vaCreateContext(va_display_, va_config_id_, size.width(), - size.height(), VA_PROGRESSIVE, &va_surface_ids_[0], - va_surface_ids_.size(), &va_context_id_); + const bool success = CreateContext(va_format, size, va_surface_ids_); + if (success) + *va_surfaces = va_surface_ids_; + else + DestroySurfaces_Locked(); + return success; +} + +bool VaapiWrapper::CreateContext(unsigned int va_format, + const gfx::Size& size, + const std::vector<VASurfaceID>& va_surfaces) { + VAStatus va_res = vaCreateContext( + va_display_, va_config_id_, size.width(), size.height(), VA_PROGRESSIVE, + &va_surface_ids_[0], va_surface_ids_.size(), &va_context_id_); VA_LOG_ON_ERROR(va_res, "vaCreateContext failed"); - if (va_res != VA_STATUS_SUCCESS) { - DestroySurfaces_Locked(); - return false; - } - - *va_surfaces = va_surface_ids_; - va_surface_format_ = va_format; - return true; + if (va_res == VA_STATUS_SUCCESS) + va_surface_format_ = va_format; + return va_res == VA_STATUS_SUCCESS; } void VaapiWrapper::DestroySurfaces() {
diff --git a/media/gpu/vaapi/vaapi_wrapper.h b/media/gpu/vaapi/vaapi_wrapper.h index f019e7a..f77ced99 100644 --- a/media/gpu/vaapi/vaapi_wrapper.h +++ b/media/gpu/vaapi/vaapi_wrapper.h
@@ -89,7 +89,7 @@ // Return true when JPEG encode is supported. static bool IsJpegEncodeSupported(); - // Create |num_surfaces| backing surfaces in driver for VASurfaces of + // Creates |num_surfaces| backing surfaces in driver for VASurfaces of // |va_format|, each of size |size|. Returns true when successful, with the // created IDs in |va_surfaces| to be managed and later wrapped in // VASurfaces. @@ -102,7 +102,12 @@ size_t num_surfaces, std::vector<VASurfaceID>* va_surfaces); - // Free all memory allocated in CreateSurfaces. + // Creates a VA Context associated with the set of |va_surfaces| of |size|. + bool CreateContext(unsigned int va_format, + const gfx::Size& size, + const std::vector<VASurfaceID>& va_surfaces); + + // Frees all memory allocated in CreateSurfaces. virtual void DestroySurfaces(); // Create a VASurface for |pixmap|. The ownership of the surface is
diff --git a/media/renderers/paint_canvas_video_renderer.cc b/media/renderers/paint_canvas_video_renderer.cc index 24f11c2..dd599ca 100644 --- a/media/renderers/paint_canvas_video_renderer.cc +++ b/media/renderers/paint_canvas_video_renderer.cc
@@ -63,13 +63,6 @@ // We delete the temporary resource if it is not used for 3 seconds. const int kTemporaryResourceDeletionDelay = 3; // Seconds; -bool CheckColorSpace(const VideoFrame* video_frame, ColorSpace color_space) { - int result; - return video_frame->metadata()->GetInteger(VideoFrameMetadata::COLOR_SPACE, - &result) && - result == color_space; -} - class SyncTokenClientImpl : public VideoFrame::SyncTokenClient { public: explicit SyncTokenClientImpl(gpu::gles2::GLES2Interface* gl) : gl_(gl) {} @@ -153,11 +146,10 @@ GrMipMapped::kNo, source_textures[2]), }; + // TODO(hubbe): This should really default to rec709. + // https://crbug.com/828599 SkYUVColorSpace color_space = kRec601_SkYUVColorSpace; - if (CheckColorSpace(video_frame, media::COLOR_SPACE_JPEG)) - color_space = kJPEG_SkYUVColorSpace; - else if (CheckColorSpace(video_frame, media::COLOR_SPACE_HD_REC709)) - color_space = kRec709_SkYUVColorSpace; + video_frame->ColorSpace().ToSkYUVColorSpace(&color_space); sk_sp<SkImage> img; if (video_frame->format() == PIXEL_FORMAT_NV12) { @@ -268,12 +260,11 @@ } if (color_space) { - if (CheckColorSpace(frame_.get(), COLOR_SPACE_JPEG)) - *color_space = kJPEG_SkYUVColorSpace; - else if (CheckColorSpace(frame_.get(), COLOR_SPACE_HD_REC709)) - *color_space = kRec709_SkYUVColorSpace; - else + if (!frame_->ColorSpace().ToSkYUVColorSpace(color_space)) { + // TODO(hubbe): This really should default to rec709 + // https://crbug.com/828599 *color_space = kRec601_SkYUVColorSpace; + } } for (int plane = VideoFrame::kYPlane; plane <= VideoFrame::kVPlane; @@ -514,6 +505,7 @@ format, video_frame->coded_size(), video_frame->visible_rect(), video_frame->natural_size(), video_frame->timestamp()); + ret->set_color_space(video_frame->ColorSpace()); // Copy all metadata. // (May be enough to copy color space) ret->metadata()->MergeMetadataFrom(video_frame->metadata()); @@ -672,39 +664,48 @@ return; } + // TODO(hubbe): This should really default to the rec709 colorspace. + // https://crbug.com/828599 + SkYUVColorSpace color_space = kRec601_SkYUVColorSpace; + video_frame->ColorSpace().ToSkYUVColorSpace(&color_space); + switch (video_frame->format()) { case PIXEL_FORMAT_YV12: case PIXEL_FORMAT_I420: - if (CheckColorSpace(video_frame, COLOR_SPACE_JPEG)) { - LIBYUV_J420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), - video_frame->stride(VideoFrame::kYPlane), - video_frame->visible_data(VideoFrame::kUPlane), - video_frame->stride(VideoFrame::kUPlane), - video_frame->visible_data(VideoFrame::kVPlane), - video_frame->stride(VideoFrame::kVPlane), - static_cast<uint8_t*>(rgb_pixels), row_bytes, - video_frame->visible_rect().width(), - video_frame->visible_rect().height()); - } else if (CheckColorSpace(video_frame, COLOR_SPACE_HD_REC709)) { - LIBYUV_H420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), - video_frame->stride(VideoFrame::kYPlane), - video_frame->visible_data(VideoFrame::kUPlane), - video_frame->stride(VideoFrame::kUPlane), - video_frame->visible_data(VideoFrame::kVPlane), - video_frame->stride(VideoFrame::kVPlane), - static_cast<uint8_t*>(rgb_pixels), row_bytes, - video_frame->visible_rect().width(), - video_frame->visible_rect().height()); - } else { - LIBYUV_I420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), - video_frame->stride(VideoFrame::kYPlane), - video_frame->visible_data(VideoFrame::kUPlane), - video_frame->stride(VideoFrame::kUPlane), - video_frame->visible_data(VideoFrame::kVPlane), - video_frame->stride(VideoFrame::kVPlane), - static_cast<uint8_t*>(rgb_pixels), row_bytes, - video_frame->visible_rect().width(), - video_frame->visible_rect().height()); + switch (color_space) { + case kJPEG_SkYUVColorSpace: + LIBYUV_J420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), + video_frame->stride(VideoFrame::kYPlane), + video_frame->visible_data(VideoFrame::kUPlane), + video_frame->stride(VideoFrame::kUPlane), + video_frame->visible_data(VideoFrame::kVPlane), + video_frame->stride(VideoFrame::kVPlane), + static_cast<uint8_t*>(rgb_pixels), row_bytes, + video_frame->visible_rect().width(), + video_frame->visible_rect().height()); + break; + case kRec709_SkYUVColorSpace: + LIBYUV_H420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), + video_frame->stride(VideoFrame::kYPlane), + video_frame->visible_data(VideoFrame::kUPlane), + video_frame->stride(VideoFrame::kUPlane), + video_frame->visible_data(VideoFrame::kVPlane), + video_frame->stride(VideoFrame::kVPlane), + static_cast<uint8_t*>(rgb_pixels), row_bytes, + video_frame->visible_rect().width(), + video_frame->visible_rect().height()); + break; + case kRec601_SkYUVColorSpace: + LIBYUV_I420_TO_ARGB(video_frame->visible_data(VideoFrame::kYPlane), + video_frame->stride(VideoFrame::kYPlane), + video_frame->visible_data(VideoFrame::kUPlane), + video_frame->stride(VideoFrame::kUPlane), + video_frame->visible_data(VideoFrame::kVPlane), + video_frame->stride(VideoFrame::kVPlane), + static_cast<uint8_t*>(rgb_pixels), row_bytes, + video_frame->visible_rect().width(), + video_frame->visible_rect().height()); + break; } break; case PIXEL_FORMAT_I422: @@ -748,7 +749,7 @@ break; case PIXEL_FORMAT_YUV420P10: - if (CheckColorSpace(video_frame, COLOR_SPACE_HD_REC709)) { + if (color_space == kRec709_SkYUVColorSpace) { LIBYUV_H010_TO_ARGB(reinterpret_cast<const uint16_t*>( video_frame->visible_data(VideoFrame::kYPlane)), video_frame->stride(VideoFrame::kYPlane) / 2,
diff --git a/mojo/edk/system/channel_win.cc b/mojo/edk/system/channel_win.cc index 285ccf4..8a346ca9 100644 --- a/mojo/edk/system/channel_win.cc +++ b/mojo/edk/system/channel_win.cc
@@ -175,10 +175,15 @@ DWORD bytes_transfered, DWORD error) override { if (error != ERROR_SUCCESS) { - if (context == &write_context_) + if (context == &write_context_) { + { + base::AutoLock lock(write_lock_); + reject_writes_ = true; + } OnWriteError(Error::kDisconnected); - else + } else { OnError(Error::kDisconnected); + } } else if (context == &connect_context_) { DCHECK(is_connect_pending_); is_connect_pending_ = false;
diff --git a/net/base/filename_util_unittest.cc b/net/base/filename_util_unittest.cc index 0010b44b..5b40aee 100644 --- a/net/base/filename_util_unittest.cc +++ b/net/base/filename_util_unittest.cc
@@ -9,6 +9,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/test/test_file_util.h" +#include "build/build_config.h" #include "net/base/mime_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -284,79 +285,64 @@ EXPECT_FALSE(FileURLToFilePath(GURL("filefoobar"), &output)); } -// Flaky, see http://crbug.com/828954. -TEST(FilenameUtilTest, DISABLED_GenerateSafeFileName) { +TEST(FilenameUtilTest, GenerateSafeFileName) { const struct { + int line; const char* mime_type; - const base::FilePath::CharType* filename; - const base::FilePath::CharType* expected_filename; + const char* filename; + const char* expected_filename; } safe_tests[] = { + {__LINE__, "text/html", "bar.htm", "bar.htm"}, + {__LINE__, "text/html", "bar.html", "bar.html"}, + {__LINE__, "application/x-chrome-extension", "bar", "bar.crx"}, + {__LINE__, "image/png", "bar.html", "bar.html"}, + {__LINE__, "text/html", "bar.exe", "bar.exe"}, + {__LINE__, "image/gif", "bar.exe", "bar.exe"}, + {__LINE__, "text/html", "google.com", "google.com"}, + // Allow extension synonyms. + {__LINE__, "image/jpeg", "bar.jpg", "bar.jpg"}, + {__LINE__, "image/jpeg", "bar.jpeg", "bar.jpeg"}, + #if defined(OS_WIN) - {"text/html", FILE_PATH_LITERAL("C:\\foo\\bar.htm"), - FILE_PATH_LITERAL("C:\\foo\\bar.htm")}, - {"text/html", FILE_PATH_LITERAL("C:\\foo\\bar.html"), - FILE_PATH_LITERAL("C:\\foo\\bar.html")}, - {"text/html", FILE_PATH_LITERAL("C:\\foo\\bar"), - FILE_PATH_LITERAL("C:\\foo\\bar.htm")}, - {"image/png", FILE_PATH_LITERAL("C:\\bar.html"), - FILE_PATH_LITERAL("C:\\bar.html")}, - {"image/png", FILE_PATH_LITERAL("C:\\bar"), - FILE_PATH_LITERAL("C:\\bar.png")}, - {"text/html", FILE_PATH_LITERAL("C:\\foo\\bar.exe"), - FILE_PATH_LITERAL("C:\\foo\\bar.exe")}, - {"image/gif", FILE_PATH_LITERAL("C:\\foo\\bar.exe"), - FILE_PATH_LITERAL("C:\\foo\\bar.exe")}, - {"text/html", FILE_PATH_LITERAL("C:\\foo\\google.com"), - FILE_PATH_LITERAL("C:\\foo\\google.com")}, - {"text/html", FILE_PATH_LITERAL("C:\\foo\\con.htm"), - FILE_PATH_LITERAL("C:\\foo\\_con.htm")}, - {"text/html", FILE_PATH_LITERAL("C:\\foo\\con"), - FILE_PATH_LITERAL("C:\\foo\\_con.htm")}, - {"text/html", - FILE_PATH_LITERAL("C:\\foo\\harmless.{not-really-this-may-be-a-guid}"), - FILE_PATH_LITERAL("C:\\foo\\harmless.download")}, - {"text/html", FILE_PATH_LITERAL("C:\\foo\\harmless.local"), - FILE_PATH_LITERAL("C:\\foo\\harmless.download")}, - {"text/html", FILE_PATH_LITERAL("C:\\foo\\harmless.lnk"), - FILE_PATH_LITERAL("C:\\foo\\harmless.download")}, - {"text/html", FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-"), - FILE_PATH_LITERAL("C:\\foo\\harmless.{mismatched-")}, - // Allow extension synonyms. - {"image/jpeg", FILE_PATH_LITERAL("C:\\foo\\bar.jpg"), - FILE_PATH_LITERAL("C:\\foo\\bar.jpg")}, - {"image/jpeg", FILE_PATH_LITERAL("C:\\foo\\bar.jpeg"), - FILE_PATH_LITERAL("C:\\foo\\bar.jpeg")}, -#else // !defined(OS_WIN) - {"text/html", FILE_PATH_LITERAL("/foo/bar.htm"), - FILE_PATH_LITERAL("/foo/bar.htm")}, - {"text/html", FILE_PATH_LITERAL("/foo/bar.html"), - FILE_PATH_LITERAL("/foo/bar.html")}, - {"text/html", FILE_PATH_LITERAL("/foo/bar"), - FILE_PATH_LITERAL("/foo/bar.html")}, - {"image/png", FILE_PATH_LITERAL("/bar.html"), - FILE_PATH_LITERAL("/bar.html")}, - {"image/png", FILE_PATH_LITERAL("/bar"), FILE_PATH_LITERAL("/bar.png")}, - {"image/gif", FILE_PATH_LITERAL("/foo/bar.exe"), - FILE_PATH_LITERAL("/foo/bar.exe")}, - {"text/html", FILE_PATH_LITERAL("/foo/google.com"), - FILE_PATH_LITERAL("/foo/google.com")}, - {"text/html", FILE_PATH_LITERAL("/foo/con.htm"), - FILE_PATH_LITERAL("/foo/con.htm")}, - {"text/html", FILE_PATH_LITERAL("/foo/con"), - FILE_PATH_LITERAL("/foo/con.html")}, - // Allow extension synonyms. - {"image/jpeg", FILE_PATH_LITERAL("/bar.jpg"), - FILE_PATH_LITERAL("/bar.jpg")}, - {"image/jpeg", FILE_PATH_LITERAL("/bar.jpeg"), - FILE_PATH_LITERAL("/bar.jpeg")}, + // Device names + {__LINE__, "text/html", "con.htm", "_con.htm"}, + {__LINE__, "text/html", "lpt1.htm", "_lpt1.htm"}, + {__LINE__, "application/x-chrome-extension", "con", "_con.crx"}, + + // Looks like foo.{GUID} which get treated as namespace mounts on Windows. + {__LINE__, "text/html", "harmless.{not-really-this-may-be-a-guid}", + "harmless.download"}, + {__LINE__, "text/html", "harmless.{mismatched-", "harmless.{mismatched-"}, + + // Dangerous extensions + {__LINE__, "text/html", "harmless.local", "harmless.download"}, + {__LINE__, "text/html", "harmless.lnk", "harmless.download"}, +#else // OS_WIN + // On Posix, none of the above set is particularly dangerous. + {__LINE__, "text/html", "con.htm", "con.htm"}, + {__LINE__, "text/html", "lpt1.htm", "lpt1.htm"}, + {__LINE__, "application/x-chrome-extension", "con", "con.crx"}, + {__LINE__, "text/html", "harmless.{not-really-this-may-be-a-guid}", + "harmless.{not-really-this-may-be-a-guid}"}, + {__LINE__, "text/html", "harmless.{mismatched-", "harmless.{mismatched-"}, + {__LINE__, "text/html", "harmless.local", "harmless.local"}, + {__LINE__, "text/html", "harmless.lnk", "harmless.lnk"}, #endif // !defined(OS_WIN) }; - for (size_t i = 0; i < arraysize(safe_tests); ++i) { - base::FilePath file_path(safe_tests[i].filename); - GenerateSafeFileName(safe_tests[i].mime_type, false, &file_path); - EXPECT_EQ(safe_tests[i].expected_filename, file_path.value()) - << "Iteration " << i; +#if defined(OS_WIN) + base::FilePath base_path(L"C:\\foo"); +#else + base::FilePath base_path("/foo"); +#endif + + for (const auto& test : safe_tests) { + base::FilePath file_path = base_path.AppendASCII(test.filename); + base::FilePath expected_path = + base_path.AppendASCII(test.expected_filename); + GenerateSafeFileName(test.mime_type, false, &file_path); + EXPECT_EQ(expected_path.value(), file_path.value()) + << "Test case at line " << test.line; } }
diff --git a/net/disk_cache/simple/simple_backend_impl.cc b/net/disk_cache/simple/simple_backend_impl.cc index bbf9773..3fbb29f 100644 --- a/net/disk_cache/simple/simple_backend_impl.cc +++ b/net/disk_cache/simple/simple_backend_impl.cc
@@ -32,6 +32,7 @@ #include "base/time/time.h" #include "base/trace_event/memory_usage_estimator.h" #include "base/trace_event/process_memory_dump.h" +#include "build/build_config.h" #include "net/base/net_errors.h" #include "net/disk_cache/backend_cleanup_tracker.h" #include "net/disk_cache/cache_util.h" @@ -73,11 +74,6 @@ // Maximum fraction of the cache that one entry can consume. const int kMaxFileRatio = 8; -#if defined(OS_POSIX) && !defined(OS_ANDROID) -// Period to check the maximum count of files available -constexpr int kUpdateIntervalInSeconds = 10 * 60; // 10 min -#endif - bool g_fd_limit_histogram_has_been_populated = false; void MaybeHistogramFdLimit() { @@ -644,18 +640,6 @@ const DiskStatResult& result) { if (result.net_error == net::OK) { index_->SetMaxSize(result.max_size); -#if defined(OS_POSIX) && !defined(OS_ANDROID) - int64_t available = base::SysInfo::AmountOfAvailableDiskInode(path_); - int64_t total = base::SysInfo::AmountOfMaxDiskInode(path_); - if (available != -1 && total != -1) { - index_->UpdateMaxFiles(available, total); - if (!update_timer_.IsRunning()) - update_timer_.Start( - FROM_HERE, base::TimeDelta::FromSeconds(kUpdateIntervalInSeconds), - base::BindRepeating(&SimpleBackendImpl::OnUpdateMaxFiles, - AsWeakPtr())); - } -#endif index_->Initialize(result.cache_dir_mtime); } callback.Run(result.net_error); @@ -867,13 +851,4 @@ base::TaskScheduler::GetInstance()->FlushForTesting(); } -#if defined(OS_POSIX) && !defined(OS_ANDROID) -void SimpleBackendImpl::OnUpdateMaxFiles() { - int64_t available = base::SysInfo::AmountOfAvailableDiskInode(path_); - int64_t total = base::SysInfo::AmountOfMaxDiskInode(path_); - if (available != -1 && total != -1) - index_->UpdateMaxFiles(available, total); -} -#endif - } // namespace disk_cache
diff --git a/net/disk_cache/simple/simple_backend_impl.h b/net/disk_cache/simple/simple_backend_impl.h index 1190461..370969b0 100644 --- a/net/disk_cache/simple/simple_backend_impl.h +++ b/net/disk_cache/simple/simple_backend_impl.h
@@ -21,7 +21,6 @@ #include "base/strings/string_split.h" #include "base/task_runner.h" #include "base/time/time.h" -#include "build/build_config.h" #include "net/base/cache_type.h" #include "net/base/net_export.h" #include "net/disk_cache/disk_cache.h" @@ -29,10 +28,6 @@ #include "net/disk_cache/simple/simple_experiment.h" #include "net/disk_cache/simple/simple_index_delegate.h" -#if defined(OS_POSIX) && !defined(OS_ANDROID) -#include "base/timer/timer.h" -#endif - namespace base { class SequencedTaskRunner; class TaskRunner; @@ -242,11 +237,6 @@ const CompletionCallback& callback, int result); -#if defined(OS_POSIX) && !defined(OS_ANDROID) - // update limit of max files to be created - void OnUpdateMaxFiles(); -#endif - // We want this destroyed after every other field. scoped_refptr<BackendCleanupTracker> cleanup_tracker_; @@ -276,10 +266,6 @@ entries_pending_doom_; net::NetLog* const net_log_; - -#if defined(OS_POSIX) && !defined(OS_ANDROID) - base::RepeatingTimer update_timer_; -#endif }; } // namespace disk_cache
diff --git a/net/disk_cache/simple/simple_index.cc b/net/disk_cache/simple/simple_index.cc index 3d4b702..a891458 100644 --- a/net/disk_cache/simple/simple_index.cc +++ b/net/disk_cache/simple/simple_index.cc
@@ -155,9 +155,6 @@ max_size_(0), high_watermark_(0), low_watermark_(0), - max_files_(0), - files_high_watermark_(0), - files_low_watermark_(0), eviction_in_progress_(false), initialized_(false), init_method_(INITIALIZE_METHOD_MAX), @@ -350,10 +347,7 @@ void SimpleIndex::StartEvictionIfNeeded() { DCHECK(io_thread_checker_.CalledOnValidThread()); - uint64_t cache_files = entries_set_.size(); - if (eviction_in_progress_ || - (cache_size_ <= high_watermark_ && - (files_high_watermark_ == 0 || cache_files <= files_high_watermark_))) + if (eviction_in_progress_ || cache_size_ <= high_watermark_) return; // Take all live key hashes from the index and sort them by time. eviction_in_progress_ = true; @@ -384,21 +378,13 @@ } uint64_t evicted_so_far_size = 0; - const uint64_t amount_to_evict = - (cache_size_ > low_watermark_) ? cache_size_ - low_watermark_ : 0; - uint64_t evicted_files_count = 0; - const uint64_t file_amount_to_evict = - (files_low_watermark_ > 0 && cache_files > files_low_watermark_) - ? cache_files - files_low_watermark_ - : 0; + const uint64_t amount_to_evict = cache_size_ - low_watermark_; std::vector<uint64_t> entry_hashes; std::sort(entries.begin(), entries.end()); for (const auto& score_metadata_pair : entries) { - if (evicted_so_far_size >= amount_to_evict && - evicted_files_count >= file_amount_to_evict) + if (evicted_so_far_size >= amount_to_evict) break; evicted_so_far_size += score_metadata_pair.second->second.GetEntrySize(); - evicted_files_count++; entry_hashes.push_back(score_metadata_pair.second->first); } @@ -543,10 +529,6 @@ io_thread_->PostTask(FROM_HERE, base::Bind((*it), net::OK)); } to_run_when_initialized_.clear(); - if (!update_max_files_cb_.is_null()) { - std::move(update_max_files_cb_).Run(); - CHECK(update_max_files_cb_.is_null()); - } } #if defined(OS_ANDROID) @@ -599,23 +581,4 @@ app_on_background_, after_write); } -void SimpleIndex::UpdateMaxFiles(uint64_t available, uint64_t total) { - DCHECK(io_thread_checker_.CalledOnValidThread()); - if (!initialized_) { - update_max_files_cb_ = base::BindOnce(&SimpleIndex::UpdateMaxFiles, - AsWeakPtr(), available, total); - return; - } - - auto cache_files = entries_set_.size(); - uint64_t max_files = static_cast<uint64_t>((cache_files + available) * 0.3); - if (max_files_ == max_files) - return; - - max_files_ = max_files; - files_high_watermark_ = max_files_ - max_files_ / kEvictionMarginDivisor; - files_low_watermark_ = max_files_ - 2 * (max_files_ / kEvictionMarginDivisor); - StartEvictionIfNeeded(); -} - } // namespace disk_cache
diff --git a/net/disk_cache/simple/simple_index.h b/net/disk_cache/simple/simple_index.h index 68c1024..0da8cd9 100644 --- a/net/disk_cache/simple/simple_index.h +++ b/net/disk_cache/simple/simple_index.h
@@ -194,8 +194,6 @@ void SetLastUsedTimeForTest(uint64_t entry_hash, const base::Time last_used); - void UpdateMaxFiles(uint64_t available, uint64_t total); - private: friend class SimpleIndexTest; FRIEND_TEST_ALL_PREFIXES(SimpleIndexTest, IndexSizeCorrectOnMerge); @@ -233,10 +231,6 @@ uint64_t max_size_; uint64_t high_watermark_; uint64_t low_watermark_; - uint64_t max_files_; // Maximum number of files allowed (0 if unlimited). - // High and low thresholds for allowed number of files (0 if unlimited). - uint64_t files_high_watermark_; - uint64_t files_low_watermark_; bool eviction_in_progress_; base::TimeTicks eviction_start_time_; @@ -261,7 +255,6 @@ base::OneShotTimer write_to_disk_timer_; base::Closure write_to_disk_cb_; - base::OnceClosure update_max_files_cb_; typedef std::list<net::CompletionCallback> CallbackList; CallbackList to_run_when_initialized_;
diff --git a/net/disk_cache/simple/simple_index_unittest.cc b/net/disk_cache/simple/simple_index_unittest.cc index 7463c09..03a6bedc 100644 --- a/net/disk_cache/simple/simple_index_unittest.cc +++ b/net/disk_cache/simple/simple_index_unittest.cc
@@ -176,7 +176,7 @@ } int doom_entries_calls() const { return doom_entries_calls_; } - const simple_util::ImmutableArray<uint64_t, 20> hashes_; + const simple_util::ImmutableArray<uint64_t, 16> hashes_; std::unique_ptr<SimpleIndex> index_; base::WeakPtr<MockSimpleIndexFile> index_file_; @@ -697,66 +697,6 @@ ASSERT_EQ(2u, last_doom_entry_hashes().size()); } -TEST_F(SimpleIndexTest, EvictByFileCount) { - base::Time now(base::Time::Now()); - index()->SetMaxSize(50000); - InsertIntoIndexFileReturn(hashes_.at<0>(), - now - base::TimeDelta::FromDays(21), 10u); - InsertIntoIndexFileReturn(hashes_.at<1>(), - now - base::TimeDelta::FromDays(20), 10u); - InsertIntoIndexFileReturn(hashes_.at<2>(), - now - base::TimeDelta::FromDays(19), 10u); - InsertIntoIndexFileReturn(hashes_.at<3>(), - now - base::TimeDelta::FromDays(18), 10u); - InsertIntoIndexFileReturn(hashes_.at<4>(), - now - base::TimeDelta::FromDays(17), 10u); - InsertIntoIndexFileReturn(hashes_.at<5>(), - now - base::TimeDelta::FromDays(16), 10u); - InsertIntoIndexFileReturn(hashes_.at<6>(), - now - base::TimeDelta::FromDays(15), 10u); - InsertIntoIndexFileReturn(hashes_.at<7>(), - now - base::TimeDelta::FromDays(14), 10u); - InsertIntoIndexFileReturn(hashes_.at<8>(), - now - base::TimeDelta::FromDays(13), 10u); - InsertIntoIndexFileReturn(hashes_.at<9>(), - now - base::TimeDelta::FromDays(12), 10u); - InsertIntoIndexFileReturn(hashes_.at<10>(), - now - base::TimeDelta::FromDays(11), 10u); - InsertIntoIndexFileReturn(hashes_.at<11>(), - now - base::TimeDelta::FromDays(10), 10u); - InsertIntoIndexFileReturn(hashes_.at<12>(), - now - base::TimeDelta::FromDays(9), 10u); - InsertIntoIndexFileReturn(hashes_.at<13>(), - now - base::TimeDelta::FromDays(8), 10u); - InsertIntoIndexFileReturn(hashes_.at<14>(), - now - base::TimeDelta::FromDays(7), 10u); - InsertIntoIndexFileReturn(hashes_.at<15>(), - now - base::TimeDelta::FromDays(6), 10u); - InsertIntoIndexFileReturn(hashes_.at<16>(), - now - base::TimeDelta::FromDays(5), 10u); - InsertIntoIndexFileReturn(hashes_.at<17>(), - now - base::TimeDelta::FromDays(4), 10u); - index()->UpdateMaxFiles(50, 200); - // This should set the max files limit to 20, so the high watermark is 19 and - // the lower watermark is 18. - ReturnIndexFile(); - WaitForTimeChange(); - - // No eviction should have happened yet. - EXPECT_EQ(18, index()->GetEntryCount()); - - index()->Insert(hashes_.at<18>()); - index()->UpdateEntrySize(hashes_.at<18>(), 10u); - index()->Insert(hashes_.at<19>()); - index()->UpdateEntrySize(hashes_.at<19>(), 10u); - - // Eviction has happened, we get back to 18 elements - EXPECT_EQ(18, index()->GetEntryCount()); - EXPECT_EQ(1, doom_entries_calls()); - EXPECT_TRUE(index()->Has(hashes_.at<2>())); - EXPECT_FALSE(index()->Has(hashes_.at<1>())); -} - // Confirm all the operations queue a disk write at some point in the // future. TEST_F(SimpleIndexTest, DiskWriteQueued) {
diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc index 106f59e..8656d3f 100644 --- a/net/http/http_response_info.cc +++ b/net/http/http_response_info.cc
@@ -191,6 +191,8 @@ ssl_info.connection_status = connection_status; } + // Signed Certificate Timestamps are no longer persisted to the cache, so + // ignore them when reading them out. if (flags & RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS) { int num_scts; if (!iter.ReadInt(&num_scts)) @@ -201,11 +203,6 @@ uint16_t status; if (!sct.get() || !iter.ReadUInt16(&status)) return false; - if (!net::ct::IsValidSCTStatus(status)) - return false; - ssl_info.signed_certificate_timestamps.push_back( - SignedCertificateTimestampAndStatus( - sct, static_cast<ct::SCTVerifyStatus>(status))); } } @@ -305,8 +302,6 @@ flags |= RESPONSE_INFO_USE_HTTP_AUTHENTICATION; if (unused_since_prefetch) flags |= RESPONSE_INFO_UNUSED_SINCE_PREFETCH; - if (!ssl_info.signed_certificate_timestamps.empty()) - flags |= RESPONSE_INFO_HAS_SIGNED_CERTIFICATE_TIMESTAMPS; if (ssl_info.pkp_bypassed) flags |= RESPONSE_INFO_PKP_BYPASSED; @@ -335,15 +330,6 @@ pickle->WriteInt(ssl_info.security_bits); if (ssl_info.connection_status != 0) pickle->WriteInt(ssl_info.connection_status); - if (!ssl_info.signed_certificate_timestamps.empty()) { - pickle->WriteInt(ssl_info.signed_certificate_timestamps.size()); - for (SignedCertificateTimestampAndStatusList::const_iterator it = - ssl_info.signed_certificate_timestamps.begin(); it != - ssl_info.signed_certificate_timestamps.end(); ++it) { - it->sct->Persist(pickle); - pickle->WriteUInt16(static_cast<uint16_t>(it->status)); - } - } } if (vary_data.is_valid())
diff --git a/net/http/http_response_info_unittest.cc b/net/http/http_response_info_unittest.cc index b8aadbb..d880cff 100644 --- a/net/http/http_response_info_unittest.cc +++ b/net/http/http_response_info_unittest.cc
@@ -72,35 +72,6 @@ EXPECT_FALSE(restored_response_info.ssl_info.pkp_bypassed); } -TEST_F(HttpResponseInfoTest, FailsInitFromPickleWithInvalidSCTStatus) { - // A valid certificate is needed for ssl_info.is_valid() to be true - // so that the SCTs would be serialized. - response_info_.ssl_info.cert = - ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); - - scoped_refptr<ct::SignedCertificateTimestamp> sct; - ct::GetX509CertSCT(&sct); - - response_info_.ssl_info.signed_certificate_timestamps.push_back( - SignedCertificateTimestampAndStatus( - sct, ct::SCTVerifyStatus::SCT_STATUS_LOG_UNKNOWN)); - - base::Pickle pickle; - response_info_.Persist(&pickle, false, false); - bool truncated = false; - net::HttpResponseInfo restored_response_info; - EXPECT_TRUE(restored_response_info.InitFromPickle(pickle, &truncated)); - - response_info_.ssl_info.signed_certificate_timestamps.push_back( - SignedCertificateTimestampAndStatus(sct, - static_cast<ct::SCTVerifyStatus>(2))); - base::Pickle pickle_invalid; - response_info_.Persist(&pickle_invalid, false, false); - net::HttpResponseInfo restored_invalid_response; - EXPECT_FALSE( - restored_invalid_response.InitFromPickle(pickle_invalid, &truncated)); -} - // Test that key_exchange_group is preserved for ECDHE ciphers. TEST_F(HttpResponseInfoTest, KeyExchangeGroupECDHE) { response_info_.ssl_info.cert =
diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index d2f010a..cfd6728 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc
@@ -1056,11 +1056,18 @@ NetLogEventType::HTTP_STREAM_REQUEST_PROTO, base::Bind(&NetLogHttpStreamProtoCallback, negotiated_protocol_)); if (negotiated_protocol_ == kProtoHTTP2) { - // If request is WebSocket with no proxy, then HTTP/2 must not have - // been advertised in the TLS handshake. The TLS layer must not have - // accepted the server choosing HTTP/2. - // TODO(bnc): Change to DCHECK once https://crbug.com/819101 is fixed. - CHECK(!(is_websocket_ && proxy_info_.is_direct())); + if (is_websocket_) { + // If request is WebSocket with no proxy, then HTTP/2 must not have + // been advertised in the TLS handshake. The TLS layer must not + // have accepted the server choosing HTTP/2. + // TODO(bnc): Change to DCHECK once https://crbug.com/819101 is + // fixed. + CHECK(!proxy_info_.is_direct()); + + // WebSocket is not supported over a fresh HTTP/2 connection. + return ERR_NOT_IMPLEMENTED; + } + using_spdy_ = true; } }
diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h index 6420f6b..596c35c 100644 --- a/net/log/net_log_event_type_list.h +++ b/net/log/net_log_event_type_list.h
@@ -3096,50 +3096,6 @@ // } EVENT_TYPE(DATA_REDUCTION_PROXY_CONFIG_REQUEST) -// ----------------------------------------------------------------------------- -// Safe Browsing related events -// ----------------------------------------------------------------------------- - -// The start/end of an async URL check by Safe Browsing. Will only show up if -// it can't be classified as "safe" synchronously. -// -// The BEGIN phase contains the following parameters: -// { -// "url": <The URL being checked>, -// } -// -// The END phase contains the following parameters: -// { -// "result": <"safe", "unsafe", or "request_canceled"> -// } -EVENT_TYPE(SAFE_BROWSING_CHECKING_URL) - -// The start/end of some portion of the SAFE_BROWSING_CHECKING_URL during which -// the request is delayed due to that check. -// -// The BEGIN phase contains the following parameters: -// { -// "url": <The URL being checked>, -// "defer_reason" : < "at_start", "at_response", "redirect", -// "resumed_redirect", "unchecked_redirect"> -// } -EVENT_TYPE(SAFE_BROWSING_DEFERRED) - -// The start/end of a Safe Browsing ping being sent. -// -// The BEGIN phase contains the following parameters: -// { -// "url": <The URL the ping is going to, which identifies the type of ping -// that is being sent (eg: ThreatReport, SafeBrowsingHit)> -// "data": <The base64 encoding of the payload sent with the ping> -// -// The END phase contains the following parameters: -// { -// "status": <The integer status of the report transmission. Corresponds to -// URLRequestStatus::Status> -// "error": <The error code returned by the server, 0 indicating success> -EVENT_TYPE(SAFE_BROWSING_PING) - // Marks start of UploadDataStream that is logged on initialization. // The END phase contains the following parameters: // {
diff --git a/net/socket/transport_client_socket_pool_unittest.cc b/net/socket/transport_client_socket_pool_unittest.cc index bdd5df5..7d844f7 100644 --- a/net/socket/transport_client_socket_pool_unittest.cc +++ b/net/socket/transport_client_socket_pool_unittest.cc
@@ -510,11 +510,7 @@ // run through the MessageLoop once to get it completely released. handle_->socket()->Disconnect(); handle_->Reset(); - { - base::MessageLoop::ScopedNestableTaskAllower allow( - base::MessageLoop::current()); - base::RunLoop().RunUntilIdle(); - } + base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle(); within_callback_ = true; scoped_refptr<TransportSocketParams> dest(new TransportSocketParams( HostPortPair("www.google.com", 80), false, OnHostResolutionCallback(),
diff --git a/net/spdy/chromium/spdy_network_transaction_unittest.cc b/net/spdy/chromium/spdy_network_transaction_unittest.cc index c4d3816..080b765 100644 --- a/net/spdy/chromium/spdy_network_transaction_unittest.cc +++ b/net/spdy/chromium/spdy_network_transaction_unittest.cc
@@ -7350,6 +7350,8 @@ SSLSocketDataProvider ssl_provider(ASYNC, OK); ssl_provider.ssl_info.cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"); + // A WebSocket request should not advertise HTTP/2 support. + ssl_provider.next_protos_expected_in_ssl_config = NextProtoVector{}; // This test uses WebSocket over HTTP/1.1. ssl_provider.next_proto = kProtoHTTP11; helper.session_deps()->socket_factory->AddSSLSocketDataProvider( @@ -7378,6 +7380,56 @@ helper.VerifyDataConsumed(); } +// Regression test for https://crbug.com/828865. +TEST_F(SpdyNetworkTransactionTest, + SecureWebSocketOverHttp2ProxyNegotiatesHttp2) { + SpdySerializedFrame connect_request(spdy_util_.ConstructSpdyConnect( + nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443))); + MockWrite writes[] = {CreateMockWrite(connect_request, 0)}; + SpdySerializedFrame connect_response( + spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); + MockRead reads[] = {CreateMockRead(connect_response, 1), + MockRead(ASYNC, 0, 2)}; + SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); + + request_.url = GURL("wss://www.example.org/"); + request_.extra_headers.SetHeader("Connection", "Upgrade"); + request_.extra_headers.SetHeader("Upgrade", "websocket"); + request_.extra_headers.SetHeader("Origin", "http://www.example.org"); + request_.extra_headers.SetHeader("Sec-WebSocket-Version", "13"); + auto session_deps = std::make_unique<SpdySessionDependencies>( + ProxyResolutionService::CreateFixed("https://proxy:70", + TRAFFIC_ANNOTATION_FOR_TESTS)); + NormalSpdyTransactionHelper helper(request_, DEFAULT_PRIORITY, log_, + std::move(session_deps)); + helper.RunPreTestSetup(); + helper.AddData(&data); + + // Add SSL data for the tunneled connection. + SSLSocketDataProvider ssl_provider(ASYNC, OK); + ssl_provider.ssl_info.cert = + ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"); + // A WebSocket request should not advertise HTTP/2 support. + ssl_provider.next_protos_expected_in_ssl_config = NextProtoVector{}; + // The server should not negotiate HTTP/2 over the tunnelled connection, + // but it must be handled gracefully if it does. + ssl_provider.next_proto = kProtoHTTP2; + helper.session_deps()->socket_factory->AddSSLSocketDataProvider( + &ssl_provider); + + HttpNetworkTransaction* trans = helper.trans(); + TestWebSocketHandshakeStreamCreateHelper websocket_stream_create_helper; + trans->SetWebSocketHandshakeStreamCreateHelper( + &websocket_stream_create_helper); + + EXPECT_TRUE(helper.StartDefaultTest()); + helper.WaitForCallbackToComplete(); + EXPECT_THAT(helper.output().rv, IsError(ERR_NOT_IMPLEMENTED)); + + base::RunLoop().RunUntilIdle(); + helper.VerifyDataConsumed(); +} + #endif // BUILDFLAG(ENABLE_WEBSOCKETS) } // namespace net
diff --git a/net/tools/quic/quic_server_bin.cc b/net/tools/quic/quic_server_bin.cc index 2bb71ba..c3d2291b 100644 --- a/net/tools/quic/quic_server_bin.cc +++ b/net/tools/quic/quic_server_bin.cc
@@ -33,13 +33,13 @@ } int main(int argc, char* argv[]) { - base::TaskScheduler::CreateAndStartWithDefaultParams("quic_server"); base::AtExitManager exit_manager; - base::MessageLoopForIO message_loop; - base::CommandLine::Init(argc, argv); base::CommandLine* line = base::CommandLine::ForCurrentProcess(); + base::MessageLoopForIO message_loop; + base::TaskScheduler::CreateAndStartWithDefaultParams("quic_server"); + logging::LoggingSettings settings; settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; CHECK(logging::InitLogging(settings));
diff --git a/net/tools/quic/quic_simple_client_bin.cc b/net/tools/quic/quic_simple_client_bin.cc index af5e63e2..f14f2aa 100644 --- a/net/tools/quic/quic_simple_client_bin.cc +++ b/net/tools/quic/quic_simple_client_bin.cc
@@ -136,10 +136,10 @@ }; int main(int argc, char* argv[]) { - base::TaskScheduler::CreateAndStartWithDefaultParams("quic_client"); base::CommandLine::Init(argc, argv); base::CommandLine* line = base::CommandLine::ForCurrentProcess(); const base::CommandLine::StringVector& urls = line->GetArgs(); + base::TaskScheduler::CreateAndStartWithDefaultParams("quic_client"); logging::LoggingSettings settings; settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
diff --git a/remoting/protocol/BUILD.gn b/remoting/protocol/BUILD.gn index 1398402..71846a6 100644 --- a/remoting/protocol/BUILD.gn +++ b/remoting/protocol/BUILD.gn
@@ -109,6 +109,8 @@ "mouse_input_filter.h", "named_message_pipe_handler.cc", "named_message_pipe_handler.h", + "native_ip_synthesizer.cc", + "native_ip_synthesizer.h", "negotiating_authenticator_base.cc", "negotiating_authenticator_base.h", "negotiating_client_authenticator.cc",
diff --git a/remoting/protocol/ice_transport.cc b/remoting/protocol/ice_transport.cc index 637498d..ff782f0d 100644 --- a/remoting/protocol/ice_transport.cc +++ b/remoting/protocol/ice_transport.cc
@@ -7,6 +7,7 @@ #include "base/bind.h" #include "remoting/protocol/channel_authenticator.h" #include "remoting/protocol/channel_multiplexer.h" +#include "remoting/protocol/native_ip_synthesizer.h" #include "remoting/protocol/pseudotcp_channel_factory.h" #include "remoting/protocol/secure_channel_factory.h" #include "remoting/protocol/stream_channel_factory.h" @@ -72,6 +73,8 @@ for (auto it = transport_info.candidates.begin(); it != transport_info.candidates.end(); ++it) { ChannelsMap::iterator channel = channels_.find(it->name); + rtc::SocketAddress address = ToNativeSocket(it->candidate.address()); + it->candidate.set_address(address); if (channel != channels_.end()) { channel->second->AddRemoteCandidate(it->candidate); } else {
diff --git a/remoting/protocol/native_ip_synthesizer.cc b/remoting/protocol/native_ip_synthesizer.cc new file mode 100644 index 0000000..8b2a782 --- /dev/null +++ b/remoting/protocol/native_ip_synthesizer.cc
@@ -0,0 +1,56 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "remoting/protocol/native_ip_synthesizer.h" + +#include "base/logging.h" +#include "build/build_config.h" +#include "net/base/sys_addrinfo.h" +#include "third_party/webrtc/rtc_base/ipaddress.h" +#include "third_party/webrtc/rtc_base/socketaddress.h" + +namespace remoting { +namespace protocol { + +// static +rtc::SocketAddress ToNativeSocket(const rtc::SocketAddress& original_socket) { +#if defined(OS_IOS) + // Currently only iOS needs the extra translation step. Android emulates an + // IPv4 network stack. + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_DEFAULT; + + addrinfo* result = nullptr; + // getaddrinfo() will resolve an IPv4 address into its curresponding IPv4/IPv6 + // address connectable on current network environment. Note that this doesn't + // really send out a DNS request on iOS. + int error = getaddrinfo(original_socket.ipaddr().ToString().c_str(), nullptr, + &hints, &result); + if (error) { + LOG(ERROR) << "getaddrinfo() failed for " << gai_strerror(error); + return original_socket; + } + + if (!result) { + return original_socket; + } + + rtc::SocketAddress new_socket; + bool success = rtc::SocketAddressFromSockAddrStorage( + *reinterpret_cast<sockaddr_storage*>(result->ai_addr), &new_socket); + DCHECK(success); + freeaddrinfo(result); + new_socket.SetPort(original_socket.port()); + return new_socket; +#else + return original_socket; +#endif // defined(OS_IOS) +} + +} // namespace protocol +} // namespace remoting
diff --git a/remoting/protocol/native_ip_synthesizer.h b/remoting/protocol/native_ip_synthesizer.h new file mode 100644 index 0000000..6855b016 --- /dev/null +++ b/remoting/protocol/native_ip_synthesizer.h
@@ -0,0 +1,34 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef REMOTING_PROTOCOL_NATIVE_IP_SYNTHESIZER_H_ +#define REMOTING_PROTOCOL_NATIVE_IP_SYNTHESIZER_H_ + +namespace rtc { +class SocketAddress; +} // namespace rtc + +namespace remoting { +namespace protocol { + +// Helper functions for synthesizing native IP address that is acceptabled by +// the OS from an IP literal. +// +// We hardcode IPv4 literals in stanza and other places. Some mobile ISP have an +// IPv6-only network with an IPv6->IPv4 gateway, so connecting with IPv4 literal +// may not work. Android and other OSes have a 464XLAT CLAT converter built into +// their network stack so IPv4 APIs are available to the app. However, iOS +// doesn't have this logic built into its network stack and instead requires +// developer to resolve an IPv6 address from IPv4 literal. This class helps +// working with this. + +// Translate socket address into the one acceptable by the OS. +// If native IP synthesis is not needed by the OS, |original_socket| will be +// returned. +rtc::SocketAddress ToNativeSocket(const rtc::SocketAddress& original_socket); + +} // namespace protocol +} // namespace remoting + +#endif // REMOTING_PROTOCOL_NATIVE_IP_SYNTHESIZER_H_
diff --git a/remoting/protocol/port_allocator.cc b/remoting/protocol/port_allocator.cc index 82efea2..ae438e1 100644 --- a/remoting/protocol/port_allocator.cc +++ b/remoting/protocol/port_allocator.cc
@@ -15,6 +15,7 @@ #include "net/base/escape.h" #include "net/http/http_status_code.h" #include "net/traffic_annotation/network_traffic_annotation.h" +#include "remoting/protocol/native_ip_synthesizer.h" #include "remoting/protocol/network_settings.h" #include "remoting/protocol/transport_context.h" @@ -232,8 +233,9 @@ base::StringToUint(relay_port, &relay_port_int)) { cricket::RelayServerConfig relay_config(cricket::RELAY_GTURN); rtc::SocketAddress address(relay_ip, relay_port_int); + // |relay_ip| is in IPv4 so we will need to do an IPv6 synthesis. relay_config.ports.push_back( - cricket::ProtocolAddress(address, cricket::PROTO_UDP)); + cricket::ProtocolAddress(ToNativeSocket(address), cricket::PROTO_UDP)); config->AddRelay(relay_config); }
diff --git a/services/network/test/test_url_loader_factory.cc b/services/network/test/test_url_loader_factory.cc index d2582233..0df8159c 100644 --- a/services/network/test/test_url_loader_factory.cc +++ b/services/network/test/test_url_loader_factory.cc
@@ -96,13 +96,16 @@ return false; CHECK(it->second.redirects.empty()) << "TODO(jam): handle redirects"; - client->OnReceiveResponse(it->second.head, nullptr); - mojo::DataPipe data_pipe(it->second.content.size()); - uint32_t bytes_written = it->second.content.size(); - CHECK_EQ(MOJO_RESULT_OK, data_pipe.producer_handle->WriteData( - it->second.content.data(), &bytes_written, - MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); - client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle)); + + if (it->second.status.error_code == net::OK) { + client->OnReceiveResponse(it->second.head, nullptr); + mojo::DataPipe data_pipe(it->second.content.size()); + uint32_t bytes_written = it->second.content.size(); + CHECK_EQ(MOJO_RESULT_OK, data_pipe.producer_handle->WriteData( + it->second.content.data(), &bytes_written, + MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); + client->OnStartLoadingResponseBody(std::move(data_pipe.consumer_handle)); + } client->OnComplete(it->second.status); return true; }
diff --git a/testing/BUILD.gn b/testing/BUILD.gn index 1477b173..70b4201 100644 --- a/testing/BUILD.gn +++ b/testing/BUILD.gn
@@ -30,10 +30,13 @@ ] } -group("run_gtest_perf_test") { +group("run_perf_test") { data = [ "//testing/scripts/common.py", "//testing/scripts/run_gtest_perf_test.py", + "//testing/scripts/run_performance_tests.py", + "//testing/scripts/run_performance_tests_wrapper.py", + "//testing/scripts/run_telemetry_benchmark_as_googletest.py", "//tools/perf/generate_legacy_perf_dashboard_json.py", ]
diff --git a/testing/buildbot/chromium.perf.fyi.json b/testing/buildbot/chromium.perf.fyi.json index bc989093..390ae542 100644 --- a/testing/buildbot/chromium.perf.fyi.json +++ b/testing/buildbot/chromium.perf.fyi.json
@@ -4,7 +4,8 @@ { "args": [ "-v", - "--browser=android-chromium" + "--browser=android-chromium", + "--upload-results" ], "isolate_name": "performance_test_suite", "merge": { @@ -450,11 +451,10 @@ "isolated_scripts": [ { "args": [ - "-v", - "--browser=release", - "--non-telemetry=true" + "--non-telemetry=true", + "--migrated-test=true" ], - "isolate_name": "load_library_perf_tests_v2", + "isolate_name": "load_library_perf_tests", "merge": { "args": [ "--service-account-file", @@ -462,9 +462,9 @@ ], "script": "//tools/perf/process_perf_results.py" }, - "name": "load_library_perf_tests_v2", + "name": "load_library_perf_tests", "override_compile_targets": [ - "load_library_perf_tests_v2" + "load_library_perf_tests" ], "swarming": { "can_use_on_swarming_builders": true, @@ -495,7 +495,8 @@ { "args": [ "-v", - "--browser=release" + "--browser=release", + "--upload-results" ], "isolate_name": "performance_test_suite", "merge": { @@ -573,10 +574,53 @@ "isolated_scripts": [ { "args": [ + "--non-telemetry=true", + "--migrated-test=true" + ], + "isolate_name": "load_library_perf_tests", + "merge": { + "args": [ + "--service-account-file", + "/creds/service_accounts/service-account-chromium-perf-histograms.json" + ], + "script": "//tools/perf/process_perf_results.py" + }, + "name": "load_library_perf_tests", + "override_compile_targets": [ + "load_library_perf_tests" + ], + "swarming": { + "can_use_on_swarming_builders": true, + "dimension_sets": [ + { + "os": "Linux", + "pool": "Chrome-perf-fyi" + } + ], + "expiration": 36000, + "hard_timeout": 36000, + "ignore_task_failure": false, + "io_timeout": 1800, + "shards": 1, + "upload_test_results": true + }, + "trigger_script": { + "args": [ + "--multiple-trigger-configs", + "[{\"id\": \"swarm823-c4\"}]", + "--multiple-dimension-script-verbose", + "True" + ], + "script": "//testing/trigger_scripts/perf_device_trigger.py" + } + }, + { + "args": [ "-v", "--browser=reference", - "--xvfb", - "--testing=true" + "--upload-results", + "--testing=true", + "--xvfb" ], "isolate_name": "telemetry_perf_tests_experimental", "merge": {
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter index 603e3f49..9921e60 100644 --- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -7,6 +7,7 @@ -ChromeSecurityExploitBrowserTest.CreateFilesystemURLInExtensionOrigin -DisabledSignInIsolationBrowserTest.SyntheticTrial -DomainReliabilityBrowserTest.Upload +-DownloadTest.DownloadDangerousBlobData -EnabledSignInIsolationBrowserTest.SyntheticTrial -ExpectCTBrowserTest.TestDynamicExpectCTHeaderProcessing -ExpectCTBrowserTest.TestDynamicExpectCTReporting @@ -22,8 +23,6 @@ -PKPModelClientTest.PKPEnforced -PlatformAppBrowserTest.AppWindowAdjustBoundsToBeVisibleOnScreen -PlatformAppBrowserTest.CreateAndCloseAppWindow --PlatformAppDevToolsBrowserTest.ReOpenedWithID --PlatformAppDevToolsBrowserTest.ReOpenedWithURL -PolicyTest.DefaultCookiesSetting -PrefetchBrowserTestPredictionDisabled.ExperimentDisabled -PreviewsOptimizationGuideBrowserTest.NoScriptPreviewsEnabledByWhitelist @@ -41,6 +40,8 @@ -WebViewTests/WebViewTest.ClearDataCache/1 -WebViewTests/WebViewTest.WebViewInBackgroundPage/0 -WebViewTests/WebViewTest.WebViewInBackgroundPage/1 +-WebViewTests/WebViewTest.DownloadPermission/0 +-WebViewTests/WebViewTest.DownloadPermission/1 # Redirects to chrome-extension:// should be blocked unless the resource is # webaccessible. https://crbug.com/821586 @@ -175,6 +176,7 @@ # http://crbug.com/721414 # TODO(rockot): add support for webRequest API. -ExtensionWebRequestApiTest.WebRequestBlocking +-ExtensionWebRequestApiTest.WebRequestClientsGoogleComProtection -ExtensionWebRequestApiTest.WebRequestDeclarative2 -ExtensionWebRequestApiTest.WebRequestDiceHeaderProtection -ExtensionWebRequestApiTest.WebRequestTypes
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl index 083ceaeb..59517a09 100644 --- a/testing/buildbot/gn_isolate_map.pyl +++ b/testing/buildbot/gn_isolate_map.pyl
@@ -1146,16 +1146,7 @@ "load_library_perf_tests": { "label": "//chrome/test:load_library_perf_tests", "type": "script", - "script": "//testing/scripts/run_gtest_perf_test.py", - "args": [ - "load_library_perf_tests", - "--test-launcher-print-test-stdio=always" - ], - }, - "load_library_perf_tests_v2": { - "label": "//chrome/test:load_library_perf_tests_v2", - "type": "script", - "script": "//testing/scripts/run_performance_tests.py", + "script": "//testing/scripts/run_performance_tests_wrapper.py", "args": [ "load_library_perf_tests", "--test-launcher-print-test-stdio=always" @@ -1195,7 +1186,7 @@ "angle_perftests": { "label": "//chrome/test:angle_perftests", "type": "script", - "script": "//testing/scripts/run_gtest_perf_test.py", + "script": "//testing/scripts/run_performance_tests_wrapper.py", "args": [ "angle_perftests", "--test-launcher-print-test-stdio=always", @@ -1216,7 +1207,7 @@ "performance_browser_tests": { "label": "//chrome/test:performance_browser_tests", "type": "script", - "script": "//testing/scripts/run_gtest_perf_test.py", + "script": "//testing/scripts/run_performance_tests_wrapper.py", "args": [ "performance_browser_tests", "--test-launcher-print-test-stdio=always",
diff --git a/testing/scripts/run_performance_tests_wrapper.py b/testing/scripts/run_performance_tests_wrapper.py new file mode 100755 index 0000000..4924fb6 --- /dev/null +++ b/testing/scripts/run_performance_tests_wrapper.py
@@ -0,0 +1,40 @@ +#!/usr/bin/env python +# Copyright 2018 The Chromium 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 is a wrapper script used during migration of performance +tests to use the new recipe. See crbug.com/757933 + +Non-telemetry tests now will all run with this script. The flag +--migrated-test will indicate if this test is using the new recipe or not. +By default this script runs the legacy testing/scripts/run_gtest_perf_test.py. + +""" + +import argparse +import os +import subprocess +import sys + +SRC_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath( + __file__)))) + +GTEST = os.path.join(SRC_DIR, 'testing', 'scripts', 'run_gtest_perf_test.py') +PERF = os.path.join(SRC_DIR, 'testing', 'scripts', 'run_performance_tests.py') + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--migrated-test', type=bool, default=False) + + args, rest_args = parser.parse_known_args() + + if args.migrated_test: + return subprocess.call([sys.executable, PERF] + rest_args) + else: + return subprocess.call([sys.executable, GTEST] + rest_args) + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 1fdeba4f..8038d6d3 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -1683,6 +1683,22 @@ ] } ], + "IncompatibleApplicationsWarning": [ + { + "platforms": [ + "win" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "IncompatibleApplicationsWarning", + "ModuleDatabase" + ] + } + ] + } + ], "InstanceID": [ { "platforms": [ @@ -3679,23 +3695,6 @@ ] } ], - "TabSyncByRecency": [ - { - "platforms": [ - "android", - "chromeos", - "ios", - "linux", - "mac", - "win" - ], - "experiments": [ - { - "name": "Enabled" - } - ] - } - ], "ThrottleDelayable": [ { "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService index f8a11d8..0c8d28d 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -10,6 +10,7 @@ Bug(none) external/wpt/cookies/secure/set-from-wss.https.sub.html [ Failure ] Bug(none) external/wpt/css/css-fonts/font-display/font-display.html [ Failure Timeout ] Bug(none) external/wpt/html/browsers/offline/appcache/workers/appcache-worker.html [ Timeout ] +crbug.com/829417 external/wpt/html/browsers/offline/appcache/workers/appcache-worker.https.html [ Timeout ] Bug(none) external/wpt/service-workers/service-worker/claim-shared-worker-fetch.https.html [ Failure ] Bug(none) external/wpt/service-workers/service-worker/clients-get-client-types.https.html [ Failure ] crbug.com/807271 external/wpt/service-workers/service-worker/fetch-canvas-tainting-video-cache.https.html [ Failure ] @@ -89,3 +90,9 @@ crbug.com/825687 http/tests/devtools/websocket/websocket-handshake.js [ Failure ] crbug.com/816556 external/wpt/html/semantics/text-level-semantics/the-a-element/a-download-click-404.html [ Failure ] +crbug.com/816556 external/wpt/html/semantics/embedded-content/the-area-element/area-download-click.html [ Crash ] +crbug.com/816556 external/wpt/html/semantics/text-level-semantics/the-a-element/a-download-click.html [ Crash ] +crbug.com/816556 fast/dom/HTMLAnchorElement/anchor-download.html [ Crash ] +crbug.com/816556 fast/dom/HTMLAnchorElement/anchor-nodownload-set.html [ Crash ] +crbug.com/816556 fast/dom/HTMLAreaElement/area-download.html [ Crash ] +crbug.com/816556 http/tests/security/anchor-download-allow-blob.html [ Crash ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 85513a0..96557c5 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2286,6 +2286,11 @@ crbug.com/805463 external/wpt/acid/acid3/numbered-tests.html [ Skip ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001a.html [ Failure ] +crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002.html [ Failure ] +crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002a.html [ Failure ] +crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002b.html [ Failure ] +crbug.com/626703 external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001b.html [ Failure ] crbug.com/626703 [ Win7 ] external/wpt/css/css-fonts/variations/font-opentype-collections.html [ Timeout ] crbug.com/626703 external/wpt/html/editing/focus/focus-01.html [ Timeout ] crbug.com/626703 external/wpt/html/editing/dnd/the-datatransfer-interface/DataTransfer-types-manual.html [ Skip ] @@ -2906,7 +2911,7 @@ # Crashes with DCHECK enabled, but not on normal Release builds. crbug.com/809935 external/wpt/css/css-fonts/variations/font-style-interpolation.html [ Timeout ] -crbug.com/828748 external/wpt/css/css-fonts/variations/font-weight-lighter-bolder.html [ Pass Crash Failure ] +crbug.com/809956 external/wpt/css/css-fonts/variations/font-weight-lighter-bolder.html [ Failure ] crbug.com/626703 external/wpt/css/css-ui/text-overflow-011.html [ Failure Crash Pass ] crbug.com/626703 external/wpt/workers/opaque-origin.html [ Failure Crash Timeout ] crbug.com/626703 external/wpt/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-quirks-mode.html [ Pass Crash ] @@ -3348,6 +3353,11 @@ crbug.com/736177 [ Mac10.12 Retina ] tables/mozilla_expected_failures/core/captions2.html [ Failure Pass ] crbug.com/736177 [ Mac10.12 Retina ] virtual/prefer_compositing_to_lcd_text/compositing/overflow/theme-affects-visual-overflow.html [ Failure Pass ] crbug.com/736177 [ Mac10.12 Retina ] virtual/scalefactor200/fast/hidpi/static/validation-bubble-appearance-hidpi.html [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/gpu/fast/canvas/canvas-composite-shadow.html [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/gpu/fast/canvas/canvas-composite-video.html [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/gpu/fast/canvas/canvas-pattern-no-repeat-with-transformations.html [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/gpu/fast/canvas/fillrect_gradient.html [ Failure Pass ] +crbug.com/736177 [ Mac ] virtual/gpu/fast/canvas/canvas-composite-video-shadow.html [ Failure Pass ] crbug.com/734762 inspector-protocol/timeline/page-frames.js [ Failure ] @@ -3790,6 +3800,7 @@ # Test failing on WebKit Trusty crbug.com/829228 [ Linux Debug ] virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-backwards.html [ Failure ] +crbug.com/829228 [ Win7 Linux ] virtual/modern-media-controls/media/controls/modern/doubletap-to-jump-forwards-too-short.html [ Failure ] crbug.com/802915 css3/blending/isolation-should-include-non-local-background.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/accessibility/focusable-span.html b/third_party/WebKit/LayoutTests/accessibility/focusable-span.html new file mode 100644 index 0000000..419e8ea --- /dev/null +++ b/third_party/WebKit/LayoutTests/accessibility/focusable-span.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<script src="../resources/testharness.js"></script> +<script src="../resources/testharnessreport.js"></script> + +<p id="p"><span tabindex="0">hello</span>there</p> + +<script> +test(() => { + let axParagraph = accessibilityController.accessibleElementById('p'); + assert_not_equals(axParagraph, null); + let axSpan = axParagraph.childAtIndex(0); + assert_not_equals(axSpan, null); + assert_equals(axSpan.role, "AXRole: AXGenericContainer"); + assert_true(axSpan.isFocusable); +}, 'Ensure that spans with a tabindex get a focusable state.'); +</script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptor/gen-descriptor-device-disconnects-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptor/gen-descriptor-device-disconnects-before.html index 0ac5d73..31100c2 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptor/gen-descriptor-device-disconnects-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptor/gen-descriptor-device-disconnects-before.html
@@ -7,29 +7,20 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}], - optionalServices: [request_disconnection_service_uuid] - })) - .then(device => device.gatt.connect()) - .then(gattServer => { - let measurement_interval; - return gattServer.getPrimaryService('health_thermometer') - .then(ht => ht.getCharacteristic('measurement_interval')) - .then(mi => measurement_interval = mi) - .then(() => get_request_disconnection(gattServer)) - .then(requestDisconnection => requestDisconnection()) - .then( - () => assert_promise_rejects_with_message( - measurement_interval.getDescriptor(user_description.name), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve descriptors. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError'))); - }); -}, 'Device disconnects before getDescriptor. Reject with NetworkError.'); +const test_desc = 'Device disconnects before getDescriptor. ' + + 'Reject with NetworkError.'; +const expected = new DOMException( + 'GATT Server is disconnected. Cannot retrieve descriptors. (Re)connect ' + + 'first with `device.gatt.connect`.', + 'NetworkError'); +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => simulateGATTDisconnectionAndWait(device, fake_peripheral)) + .then(() => assert_promise_rejects_with_message( + characteristic.getDescriptor(user_description.name), + expected)), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptor/gen-descriptor-disconnect-called-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptor/gen-descriptor-disconnect-called-before.html index 9c08c8c..8fa4e59c 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptor/gen-descriptor-disconnect-called-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptor/gen-descriptor-disconnect-called-before.html
@@ -7,26 +7,21 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then( - () => requestDeviceWithTrustedClick( - {filters: [{services: ['health_thermometer']}]})) - .then(device => device.gatt.connect()) - .then(gattServer => { - return gattServer.getPrimaryService('health_thermometer') - .then(service => service.getCharacteristic('measurement_interval')) - .then(measurement_interval => { - gattServer.disconnect(); - return assert_promise_rejects_with_message( - measurement_interval.getDescriptor(user_description.name), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve descriptors. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - }); - }); -}, 'disconnect() called before getDescriptor. Reject with NetworkError.'); +const test_desc = 'disconnect() called before getDescriptor. ' + + 'Reject with NetworkError.'; +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'retrieve descriptors. (Re)connect first with `device.gatt.connect`.', + 'NetworkError'); +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => { + device.gatt.disconnect(); + return assert_promise_rejects_with_message( + characteristic.getDescriptor(user_description.name), + expected); + }), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-device-disconnects-before-with-uuid.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-device-disconnects-before-with-uuid.html index 99e03927..d918e0e 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-device-disconnects-before-with-uuid.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-device-disconnects-before-with-uuid.html
@@ -7,29 +7,20 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}], - optionalServices: [request_disconnection_service_uuid] - })) - .then(device => device.gatt.connect()) - .then(gattServer => { - let measurement_interval; - return gattServer.getPrimaryService('health_thermometer') - .then(ht => ht.getCharacteristic('measurement_interval')) - .then(mi => measurement_interval = mi) - .then(() => get_request_disconnection(gattServer)) - .then(requestDisconnection => requestDisconnection()) - .then( - () => assert_promise_rejects_with_message( - measurement_interval.getDescriptors(user_description.name), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve descriptors. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError'))); - }); -}, 'Device disconnects before getDescriptors. Reject with NetworkError.'); +const test_desc = 'Device disconnects before getDescriptors. ' + + 'Reject with NetworkError.'; +const expected = new DOMException( + 'GATT Server is disconnected. Cannot retrieve descriptors. (Re)connect ' + + 'first with `device.gatt.connect`.', + 'NetworkError'); +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => simulateGATTDisconnectionAndWait(device, fake_peripheral)) + .then(() => assert_promise_rejects_with_message( + characteristic.getDescriptors(user_description.name), + expected)), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-device-disconnects-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-device-disconnects-before.html index 0493e3a1..a67e0cbe 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-device-disconnects-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-device-disconnects-before.html
@@ -7,29 +7,20 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}], - optionalServices: [request_disconnection_service_uuid] - })) - .then(device => device.gatt.connect()) - .then(gattServer => { - let measurement_interval; - return gattServer.getPrimaryService('health_thermometer') - .then(ht => ht.getCharacteristic('measurement_interval')) - .then(mi => measurement_interval = mi) - .then(() => get_request_disconnection(gattServer)) - .then(requestDisconnection => requestDisconnection()) - .then( - () => assert_promise_rejects_with_message( - measurement_interval.getDescriptors(), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve descriptors. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError'))); - }); -}, 'Device disconnects before getDescriptors. Reject with NetworkError.'); +const test_desc = 'Device disconnects before getDescriptors. ' + + 'Reject with NetworkError.'; +const expected = new DOMException( + 'GATT Server is disconnected. Cannot retrieve descriptors. (Re)connect ' + + 'first with `device.gatt.connect`.', + 'NetworkError'); +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => simulateGATTDisconnectionAndWait(device, fake_peripheral)) + .then(() => assert_promise_rejects_with_message( + characteristic.getDescriptors(), + expected)), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-disconnect-called-before-with-uuid.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-disconnect-called-before-with-uuid.html index a4250319..b1e18fa 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-disconnect-called-before-with-uuid.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-disconnect-called-before-with-uuid.html
@@ -7,26 +7,21 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then( - () => requestDeviceWithTrustedClick( - {filters: [{services: ['health_thermometer']}]})) - .then(device => device.gatt.connect()) - .then(gattServer => { - return gattServer.getPrimaryService('health_thermometer') - .then(service => service.getCharacteristic('measurement_interval')) - .then(measurement_interval => { - gattServer.disconnect(); - return assert_promise_rejects_with_message( - measurement_interval.getDescriptors(user_description.name), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve descriptors. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - }); - }); -}, 'disconnect() called before getDescriptors. Reject with NetworkError.'); +const test_desc = 'disconnect() called before getDescriptors. ' + + 'Reject with NetworkError.'; +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'retrieve descriptors. (Re)connect first with `device.gatt.connect`.', + 'NetworkError'); +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => { + device.gatt.disconnect(); + return assert_promise_rejects_with_message( + characteristic.getDescriptors(user_description.name), + expected); + }), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-disconnect-called-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-disconnect-called-before.html index c4f2ba69..49eebaf 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-disconnect-called-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/getDescriptors/gen-descriptor-disconnect-called-before.html
@@ -7,26 +7,21 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then( - () => requestDeviceWithTrustedClick( - {filters: [{services: ['health_thermometer']}]})) - .then(device => device.gatt.connect()) - .then(gattServer => { - return gattServer.getPrimaryService('health_thermometer') - .then(service => service.getCharacteristic('measurement_interval')) - .then(measurement_interval => { - gattServer.disconnect(); - return assert_promise_rejects_with_message( - measurement_interval.getDescriptors(), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve descriptors. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - }); - }); -}, 'disconnect() called before getDescriptors. Reject with NetworkError.'); +const test_desc = 'disconnect() called before getDescriptors. ' + + 'Reject with NetworkError.'; +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'retrieve descriptors. (Re)connect first with `device.gatt.connect`.', + 'NetworkError'); +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => { + device.gatt.disconnect(); + return assert_promise_rejects_with_message( + characteristic.getDescriptors(), + expected); + }), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/notifications/start-stop-start-stop.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/notifications/start-stop-start-stop.html index 7a0090d..c6a924c 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/notifications/start-stop-start-stop.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/notifications/start-stop-start-stop.html
@@ -6,20 +6,26 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - return setBluetoothFakeAdapter('HeartRateAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['heart_rate']}]})) - .then(device => device.gatt.connect()) - .then(gattServer => gattServer.getPrimaryService('heart_rate')) - .then(service => service.getCharacteristic('heart_rate_measurement')) - .then(characteristic => { - return characteristic.startNotifications() - .then(() => characteristic.stopNotifications()) - .then(() => characteristic.startNotifications()) - .then(() => characteristic.stopNotifications()); - }); - // TODO(ortuno): Assert that notifications are not active. - // http://crbug.com/600762 -}, 'Start -> stop -> start -> stop.'); +const test_desc = 'The characteristic should be able to start and stop ' + + 'notifications multiple times in a row.'; +let characteristic, fake_characteristic; +let startStopNotifications = () => { + return fake_characteristic.setNextSubscribeToNotificationsResponse( + HCI_SUCCESS) + .then(() => characteristic.startNotifications()) + .then(() => fake_characteristic.isNotifying()) + .then(isNotifying => assert_true(isNotifying)) + .then(() => + fake_characteristic.setNextUnsubscribeFromNotificationsResponse( + HCI_SUCCESS)) + .then(() => characteristic.stopNotifications()) + .then(() => fake_characteristic.isNotifying()) + .then(isNotifying => assert_false(isNotifying)); +} + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({characteristic, fake_characteristic} = _)) + .then(() => startStopNotifications()) + .then(() => startStopNotifications()), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/readValue/gen-gatt-op-device-disconnects-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/readValue/gen-gatt-op-device-disconnects-before.html index d48fdb8..2e5d16b 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/readValue/gen-gatt-op-device-disconnects-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/readValue/gen-gatt-op-device-disconnects-before.html
@@ -7,28 +7,19 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}], - optionalServices: [request_disconnection_service_uuid] - })) - .then(device => device.gatt.connect()) - .then(gattServer => { - let measurement_interval; - return gattServer.getPrimaryService('health_thermometer') - .then(ht=> ht.getCharacteristic('measurement_interval')) - .then(mi => measurement_interval = mi) - .then(() => get_request_disconnection(gattServer)) - .then(requestDisconnection => requestDisconnection()) - .then(() => assert_promise_rejects_with_message( - measurement_interval.readValue(), - new DOMException( - 'GATT Server is disconnected. Cannot perform GATT operations. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError'))); - }); -}, 'Device disconnects before readValue. Reject with NetworkError.'); +const test_desc = 'Device disconnects before readValue. ' + + 'Reject with NetworkError.'; +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'perform GATT operations. (Re)connect first with `device.gatt.connect`.', + 'NetworkError') +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => simulateGATTDisconnectionAndWait(device, fake_peripheral)) + .then(() => assert_promise_rejects_with_message( + characteristic.readValue(), + expected)), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/readValue/gen-gatt-op-disconnect-called-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/readValue/gen-gatt-op-disconnect-called-before.html index 116a778..4b8e541 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/readValue/gen-gatt-op-disconnect-called-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/readValue/gen-gatt-op-disconnect-called-before.html
@@ -7,25 +7,22 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}]})) - .then(device => device.gatt.connect()) - .then(gattServer => { - return gattServer.getPrimaryService('health_thermometer') - .then(service => service.getCharacteristic('measurement_interval')) - .then(measurement_interval => { - gattServer.disconnect(); - return assert_promise_rejects_with_message( - measurement_interval.readValue(), - new DOMException( - 'GATT Server is disconnected. Cannot perform GATT operations. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - }); - }); -}, 'disconnect() called before readValue. Reject with NetworkError.'); +const test_desc = 'disconnect() called before readValue. ' + + 'Reject with NetworkError.'; +const value = new Uint8Array([1]); +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'perform GATT operations. (Re)connect first with `device.gatt.connect`.', + 'NetworkError') +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => { + device.gatt.disconnect(); + return assert_promise_rejects_with_message( + characteristic.readValue(), + expected); + }), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/startNotifications/gen-gatt-op-device-disconnects-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/startNotifications/gen-gatt-op-device-disconnects-before.html index 9e59e33..d7fb360 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/startNotifications/gen-gatt-op-device-disconnects-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/startNotifications/gen-gatt-op-device-disconnects-before.html
@@ -7,28 +7,19 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}], - optionalServices: [request_disconnection_service_uuid] - })) - .then(device => device.gatt.connect()) - .then(gattServer => { - let measurement_interval; - return gattServer.getPrimaryService('health_thermometer') - .then(ht=> ht.getCharacteristic('measurement_interval')) - .then(mi => measurement_interval = mi) - .then(() => get_request_disconnection(gattServer)) - .then(requestDisconnection => requestDisconnection()) - .then(() => assert_promise_rejects_with_message( - measurement_interval.startNotifications(), - new DOMException( - 'GATT Server is disconnected. Cannot perform GATT operations. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError'))); - }); -}, 'Device disconnects before startNotifications. Reject with NetworkError.'); +const test_desc = 'Device disconnects before startNotifications. ' + + 'Reject with NetworkError.'; +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'perform GATT operations. (Re)connect first with `device.gatt.connect`.', + 'NetworkError') +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => simulateGATTDisconnectionAndWait(device, fake_peripheral)) + .then(() => assert_promise_rejects_with_message( + characteristic.startNotifications(), + expected)), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/startNotifications/gen-gatt-op-disconnect-called-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/startNotifications/gen-gatt-op-disconnect-called-before.html index de76b6a..39873b4 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/startNotifications/gen-gatt-op-disconnect-called-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/startNotifications/gen-gatt-op-disconnect-called-before.html
@@ -7,25 +7,22 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}]})) - .then(device => device.gatt.connect()) - .then(gattServer => { - return gattServer.getPrimaryService('health_thermometer') - .then(service => service.getCharacteristic('measurement_interval')) - .then(measurement_interval => { - gattServer.disconnect(); - return assert_promise_rejects_with_message( - measurement_interval.startNotifications(), - new DOMException( - 'GATT Server is disconnected. Cannot perform GATT operations. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - }); - }); -}, 'disconnect() called before startNotifications. Reject with NetworkError.'); +const test_desc = 'disconnect() called before startNotifications. ' + + 'Reject with NetworkError.'; +const value = new Uint8Array([1]); +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'perform GATT operations. (Re)connect first with `device.gatt.connect`.', + 'NetworkError') +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => { + device.gatt.disconnect(); + return assert_promise_rejects_with_message( + characteristic.startNotifications(), + expected); + }), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/stopNotifications/gen-gatt-op-device-disconnects-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/stopNotifications/gen-gatt-op-device-disconnects-before.html index cd29be37..b07c3fc4e 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/stopNotifications/gen-gatt-op-device-disconnects-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/stopNotifications/gen-gatt-op-device-disconnects-before.html
@@ -7,28 +7,19 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}], - optionalServices: [request_disconnection_service_uuid] - })) - .then(device => device.gatt.connect()) - .then(gattServer => { - let measurement_interval; - return gattServer.getPrimaryService('health_thermometer') - .then(ht=> ht.getCharacteristic('measurement_interval')) - .then(mi => measurement_interval = mi) - .then(() => get_request_disconnection(gattServer)) - .then(requestDisconnection => requestDisconnection()) - .then(() => assert_promise_rejects_with_message( - measurement_interval.stopNotifications(), - new DOMException( - 'GATT Server is disconnected. Cannot perform GATT operations. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError'))); - }); -}, 'Device disconnects before stopNotifications. Reject with NetworkError.'); +const test_desc = 'Device disconnects before stopNotifications. ' + + 'Reject with NetworkError.'; +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'perform GATT operations. (Re)connect first with `device.gatt.connect`.', + 'NetworkError') +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => simulateGATTDisconnectionAndWait(device, fake_peripheral)) + .then(() => assert_promise_rejects_with_message( + characteristic.stopNotifications(), + expected)), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/stopNotifications/gen-gatt-op-disconnect-called-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/stopNotifications/gen-gatt-op-disconnect-called-before.html index 8363837..99cf7ee 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/stopNotifications/gen-gatt-op-disconnect-called-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/stopNotifications/gen-gatt-op-disconnect-called-before.html
@@ -7,25 +7,22 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}]})) - .then(device => device.gatt.connect()) - .then(gattServer => { - return gattServer.getPrimaryService('health_thermometer') - .then(service => service.getCharacteristic('measurement_interval')) - .then(measurement_interval => { - gattServer.disconnect(); - return assert_promise_rejects_with_message( - measurement_interval.stopNotifications(), - new DOMException( - 'GATT Server is disconnected. Cannot perform GATT operations. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - }); - }); -}, 'disconnect() called before stopNotifications. Reject with NetworkError.'); +const test_desc = 'disconnect() called before stopNotifications. ' + + 'Reject with NetworkError.'; +const value = new Uint8Array([1]); +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'perform GATT operations. (Re)connect first with `device.gatt.connect`.', + 'NetworkError') +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => { + device.gatt.disconnect(); + return assert_promise_rejects_with_message( + characteristic.stopNotifications(), + expected); + }), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/writeValue/gen-gatt-op-device-disconnects-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/writeValue/gen-gatt-op-device-disconnects-before.html index b3281161..74d6bba 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/writeValue/gen-gatt-op-device-disconnects-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/writeValue/gen-gatt-op-device-disconnects-before.html
@@ -7,28 +7,19 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}], - optionalServices: [request_disconnection_service_uuid] - })) - .then(device => device.gatt.connect()) - .then(gattServer => { - let measurement_interval; - return gattServer.getPrimaryService('health_thermometer') - .then(ht=> ht.getCharacteristic('measurement_interval')) - .then(mi => measurement_interval = mi) - .then(() => get_request_disconnection(gattServer)) - .then(requestDisconnection => requestDisconnection()) - .then(() => assert_promise_rejects_with_message( - measurement_interval.writeValue(val), - new DOMException( - 'GATT Server is disconnected. Cannot perform GATT operations. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError'))); - }); -}, 'Device disconnects before writeValue. Reject with NetworkError.'); +const test_desc = 'Device disconnects before writeValue. ' + + 'Reject with NetworkError.'; +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'perform GATT operations. (Re)connect first with `device.gatt.connect`.', + 'NetworkError') +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => simulateGATTDisconnectionAndWait(device, fake_peripheral)) + .then(() => assert_promise_rejects_with_message( + characteristic.writeValue(new Uint8Array(1 /*length */)), + expected)), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/characteristic/writeValue/gen-gatt-op-disconnect-called-before.html b/third_party/WebKit/LayoutTests/bluetooth/characteristic/writeValue/gen-gatt-op-disconnect-called-before.html index 80f1435..6db99d2 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/characteristic/writeValue/gen-gatt-op-disconnect-called-before.html +++ b/third_party/WebKit/LayoutTests/bluetooth/characteristic/writeValue/gen-gatt-op-disconnect-called-before.html
@@ -7,25 +7,22 @@ <script src="../../../external/wpt/bluetooth/resources/bluetooth-helpers.js"></script> <script> 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}]})) - .then(device => device.gatt.connect()) - .then(gattServer => { - return gattServer.getPrimaryService('health_thermometer') - .then(service => service.getCharacteristic('measurement_interval')) - .then(measurement_interval => { - gattServer.disconnect(); - return assert_promise_rejects_with_message( - measurement_interval.writeValue(val), - new DOMException( - 'GATT Server is disconnected. Cannot perform GATT operations. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - }); - }); -}, 'disconnect() called before writeValue. Reject with NetworkError.'); +const test_desc = 'disconnect() called before writeValue. ' + + 'Reject with NetworkError.'; +const value = new Uint8Array([1]); +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'perform GATT operations. (Re)connect first with `device.gatt.connect`.', + 'NetworkError') +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => { + device.gatt.disconnect(); + return assert_promise_rejects_with_message( + characteristic.writeValue(value), + expected); + }), + test_desc); </script>
diff --git a/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/descriptor-device-disconnects-before.js b/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/descriptor-device-disconnects-before.js index 11dac5d..08ab868 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/descriptor-device-disconnects-before.js +++ b/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/descriptor-device-disconnects-before.js
@@ -1,28 +1,20 @@ 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}], - optionalServices: [request_disconnection_service_uuid] - })) - .then(device => device.gatt.connect()) - .then(gattServer => { - let measurement_interval; - return gattServer.getPrimaryService('health_thermometer') - .then(ht => ht.getCharacteristic('measurement_interval')) - .then(mi => measurement_interval = mi) - .then(() => get_request_disconnection(gattServer)) - .then(requestDisconnection => requestDisconnection()) - .then( - () => assert_promise_rejects_with_message( - measurement_interval.CALLS( - [getDescriptor(user_description.name) | - getDescriptors(user_description.name)[UUID] | - getDescriptors()]), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve descriptors. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError'))); - }); -}, 'Device disconnects before FUNCTION_NAME. Reject with NetworkError.'); +const test_desc = 'Device disconnects before FUNCTION_NAME. ' + + 'Reject with NetworkError.'; +const expected = new DOMException( + 'GATT Server is disconnected. Cannot retrieve descriptors. (Re)connect ' + + 'first with `device.gatt.connect`.', + 'NetworkError'); +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => simulateGATTDisconnectionAndWait(device, fake_peripheral)) + .then(() => assert_promise_rejects_with_message( + characteristic.CALLS([ + getDescriptor(user_description.name) | + getDescriptors(user_description.name)[UUID] | + getDescriptors() + ]), + expected)), + test_desc);
diff --git a/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/descriptor-disconnect-called-before.js b/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/descriptor-disconnect-called-before.js index 974f437..bacf0d91 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/descriptor-disconnect-called-before.js +++ b/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/descriptor-disconnect-called-before.js
@@ -1,25 +1,21 @@ 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then( - () => requestDeviceWithTrustedClick( - {filters: [{services: ['health_thermometer']}]})) - .then(device => device.gatt.connect()) - .then(gattServer => { - return gattServer.getPrimaryService('health_thermometer') - .then(service => service.getCharacteristic('measurement_interval')) - .then(measurement_interval => { - gattServer.disconnect(); - return assert_promise_rejects_with_message( - measurement_interval.CALLS( - [getDescriptor(user_description.name) | - getDescriptors(user_description.name)[UUID] | - getDescriptors()]), - new DOMException( - 'GATT Server is disconnected. Cannot retrieve descriptors. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - }); - }); -}, 'disconnect() called before FUNCTION_NAME. Reject with NetworkError.'); +const test_desc = 'disconnect() called before FUNCTION_NAME. ' + + 'Reject with NetworkError.'; +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'retrieve descriptors. (Re)connect first with `device.gatt.connect`.', + 'NetworkError'); +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => { + device.gatt.disconnect(); + return assert_promise_rejects_with_message( + characteristic.CALLS([ + getDescriptor(user_description.name) | + getDescriptors(user_description.name)[UUID] | + getDescriptors() + ]), + expected); + }), + test_desc);
diff --git a/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/gatt-op-device-disconnects-before.js b/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/gatt-op-device-disconnects-before.js index 965fbad..12f7a9b 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/gatt-op-device-disconnects-before.js +++ b/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/gatt-op-device-disconnects-before.js
@@ -1,28 +1,20 @@ 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}], - optionalServices: [request_disconnection_service_uuid] - })) - .then(device => device.gatt.connect()) - .then(gattServer => { - let measurement_interval; - return gattServer.getPrimaryService('health_thermometer') - .then(ht=> ht.getCharacteristic('measurement_interval')) - .then(mi => measurement_interval = mi) - .then(() => get_request_disconnection(gattServer)) - .then(requestDisconnection => requestDisconnection()) - .then(() => assert_promise_rejects_with_message( - measurement_interval.CALLS([ +const test_desc = 'Device disconnects before FUNCTION_NAME. ' + + 'Reject with NetworkError.'; +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'perform GATT operations. (Re)connect first with `device.gatt.connect`.', + 'NetworkError') +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => simulateGATTDisconnectionAndWait(device, fake_peripheral)) + .then(() => assert_promise_rejects_with_message( + characteristic.CALLS([ readValue()| - writeValue(val)| + writeValue(new Uint8Array(1 /*length */))| startNotifications()| - stopNotifications()]), - new DOMException( - 'GATT Server is disconnected. Cannot perform GATT operations. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError'))); - }); -}, 'Device disconnects before FUNCTION_NAME. Reject with NetworkError.'); + stopNotifications() + ]), + expected)), + test_desc);
diff --git a/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/gatt-op-disconnect-called-before.js b/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/gatt-op-disconnect-called-before.js index ef99764..fedf712 100644 --- a/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/gatt-op-disconnect-called-before.js +++ b/third_party/WebKit/LayoutTests/bluetooth/script-tests/characteristic/gatt-op-disconnect-called-before.js
@@ -1,25 +1,23 @@ 'use strict'; -bluetooth_test(() => { - let val = new Uint8Array([1]); - return setBluetoothFakeAdapter('DisconnectingHealthThermometerAdapter') - .then(() => requestDeviceWithTrustedClick({ - filters: [{services: ['health_thermometer']}]})) - .then(device => device.gatt.connect()) - .then(gattServer => { - return gattServer.getPrimaryService('health_thermometer') - .then(service => service.getCharacteristic('measurement_interval')) - .then(measurement_interval => { - gattServer.disconnect(); - return assert_promise_rejects_with_message( - measurement_interval.CALLS([ - readValue()| - writeValue(val)| - startNotifications()| - stopNotifications()]), - new DOMException( - 'GATT Server is disconnected. Cannot perform GATT operations. ' + - '(Re)connect first with `device.gatt.connect`.', - 'NetworkError')); - }); - }); -}, 'disconnect() called before FUNCTION_NAME. Reject with NetworkError.'); +const test_desc = 'disconnect() called before FUNCTION_NAME. ' + + 'Reject with NetworkError.'; +const value = new Uint8Array([1]); +const expected = new DOMException('GATT Server is disconnected. Cannot ' + + 'perform GATT operations. (Re)connect first with `device.gatt.connect`.', + 'NetworkError') +let device, characteristic, fake_peripheral; + +bluetooth_test(() => getMeasurementIntervalCharacteristic() + .then(_ => ({device, characteristic, fake_peripheral} = _)) + .then(() => { + device.gatt.disconnect(); + return assert_promise_rejects_with_message( + characteristic.CALLS([ + readValue()| + writeValue(value)| + startNotifications()| + stopNotifications() + ]), + expected); + }), + test_desc);
diff --git a/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins-expected.html b/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins-expected.html new file mode 100644 index 0000000..3c5ef2a --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins-expected.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<style> + .bordered { + margin: auto; + margin-top: -40px; + width: 260px; + height: 260px; + background-color: red; + background-image: linear-gradient(green, green); + border: 40px solid green; + } +</style> +<div id="spacer" style="height: 100px; width: 100px;"></div> +<!-- Test should show no red background color around the gradient. --> +<div class="bordered"></div>
diff --git a/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins.html b/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins.html new file mode 100644 index 0000000..9b6fb5be --- /dev/null +++ b/third_party/WebKit/LayoutTests/css3/background/background-border-image-auto-margins.html
@@ -0,0 +1,15 @@ +<!DOCTYPE html> +<style> + .bordered { + margin: auto; + width: 200px; + height: 200px; + background-color: red; + background-image: linear-gradient(green, green); + border: 30px solid red; + border-image: repeat stretch 40 / 40px / 40px linear-gradient(green, green); + } +</style> +<div id="spacer" style="height: 100px; width: 100px;"></div> +<!-- Test should show no red background color around the gradient. --> +<div class="bordered"></div>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index bcb1087..bf8e4e04 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -5137,6 +5137,30 @@ {} ] ], + "pointerevents/extension/pointerevent_touch-action-pan-down-css_touch-manual.html": [ + [ + "/pointerevents/extension/pointerevent_touch-action-pan-down-css_touch-manual.html", + {} + ] + ], + "pointerevents/extension/pointerevent_touch-action-pan-left-css_touch-manual.html": [ + [ + "/pointerevents/extension/pointerevent_touch-action-pan-left-css_touch-manual.html", + {} + ] + ], + "pointerevents/extension/pointerevent_touch-action-pan-right-css_touch-manual.html": [ + [ + "/pointerevents/extension/pointerevent_touch-action-pan-right-css_touch-manual.html", + {} + ] + ], + "pointerevents/extension/pointerevent_touch-action-pan-up-css_touch-manual.html": [ + [ + "/pointerevents/extension/pointerevent_touch-action-pan-up-css_touch-manual.html", + {} + ] + ], "pointerevents/html/pointerevent_drag_interaction-manual.html": [ [ "/pointerevents/html/pointerevent_drag_interaction-manual.html", @@ -5431,30 +5455,6 @@ {} ] ], - "pointerevents/pointerevent_touch-action-pan-down-css_touch-manual.html": [ - [ - "/pointerevents/pointerevent_touch-action-pan-down-css_touch-manual.html", - {} - ] - ], - "pointerevents/pointerevent_touch-action-pan-left-css_touch-manual.html": [ - [ - "/pointerevents/pointerevent_touch-action-pan-left-css_touch-manual.html", - {} - ] - ], - "pointerevents/pointerevent_touch-action-pan-right-css_touch-manual.html": [ - [ - "/pointerevents/pointerevent_touch-action-pan-right-css_touch-manual.html", - {} - ] - ], - "pointerevents/pointerevent_touch-action-pan-up-css_touch-manual.html": [ - [ - "/pointerevents/pointerevent_touch-action-pan-up-css_touch-manual.html", - {} - ] - ], "pointerevents/pointerevent_touch-action-pan-x-css_touch-manual.html": [ [ "/pointerevents/pointerevent_touch-action-pan-x-css_touch-manual.html", @@ -48535,6 +48535,18 @@ {} ] ], + "css/css-scoping/shadow-reassign-dynamic-001.html": [ + [ + "/css/css-scoping/shadow-reassign-dynamic-001.html", + [ + [ + "/css/css-scoping/reference/green-box.html", + "==" + ] + ], + {} + ] + ], "css/css-scoping/shadow-root-insert-into-document.html": [ [ "/css/css-scoping/shadow-root-insert-into-document.html", @@ -83579,6 +83591,18 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001a.xhtml": [ [ "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001a.xhtml", @@ -84491,6 +84515,54 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001a.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001a.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001b.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001b.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002a.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002a.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002-ref.html", + "==" + ] + ], + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002b.html": [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002b.html", + [ + [ + "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002-ref.html", + "==" + ] + ], + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-flow-001.html": [ [ "/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-flow-001.html", @@ -100517,6 +100589,11 @@ {} ] ], + "content-security-policy/support/file-prefetch-allowed.html": [ + [ + {} + ] + ], "content-security-policy/support/fonts.css": [ [ {} @@ -116917,6 +116994,11 @@ {} ] ], + "css/css-fonts/variations/font-shorthand-expected.txt": [ + [ + {} + ] + ], "css/css-fonts/variations/font-stretch-expected.txt": [ [ {} @@ -116932,6 +117014,11 @@ {} ] ], + "css/css-fonts/variations/font-weight-parsing-expected.txt": [ + [ + {} + ] + ], "css/css-fonts/variations/resources/ahem.ttc": [ [ {} @@ -119102,6 +119189,11 @@ {} ] ], + "css/css-shadow-parts/support/shadow-helper.js": [ + [ + {} + ] + ], "css/css-shapes/OWNERS": [ [ {} @@ -125482,6 +125574,21 @@ {} ] ], + "css/css-typed-om/the-stylepropertymap/properties/grid-expected.txt": [ + [ + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-gap-expected.txt": [ + [ + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-template-expected.txt": [ + [ + {} + ] + ], "css/css-typed-om/the-stylepropertymap/properties/image-rendering-expected.txt": [ [ {} @@ -129947,6 +130054,11 @@ {} ] ], + "css/cssom-view/cssom-getBoxQuads-001-expected.txt": [ + [ + {} + ] + ], "css/cssom-view/cssom-getClientRects-002-expected.txt": [ [ {} @@ -132972,6 +133084,11 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002-ref.html": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001-ref.xhtml": [ [ {} @@ -133272,6 +133389,16 @@ {} ] ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001-ref.html": [ + [ + {} + ] + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002-ref.html": [ + [ + {} + ] + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-flow-001-ref.html": [ [ {} @@ -133927,6 +134054,11 @@ {} ] ], + "custom-elements/HTMLElement-constructor-expected.txt": [ + [ + {} + ] + ], "custom-elements/OWNERS": [ [ {} @@ -133947,6 +134079,11 @@ {} ] ], + "custom-elements/htmlconstructor/newtarget-expected.txt": [ + [ + {} + ] + ], "custom-elements/parser/parser-uses-registry-of-owner-document-expected.txt": [ [ {} @@ -140377,6 +140514,11 @@ {} ] ], + "html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext-subframe.txt": [ + [ + {} + ] + ], "html/dom/elements-embedded.js": [ [ {} @@ -146522,6 +146664,11 @@ {} ] ], + "html/semantics/document-metadata/the-link-element/resources/link-rel-attribute.css": [ + [ + {} + ] + ], "html/semantics/document-metadata/the-link-element/resources/stylesheet.css": [ [ {} @@ -151407,6 +151554,11 @@ {} ] ], + "infrastructure/testdriver/send_keys-expected.txt": [ + [ + {} + ] + ], "innerText/OWNERS": [ [ {} @@ -161297,11 +161449,6 @@ {} ] ], - "url/urlsearchparams-foreach-expected.txt": [ - [ - {} - ] - ], "url/urltestdata.json": [ [ {} @@ -161602,11 +161749,6 @@ {} ] ], - "web-animations/interfaces/Document/getAnimations-expected.txt": [ - [ - {} - ] - ], "web-animations/interfaces/KeyframeEffect/constructor-expected.txt": [ [ {} @@ -166332,6 +166474,11 @@ {} ] ], + "xhr/resources/header-user-agent.py": [ + [ + {} + ] + ], "xhr/resources/headers-basic.asis": [ [ {} @@ -177124,13 +177271,17 @@ "content-security-policy/navigate-to/child-navigates-parent-allowed.html": [ [ "/content-security-policy/navigate-to/child-navigates-parent-allowed.html", - {} + { + "timeout": "long" + } ] ], "content-security-policy/navigate-to/child-navigates-parent-blocked.html": [ [ "/content-security-policy/navigate-to/child-navigates-parent-blocked.html", - {} + { + "timeout": "long" + } ] ], "content-security-policy/navigate-to/form-action/form-action-allows-navigate-to-allows.html": [ @@ -177232,37 +177383,49 @@ "content-security-policy/navigate-to/link-click-allowed.html": [ [ "/content-security-policy/navigate-to/link-click-allowed.html", - {} + { + "timeout": "long" + } ] ], "content-security-policy/navigate-to/link-click-blocked.html": [ [ "/content-security-policy/navigate-to/link-click-blocked.html", - {} + { + "timeout": "long" + } ] ], "content-security-policy/navigate-to/link-click-cross-origin-allowed.sub.html": [ [ "/content-security-policy/navigate-to/link-click-cross-origin-allowed.sub.html", - {} + { + "timeout": "long" + } ] ], "content-security-policy/navigate-to/link-click-cross-origin-blocked.sub.html": [ [ "/content-security-policy/navigate-to/link-click-cross-origin-blocked.sub.html", - {} + { + "timeout": "long" + } ] ], "content-security-policy/navigate-to/link-click-redirected-allowed.html": [ [ "/content-security-policy/navigate-to/link-click-redirected-allowed.html", - {} + { + "timeout": "long" + } ] ], "content-security-policy/navigate-to/link-click-redirected-blocked.sub.html": [ [ "/content-security-policy/navigate-to/link-click-redirected-blocked.sub.html", - {} + { + "timeout": "long" + } ] ], "content-security-policy/navigate-to/meta-refresh-allowed.html": [ @@ -181675,6 +181838,12 @@ {} ] ], + "css/css-multicol/going-out-of-flow-after-spanner.html": [ + [ + "/css/css-multicol/going-out-of-flow-after-spanner.html", + {} + ] + ], "css/css-multicol/multicol-gap-animation-001.html": [ [ "/css/css-multicol/multicol-gap-animation-001.html", @@ -182053,6 +182222,54 @@ {} ] ], + "css/css-shadow-parts/all-hosts.html": [ + [ + "/css/css-shadow-parts/all-hosts.html", + {} + ] + ], + "css/css-shadow-parts/chaining-invalid-selector.html": [ + [ + "/css/css-shadow-parts/chaining-invalid-selector.html", + {} + ] + ], + "css/css-shadow-parts/complex-matching.html": [ + [ + "/css/css-shadow-parts/complex-matching.html", + {} + ] + ], + "css/css-shadow-parts/complex-non-matching.html": [ + [ + "/css/css-shadow-parts/complex-non-matching.html", + {} + ] + ], + "css/css-shadow-parts/different-host.html": [ + [ + "/css/css-shadow-parts/different-host.html", + {} + ] + ], + "css/css-shadow-parts/host-stylesheet.html": [ + [ + "/css/css-shadow-parts/host-stylesheet.html", + {} + ] + ], + "css/css-shadow-parts/inner-host.html": [ + [ + "/css/css-shadow-parts/inner-host.html", + {} + ] + ], + "css/css-shadow-parts/simple.html": [ + [ + "/css/css-shadow-parts/simple.html", + {} + ] + ], "css/css-shapes/basic-shape-circle-ellipse-serialization.html": [ [ "/css/css-shapes/basic-shape-circle-ellipse-serialization.html", @@ -185257,6 +185474,60 @@ {} ] ], + "css/css-typed-om/the-stylepropertymap/properties/grid-area.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/grid-area.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-auto-columns-rows.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/grid-auto-columns-rows.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-auto-flow.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/grid-auto-flow.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-gap.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/grid-gap.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-start-end.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/grid-start-end.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-template-areas.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/grid-template-areas.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-template-columns-rows.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/grid-template-columns-rows.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-template.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/grid-template.html", + {} + ] + ], + "css/css-typed-om/the-stylepropertymap/properties/grid.html": [ + [ + "/css/css-typed-om/the-stylepropertymap/properties/grid.html", + {} + ] + ], "css/css-typed-om/the-stylepropertymap/properties/height.html": [ [ "/css/css-typed-om/the-stylepropertymap/properties/height.html", @@ -186409,6 +186680,12 @@ {} ] ], + "css/cssom-view/cssom-getBoxQuads-001.html": [ + [ + "/css/cssom-view/cssom-getBoxQuads-001.html", + {} + ] + ], "css/cssom-view/cssom-getClientRects-002.html": [ [ "/css/cssom-view/cssom-getClientRects-002.html", @@ -196693,6 +196970,12 @@ {} ] ], + "html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext.window.js": [ + [ + "/html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext.window.html", + {} + ] + ], "html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument.window.js": [ [ "/html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument.window.html", @@ -197649,6 +197932,12 @@ {} ] ], + "html/semantics/document-metadata/the-link-element/link-rel-attribute.html": [ + [ + "/html/semantics/document-metadata/the-link-element/link-rel-attribute.html", + {} + ] + ], "html/semantics/document-metadata/the-link-element/link-rellist.html": [ [ "/html/semantics/document-metadata/the-link-element/link-rellist.html", @@ -218195,6 +218484,12 @@ {} ] ], + "pointerevents/extension/pointerevent_touch-action-verification.html": [ + [ + "/pointerevents/extension/pointerevent_touch-action-verification.html", + {} + ] + ], "pointerevents/idlharness.html": [ [ "/pointerevents/idlharness.html", @@ -237055,6 +237350,12 @@ {} ] ], + "workers/interfaces/WorkerUtils/WindowTimers/005.html": [ + [ + "/workers/interfaces/WorkerUtils/WindowTimers/005.html", + {} + ] + ], "workers/interfaces/WorkerUtils/importScripts/001.worker.js": [ [ "/workers/interfaces/WorkerUtils/importScripts/001.worker.html", @@ -238187,6 +238488,18 @@ {} ] ], + "xhr/header-user-agent-async.htm": [ + [ + "/xhr/header-user-agent-async.htm", + {} + ] + ], + "xhr/header-user-agent-sync.htm": [ + [ + "/xhr/header-user-agent-sync.htm", + {} + ] + ], "xhr/headers-normalize-response.htm": [ [ "/xhr/headers-normalize-response.htm", @@ -252677,19 +252990,19 @@ "testharness" ], "bluetooth/device/gattserverdisconnected-event/disconnected.https.html": [ - "ee14803683f17133c6147c2eaf250befbaaf0be1", + "709429f27f57c27319fd14bf419dca46e5f8cee8", "testharness" ], "bluetooth/device/gattserverdisconnected-event/disconnected_gc.https.html": [ - "6b4676f3b9b34ffa45ff616eb9d3c514e33ad471", + "4414277635ef6d8fb5fc941635e89587f3615436", "testharness" ], "bluetooth/device/gattserverdisconnected-event/one-event-per-disconnection.https.html": [ - "a0fbabe94fe246c2031fe4baf30ba52b58a17b36", + "fbb48d3173b0a35aa517b4c2ffb649a5a9280870", "testharness" ], "bluetooth/device/gattserverdisconnected-event/reconnect-during-disconnected-event.https.html": [ - "a66e1df2d870876d06ad0990ea523153539eff0e", + "c0142db0ee3a784184fd78b5255054539ae8b880", "testharness" ], "bluetooth/generate.py": [ @@ -252705,7 +253018,7 @@ "testharness" ], "bluetooth/idl/idl-BluetoothDevice.https.html": [ - "b4c78ec760b61420a82f4a1a2951fb2eaa6af10d", + "19d0c7b6e08ada8f3ed58921e662fe2d06ed55a4", "testharness" ], "bluetooth/idl/idl-BluetoothUUID.html": [ @@ -252725,7 +253038,7 @@ "testharness" ], "bluetooth/requestDevice/acceptAllDevices/optional-services-missing.https.html": [ - "c6e28d2c8509ea2f0e3633b2517ad68631119ffe", + "1e4a408d0497db72b1f1dc201f278ae7a701e0ab", "testharness" ], "bluetooth/requestDevice/acceptAllDevices/optional-services-present.https.html": [ @@ -252737,7 +253050,7 @@ "testharness" ], "bluetooth/requestDevice/blocklisted-service-in-optionalServices.https.html": [ - "c3fbd786e7cf05f72eb0afadba8924c43f2fdc11", + "5e3c7ac81089d9a44d07812b43e2ed63e1d39f11", "testharness" ], "bluetooth/requestDevice/canonicalizeFilter/device-name-longer-than-29-bytes.https.html": [ @@ -252821,11 +253134,11 @@ "testharness" ], "bluetooth/requestDevice/cross-origin-iframe.sub.https.html": [ - "dc9df7886d4a020b1853d7a54d67a8b1249c56c7", + "e5e22c1b7811699bb8bfd2b6593edf78a270a658", "testharness" ], "bluetooth/requestDevice/discovery-succeeds.https.html": [ - "da1be25f068cdb9602d6207b6af0170e232e68cd", + "0b75576a4742cc7496a890b273f2bb1c1f56017c", "testharness" ], "bluetooth/requestDevice/filter-matches.https.html": [ @@ -252853,7 +253166,7 @@ "testharness" ], "bluetooth/requestDevice/request-from-sandboxed-iframe.https.html": [ - "917a1be9111f04e67231c92921b1f856685deb55", + "fe1db81b730c5facaf45718e4536793f6c10f72a", "testharness" ], "bluetooth/requestDevice/same-device.https.html": [ @@ -252865,7 +253178,7 @@ "testharness" ], "bluetooth/resources/bluetooth-helpers.js": [ - "f19d8ab872de44f50c37aac3e3ad97ab0e502b59", + "c86347e3b26f369907ec7f0c3adaee20b630ade8", "support" ], "bluetooth/resources/health-thermometer-iframe.html": [ @@ -252893,7 +253206,7 @@ "support" ], "bluetooth/script-tests/server/disconnect-called-before.js": [ - "3ea0ed09ee2197401437b4d89c335181b2983b17", + "e8c31819a1250ec08217766f4b8228aa195a2d97", "support" ], "bluetooth/script-tests/server/disconnect-called-during-error.js": [ @@ -252937,19 +253250,19 @@ "support" ], "bluetooth/script-tests/server/invalid-service-name.js": [ - "0c2b3d759291d4e247df131f82daa2be847cb1d9", + "b7f6b5db7334b6467ec446fa5b0ea637306c8911", "support" ], "bluetooth/script-tests/server/no-permission-absent-service.js": [ - "78388409359e9e5bc36b304865e6e14d30769e12", + "8b0fb54dfffb7855923c51031969d0b5f9276918", "support" ], "bluetooth/script-tests/server/no-permission-for-any-service.js": [ - "f9230d7d66815561f575ba55409f2ca4fc0a67b8", + "81d9589206bbe46c784b415e3b250f9b05443e60", "support" ], "bluetooth/script-tests/server/no-permission-present-service.js": [ - "0f2e002be9842eb06f31f63de31c96fcd2820258", + "3200cee17040440cfe67a354c1fbc90fe537de81", "support" ], "bluetooth/script-tests/server/service-not-found.js": [ @@ -253017,7 +253330,7 @@ "testharness" ], "bluetooth/server/getPrimaryService/gen-disconnect-called-before.https.html": [ - "d1f9a8a640ae96589e7406e6c296137a08c4ea01", + "f4d97a6bd746c3d127378ad9c692b542c114d4e7", "testharness" ], "bluetooth/server/getPrimaryService/gen-disconnect-called-during-error.https.html": [ @@ -253061,19 +253374,19 @@ "testharness" ], "bluetooth/server/getPrimaryService/gen-invalid-service-name.https.html": [ - "5728e27aba6861ddfc7cb4278b116ee9d94fbb7a", + "4886cfde2f041edb7445c170b1a6c1a61b37f075", "testharness" ], "bluetooth/server/getPrimaryService/gen-no-permission-absent-service.https.html": [ - "ed7a5e4ab959f5d8b5e72154c68e397128c4d071", + "e40e8af7de38257160e5e4ef38f9c85667c5c274", "testharness" ], "bluetooth/server/getPrimaryService/gen-no-permission-for-any-service.https.html": [ - "86fab4a334c37e61ff9acbeafba071fd0aab5d30", + "1b87eb365022aec9c1f30fea557c996f232f6331", "testharness" ], "bluetooth/server/getPrimaryService/gen-no-permission-present-service.https.html": [ - "46717e75f676ff426773a79c4c01b2412b2c70ee", + "2ea2cff3588b10a387a182b31dac40dea52ab7b4", "testharness" ], "bluetooth/server/getPrimaryService/gen-service-not-found.https.html": [ @@ -253089,7 +253402,7 @@ "testharness" ], "bluetooth/server/getPrimaryServices/blocklisted-services-with-uuid.https.html": [ - "a58240662db7a01866c144e95d828cbeb6340a49", + "cb92cf7ba078851ccda73c6b069de825af05286b", "testharness" ], "bluetooth/server/getPrimaryServices/blocklisted-services.https.html": [ @@ -253101,11 +253414,11 @@ "testharness" ], "bluetooth/server/getPrimaryServices/gen-disconnect-called-before-with-uuid.https.html": [ - "ff1af939fa2b5b77523712a4281839349f00e43b", + "18aca22776caae36b47a58866f78a72ecc7f9f79", "testharness" ], "bluetooth/server/getPrimaryServices/gen-disconnect-called-before.https.html": [ - "b579d5e4ea1762930d2831b082fa6d92810e59c3", + "c98a723569159c5a139fd74fac0672590106f258", "testharness" ], "bluetooth/server/getPrimaryServices/gen-disconnect-called-during-error-with-uuid.https.html": [ @@ -253181,23 +253494,23 @@ "testharness" ], "bluetooth/server/getPrimaryServices/gen-invalid-service-name.https.html": [ - "878c93bcea918a0d008ab44552f7b26ff6f7a151", + "819b61b51d4f9ed60fdedcb3a719aa81c11d0d1b", "testharness" ], "bluetooth/server/getPrimaryServices/gen-no-permission-absent-service-with-uuid.https.html": [ - "f96b80beb4c79a2bda3cc06bc11d6aa5fb392ada", + "bec664d2805d7c98dccf83b93a6d49a145f06e19", "testharness" ], "bluetooth/server/getPrimaryServices/gen-no-permission-for-any-service-with-uuid.https.html": [ - "96a195a1b25cf1985ccbc949431a28226f3ee684", + "4cda505124cfe20c8b8e3630774b4f734eea10fe", "testharness" ], "bluetooth/server/getPrimaryServices/gen-no-permission-for-any-service.https.html": [ - "618cf409fffba7679abe515982695db4bb1a5f68", + "3a9ed522982b890296f926759954d463915818e9", "testharness" ], "bluetooth/server/getPrimaryServices/gen-no-permission-present-service-with-uuid.https.html": [ - "3126e3b157670506442b0032de53e6d29e4c30f6", + "6148df8814a7f9bc7bbad6cb278cffded99bcb9d", "testharness" ], "bluetooth/server/getPrimaryServices/gen-service-not-found-with-uuid.https.html": [ @@ -254617,7 +254930,7 @@ "support" ], "content-security-policy/navigate-to/child-navigates-parent-allowed.html": [ - "bacb9cd495aa4309349a4f80b3f886ee94542027", + "54f517e54260d444bce9866204172e6272c8f284", "testharness" ], "content-security-policy/navigate-to/child-navigates-parent-allowed.html.headers": [ @@ -254629,7 +254942,7 @@ "support" ], "content-security-policy/navigate-to/child-navigates-parent-blocked.html": [ - "fceb74d2ed4e5279da6455bff9abafb00c4f97cb", + "1e35f9b195940f9134d53849de6fafef370f0744", "testharness" ], "content-security-policy/navigate-to/child-navigates-parent-blocked.html.headers": [ @@ -254725,7 +255038,7 @@ "testharness" ], "content-security-policy/navigate-to/link-click-allowed.html": [ - "a4200a991a2e6d93ccf9f6dfedcaa5e5d75ead9e", + "133c29674edc3a53e5bc65f5f2e8b72a8ccc7bdf", "testharness" ], "content-security-policy/navigate-to/link-click-blocked-expected.txt": [ @@ -254733,11 +255046,11 @@ "support" ], "content-security-policy/navigate-to/link-click-blocked.html": [ - "04fafa60b6934d119997c37058605007cc8f2632", + "14861dffd89d889059d30f54a698ecff60a6c950", "testharness" ], "content-security-policy/navigate-to/link-click-cross-origin-allowed.sub.html": [ - "b1805390dada0f11c4dc45adf647133237934c45", + "55f36a1c3965f6acdc93fa23dba543608d9912d2", "testharness" ], "content-security-policy/navigate-to/link-click-cross-origin-blocked.sub-expected.txt": [ @@ -254745,11 +255058,11 @@ "support" ], "content-security-policy/navigate-to/link-click-cross-origin-blocked.sub.html": [ - "1f1def5a103caf71d8cd5ddc870f3050d98ec9f2", + "7247d779fa3729a9118859dd41e94aae7505afbd", "testharness" ], "content-security-policy/navigate-to/link-click-redirected-allowed.html": [ - "d89312685c3022438a2e55a025d330bb73eeedc0", + "f8a0f0646b5493be62ffeb541edbb039c1321d06", "testharness" ], "content-security-policy/navigate-to/link-click-redirected-blocked.sub-expected.txt": [ @@ -254757,7 +255070,7 @@ "support" ], "content-security-policy/navigate-to/link-click-redirected-blocked.sub.html": [ - "0b0c2c02fde1ea8aad7c25db210ea5fdd6f391e5", + "46ac39a0a5eb10fbb18ac6b19a087c81b66427f6", "testharness" ], "content-security-policy/navigate-to/meta-refresh-allowed.html": [ @@ -254973,7 +255286,7 @@ "testharness" ], "content-security-policy/prefetch-src/prefetch-allowed.html": [ - "8c88fefbffb6f5270b64cd8d81b405857a9c1123", + "45e002cde6f0e61cfc4876fad6d5af7341fec346", "testharness" ], "content-security-policy/prefetch-src/prefetch-blocked.html": [ @@ -255928,6 +256241,10 @@ "13c3f17f61fa30ac6d7c5c54bd73a6f93d1611c1", "support" ], + "content-security-policy/support/file-prefetch-allowed.html": [ + "13e9e4ef7ad82d1f9404381a3eeb2a00c319b52a", + "support" + ], "content-security-policy/support/fonts.css": [ "4577fb4f580bfd9c723e1a5ee0f9d8438ce41ac9", "support" @@ -286448,6 +286765,10 @@ "b9aa593e5fcba0d7af8f66446d473608a7025f1c", "testharness" ], + "css/css-fonts/variations/font-shorthand-expected.txt": [ + "ebc1d4d3ccac459d39cf416f0caccb6cb512d048", + "support" + ], "css/css-fonts/variations/font-shorthand.html": [ "7e193d5e25424699652e64b419e1d1384370e3a4", "testharness" @@ -286500,6 +286821,10 @@ "3e40c3f6d48096cbebe2a5c5becc627b17ed35a2", "testharness" ], + "css/css-fonts/variations/font-weight-parsing-expected.txt": [ + "936c28d1116cda3fb055133e8b46728bbdc85d55", + "support" + ], "css/css-fonts/variations/font-weight-parsing.html": [ "3cf6476257a47f8518ad19079cab4923598dc7da", "testharness" @@ -289480,6 +289805,10 @@ "435614e6d5dcdbd8325687f70014bea0e3dea5f7", "reftest" ], + "css/css-multicol/going-out-of-flow-after-spanner.html": [ + "d76366e15dd552c4c013c98e2de70ce6b38f0202", + "testharness" + ], "css/css-multicol/multicol-basic-001.html": [ "7cb568d75ea3fec9046ec69770fe59b8539beb02", "reftest" @@ -289833,7 +290162,7 @@ "support" ], "css/css-multicol/multicol-gap-001.xht": [ - "df60ea8599762b30a4b2c8e9d1e8164e5275a8fa", + "3d38feef824413b93cf65b2955044b1929390138", "reftest" ], "css/css-multicol/multicol-gap-002-ref.xht": [ @@ -289845,7 +290174,7 @@ "reftest" ], "css/css-multicol/multicol-gap-003.xht": [ - "16067366a3c1922e9c8415b21e513edd47c2305f", + "2cca63f39c97fd2f4de46bc0f892f07ad12b91ef", "reftest" ], "css/css-multicol/multicol-gap-animation-001.html": [ @@ -291748,6 +292077,10 @@ "ab3c3d205e59df800ba5b4217245b83685521c31", "reftest" ], + "css/css-scoping/shadow-reassign-dynamic-001.html": [ + "11ed4da2e6ce88d8a2b98a8f1c814417ef7770dd", + "reftest" + ], "css/css-scoping/shadow-root-insert-into-document.html": [ "2cee9fff35c9222074f4ef78dcfcb8a3e02bbc98", "reftest" @@ -291880,6 +292213,42 @@ "dfaf8675bec557c9f2178ad48b29c803f94056b5", "testharness" ], + "css/css-shadow-parts/all-hosts.html": [ + "a92019bba916ed3242dcdf66184d73b915f2689d", + "testharness" + ], + "css/css-shadow-parts/chaining-invalid-selector.html": [ + "f578d6766e7e20c31c677b6dfe1aea201f24ef65", + "testharness" + ], + "css/css-shadow-parts/complex-matching.html": [ + "abb39240874b2354afd80486da48285add6962b8", + "testharness" + ], + "css/css-shadow-parts/complex-non-matching.html": [ + "776604de1368139bc460e6376372ecfcea4ccdb5", + "testharness" + ], + "css/css-shadow-parts/different-host.html": [ + "040c22ffe6521d29be545e00a2b80d0e870426c3", + "testharness" + ], + "css/css-shadow-parts/host-stylesheet.html": [ + "fe3affed81f2edea4e72f9e006ef81ab360f9555", + "testharness" + ], + "css/css-shadow-parts/inner-host.html": [ + "4330af8042042c73a6cc590c38cd32613e2b9db3", + "testharness" + ], + "css/css-shadow-parts/simple.html": [ + "76bea5867f75428345b105a813b7510f0492b2d2", + "testharness" + ], + "css/css-shadow-parts/support/shadow-helper.js": [ + "00de7ed5660dd4e1b37710aba7cf2664c4773749", + "support" + ], "css/css-shapes/OWNERS": [ "440928017de5f0747eb891e3f8374018ef1e57d4", "support" @@ -306601,7 +306970,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/background-expected.txt": [ - "2678d8c6a0464fa6ce365f81fcbd81d5b8d3aa6f", + "90f4bbb49e747b7bc35067faaed5175bcf2bf8aa", "support" ], "css/css-typed-om/the-stylepropertymap/properties/background-image.html": [ @@ -306645,7 +307014,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/break-expected.txt": [ - "9a8a88f3b60ba9d731e1816bb3c3a769f4357905", + "e686f54d53e430604f8df475e7977d083f07b8ff", "support" ], "css/css-typed-om/the-stylepropertymap/properties/break.html": [ @@ -306701,7 +307070,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/flex-basis-expected.txt": [ - "b2bf34ab42aa154894eb40dc5a3e58f137459ae1", + "68bfdcebfc98430d988ae79be2d47f46c11690a9", "support" ], "css/css-typed-om/the-stylepropertymap/properties/flex-basis.html": [ @@ -306741,7 +307110,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-language-override-expected.txt": [ - "59ffb7920ddeeb2b8595b5fea5dd320085c12b0e", + "edc0dcd11fb4e8b1db684349b4af5ff805777dfa", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-language-override.html": [ @@ -306749,7 +307118,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-optical-sizing-expected.txt": [ - "678282ff775bfaf48f96b73925ba9fc3e938493c", + "a5ff71f72a9eca63412230e8279f1f136ecea892", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-optical-sizing.html": [ @@ -306757,7 +307126,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-palette-expected.txt": [ - "a12c3242888ed3152ce24f82a7678d7d214e2602", + "6689f333ca7d25c1ef60946b1e1dc5ab1af10e33", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-palette.html": [ @@ -306765,7 +307134,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-presentation-expected.txt": [ - "8c6dc676d593cfb5d1b86d70b7eb1d4bf92a1e18", + "84e5dd1e1d7089000ae0ed631abb46a35f973704", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-presentation.html": [ @@ -306777,7 +307146,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-size-expected.txt": [ - "7199fdfa6f0559e3bb92c3cdb5a93e31d6f31b23", + "48f05066f666fba865c27573ecca86e50c9f9ed6", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-size.html": [ @@ -306785,7 +307154,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-stretch-expected.txt": [ - "ce411f253e6c8b2872d5a20e74d417ffbd9f5587", + "ebedb322ba599aec29cbe111cdc79e8a905654db", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-stretch.html": [ @@ -306793,7 +307162,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-style-expected.txt": [ - "f51e7f0bff63be8c8eee471953b935ca4eab2e6f", + "914bafe45bc60bc6b5c8149d4f5c52e548dfb8d5", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-style.html": [ @@ -306801,7 +307170,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-synthesis-expected.txt": [ - "a593ae0e8a3f8e0df2303b61b59c0bbd9194ae85", + "a0abddd2484fdecea5eb6a9f23e561bf79d4e731", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-synthesis.html": [ @@ -306809,7 +307178,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-variant-alternates-expected.txt": [ - "dba98f248c2860fba2db9eb4966cd65767887e5d", + "507d4e36d6a1532f9e3882081ac2a0dc815cee29", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-variant-alternates.html": [ @@ -306817,7 +307186,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-variant-emoji-expected.txt": [ - "5d0bf66e0005650cdf47deb462aa73d9dbed9c29", + "cda2f64b09d57b58d6433791ac4ba59e37e2a14b", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-variant-emoji.html": [ @@ -306833,7 +307202,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/font-weight-expected.txt": [ - "48ca2e6c7e9fd594328b7490ad18a5a65c8c1902", + "00597b616a928087bb62547aff0b107619d1cf63", "support" ], "css/css-typed-om/the-stylepropertymap/properties/font-weight.html": [ @@ -306848,12 +307217,60 @@ "e113dfd152548c6ba612d40af13ba5877673b043", "testharness" ], + "css/css-typed-om/the-stylepropertymap/properties/grid-area.html": [ + "3f139dfec90a4ed0a460530fe5736475b6c25540", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-auto-columns-rows.html": [ + "ff3e9e2b1186aed0e9ecf17cebe40316880d447d", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-auto-flow.html": [ + "25af714f7993ad00a36cf9a96cc0218aaed9f53f", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-expected.txt": [ + "677d787bc4e2efd09f17907709416449de0b2785", + "support" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-gap-expected.txt": [ + "b1c12d725c1d9869754caadc174759fb6fa22472", + "support" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-gap.html": [ + "1fbe50656f4d598f3baed2116c51b47fe3187b92", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-start-end.html": [ + "12c4d77ab5df2b6e9f673a9f83ffcb583ccb9fe1", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-template-areas.html": [ + "5bcd38d13e904ca4e74aef5701f10f325c1f702f", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-template-columns-rows.html": [ + "1f6e412eb1a862b8c3bdd2d4fa30e6495ebfdbb0", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-template-expected.txt": [ + "b4b075932313f2c7d12f871536470750b1e75b08", + "support" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid-template.html": [ + "f1bb1330c555ffdedcd0b53c879d18f0b4ddedea", + "testharness" + ], + "css/css-typed-om/the-stylepropertymap/properties/grid.html": [ + "13ec601464ba9935b2167493c77d6189737f5380", + "testharness" + ], "css/css-typed-om/the-stylepropertymap/properties/height.html": [ "617ec941ab1cbd02b31b8a9bb7ce6da311109476", "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/image-rendering-expected.txt": [ - "2b10e5f9dfdc1cc499d9bea6a7e4c3cb966bbdf8", + "7522b7cef80d8eeac97ceefc4585fc6326fc2c34", "support" ], "css/css-typed-om/the-stylepropertymap/properties/image-rendering.html": [ @@ -306873,7 +307290,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/line-height-expected.txt": [ - "022684735db5c3aaee60fc3c340864d583b120ba", + "43fb859a614ed3efff4052b365eee41df69724a0", "support" ], "css/css-typed-om/the-stylepropertymap/properties/line-height.html": [ @@ -306889,7 +307306,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/margin-expected.txt": [ - "418a278215425057cd7b158dd2f0d143a8615628", + "adb3b909a22bec9017f599ac4e3c7cbb44c52ab9", "support" ], "css/css-typed-om/the-stylepropertymap/properties/margin.html": [ @@ -306901,7 +307318,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/mask-image-expected.txt": [ - "0cc719048e458d2454d85d9ce9a6e197148ca07b", + "36d4768ce5ba6c03284ea59ccc9def2a433d8bfb", "support" ], "css/css-typed-om/the-stylepropertymap/properties/mask-image.html": [ @@ -306953,7 +307370,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/outline-style-expected.txt": [ - "981154baad2963b7ab6e06e1950e1d3511878532", + "ac303bed8b63d8a7f0cff2cfcc9b3c4962ac1a79", "support" ], "css/css-typed-om/the-stylepropertymap/properties/outline-style.html": [ @@ -306965,7 +307382,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/overflow-expected.txt": [ - "b3092b55eea27cd358380db1127a688bf7c40724", + "51cf73e8e62c5e8f009764822f9a1f21bfac061c", "support" ], "css/css-typed-om/the-stylepropertymap/properties/overflow.html": [ @@ -306993,7 +307410,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/resources/testsuite.js": [ - "a11458935f17ace154a68314677a4a868ba55273", + "9e7a4bb8fa2d8ad491353117b409a2a7ff314d7f", "support" ], "css/css-typed-om/the-stylepropertymap/properties/right.html": [ @@ -307009,7 +307426,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/shape-outside-expected.txt": [ - "db3780a372263495200ba69d978c60d43ccb2aa1", + "ea8f992a222281db2a864895df647591f76dca67", "support" ], "css/css-typed-om/the-stylepropertymap/properties/shape-outside.html": [ @@ -307029,7 +307446,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/text-combine-upright-expected.txt": [ - "cdabdc0dd6cfb006a7f97d88f5adf24a3a67b181", + "19aee5b2ffaa769d11fae78c9de4c41688f047e9", "support" ], "css/css-typed-om/the-stylepropertymap/properties/text-combine-upright.html": [ @@ -307041,7 +307458,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/text-decoration-line-expected.txt": [ - "ab2faf1d519b3fad46aa6eb11a623d54c9ee9191", + "7c3181683af1d002346575143a8fe606f01e9844", "support" ], "css/css-typed-om/the-stylepropertymap/properties/text-decoration-line.html": [ @@ -307049,7 +307466,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/text-decoration-skip-expected.txt": [ - "b77aafbe21874ecb5e5bfe1c2c60b410e9d37afe", + "3643827beefeefea86abaf5508bddefc9ce17eef", "support" ], "css/css-typed-om/the-stylepropertymap/properties/text-decoration-skip-ink.html": [ @@ -307065,7 +307482,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/text-decoration-width-expected.txt": [ - "72c8831b783d79b5fef43f3221461bbac76cf097", + "04b1d2dff135aaeae50e46f502b9fcf7b71e63b6", "support" ], "css/css-typed-om/the-stylepropertymap/properties/text-decoration-width.html": [ @@ -307077,7 +307494,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/text-emphasis-color-expected.txt": [ - "1c109f27ed4ef58da4ba6a95232e70988704b712", + "4f81b23b27e8a2f5c33845f177e8ae10274e4dac", "support" ], "css/css-typed-om/the-stylepropertymap/properties/text-emphasis-color.html": [ @@ -307089,7 +307506,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/text-overflow-expected.txt": [ - "ecd1db7a12ee95c8ca1a1e5a1aa960af8204036c", + "7561fd04d53b20a6d5e1a85dd89e3a982aab01c0", "support" ], "css/css-typed-om/the-stylepropertymap/properties/text-overflow.html": [ @@ -307101,7 +307518,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/text-transform-expected.txt": [ - "3999d23023fb88ad5e47879574f7b3bd92d91528", + "66ec6be5f3c050ea2093537e25d35b141a623cec", "support" ], "css/css-typed-om/the-stylepropertymap/properties/text-transform.html": [ @@ -307153,7 +307570,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/user-select-expected.txt": [ - "b626905dec44c166f27bf2b6546d49a0b246b7ba", + "01766d2927fe93aa54a9f67ef427f1dec427554a", "support" ], "css/css-typed-om/the-stylepropertymap/properties/user-select.html": [ @@ -307177,7 +307594,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/properties/writing-mode-expected.txt": [ - "44d90fb5d8c6dcbf82cfe7b99baf554fb6195ba8", + "beee8ef4c10d15f816b1cfa233a0980de09d6d78", "support" ], "css/css-typed-om/the-stylepropertymap/properties/writing-mode.html": [ @@ -316264,6 +316681,14 @@ "8dfaa313b4abad30281d07ce22ac06a61754cc06", "testharness" ], + "css/cssom-view/cssom-getBoxQuads-001-expected.txt": [ + "d4ba483519cb637ec729a96ba7180744c2f21a96", + "support" + ], + "css/cssom-view/cssom-getBoxQuads-001.html": [ + "6236946f2eb29b2fdb3e7b3c1152ef275d921759", + "testharness" + ], "css/cssom-view/cssom-getClientRects-002-expected.txt": [ "9a34de1b85869d6354083854633b2b2c800dd784", "support" @@ -320044,6 +320469,14 @@ "4eff7ada840bc140d4ba2a115169f19855e0acec", "reftest" ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002-ref.html": [ + "5e341aaf001f17249f7307552d0bc639021a4a25", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002.html": [ + "5ba69f0e2b5d2308c553a5a6e1c6a6eeb19528a4", + "reftest" + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-align-content-horiz-001-ref.xhtml": [ "812712adfc932b89afaae066b464562f4bddf7a9", "support" @@ -320588,6 +321021,30 @@ "95154acaff08d7d3f999afe1ea1979017fdcc115", "reftest" ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001-ref.html": [ + "89fd3533c50deabebc3742ee839e7ac820da2a0e", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001a.html": [ + "777b5ec16a9e01bcb24aaba36aa4f427ed76b666", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001b.html": [ + "0c94fe7294a1b2f9e629f86281cdb479776516bb", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002-ref.html": [ + "79b75f4761f6433fd02b9595afd652e22e2887c2", + "support" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002a.html": [ + "2516ae40d90a58510a89caabce2ce80cd1eccea3", + "reftest" + ], + "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002b.html": [ + "6dc70e9530748c19bcff41bdaaee961adf327e5d", + "reftest" + ], "css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-flow-001-ref.html": [ "b1e21a6a3e12afbf1602aec0888f6f9c7ba9e97d", "support" @@ -322356,8 +322813,12 @@ "da90b2a1c13cf18fd5cade85dcae2dadef6243c9", "testharness" ], + "custom-elements/HTMLElement-constructor-expected.txt": [ + "4d971d82102ff68de3140a7e766ef0c62c678b68", + "support" + ], "custom-elements/HTMLElement-constructor.html": [ - "64522527ef425b90c704b20b000c8feef0d1ca25", + "4dc04a8b026538bddee52586f2df50206abc9334", "testharness" ], "custom-elements/OWNERS": [ @@ -322416,8 +322877,12 @@ "991ebcff1d8b59a7a4d959f3061a17e0e8a83704", "testharness" ], + "custom-elements/htmlconstructor/newtarget-expected.txt": [ + "db2562ea508f54ad20b7d41b908200a807dbb155", + "support" + ], "custom-elements/htmlconstructor/newtarget.html": [ - "11b7927c9a2946c752f56e5b44cfb4051ab8b6d6", + "39a7331d37056d0203fd771d797fd8da3d2bbefb", "testharness" ], "custom-elements/microtasks-and-constructors.html": [ @@ -327525,7 +327990,7 @@ "support" ], "fetch/api/abort/general.any.js": [ - "a0b775a19b3046336c45289f5a87ea57e476f084", + "e7a735978af073066872021580ececcb7f465512", "testharness" ], "fetch/api/abort/general.any.worker-expected.txt": [ @@ -333536,6 +334001,14 @@ "a2a5acc9dfe53c7482eeaa4be3a4819238f8e120", "testharness" ], + "html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext-subframe.txt": [ + "8d06cea05d408d70c59b1dbc5df3bda374d869a4", + "support" + ], + "html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext.window.js": [ + "1f440ff93300a0ab715982feb067dd3162c8fce9", + "testharness" + ], "html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument.window.js": [ "0f0020e1d7d8050892ef146d687178cfe8eedcd2", "testharness" @@ -340044,6 +340517,10 @@ "628527090c78d90d831cb80ea8eee7ffa66722f5", "testharness" ], + "html/semantics/document-metadata/the-link-element/link-rel-attribute.html": [ + "45824076fb8696f775582c7bcfab093ebfb3055c", + "testharness" + ], "html/semantics/document-metadata/the-link-element/link-rellist.html": [ "e18655ffb90bb039c50b262d145d63ca5efc22ca", "testharness" @@ -340072,6 +340549,10 @@ "1c5d8fe0b94b033b8e6ee7bcf54bd35ba2febd36", "support" ], + "html/semantics/document-metadata/the-link-element/resources/link-rel-attribute.css": [ + "7439a846bece4561d9b17494aaae4c7b2aef6a2f", + "support" + ], "html/semantics/document-metadata/the-link-element/resources/stylesheet.css": [ "2829167c82bafef6cfea06071007a231aa4277f6", "support" @@ -349552,6 +350033,10 @@ "afb1a08faa639bdd1ee4387069d76803c5e38d54", "testharness" ], + "infrastructure/testdriver/send_keys-expected.txt": [ + "44a260387704a7a9943182a7561a46d222bae650", + "support" + ], "infrastructure/testdriver/send_keys.html": [ "f2ede647416d150d7cd3720719f386b9f4d5fb6c", "testharness" @@ -350997,7 +351482,7 @@ "testharness" ], "mediasession/setactionhandler.html": [ - "70a1f9e81faa3dbbe320a71a008e4594a29878a8", + "ab3482a22dd713ce7c71ce4b5efeb3cb201e76e6", "testharness" ], "mimesniff/README.md": [ @@ -351009,7 +351494,7 @@ "support" ], "mimesniff/mime-types/charset-parameter.window-expected.txt": [ - "f60ed8f628e6c2688572b2a30fc7d4fff13f63ac", + "307de11484a2c6ca3f0ef757057e3ade7576c01f", "support" ], "mimesniff/mime-types/charset-parameter.window.js": [ @@ -351017,7 +351502,7 @@ "testharness" ], "mimesniff/mime-types/parsing.any-expected.txt": [ - "102170f15a37599e9e4346371fe6c6a6626540ea", + "ce5e71c028a601fecbdc3adeb69925266b651287", "support" ], "mimesniff/mime-types/parsing.any.js": [ @@ -351025,7 +351510,7 @@ "testharness" ], "mimesniff/mime-types/parsing.any.worker-expected.txt": [ - "102170f15a37599e9e4346371fe6c6a6626540ea", + "ce5e71c028a601fecbdc3adeb69925266b651287", "support" ], "mimesniff/mime-types/resources/generated-mime-types.json": [ @@ -351041,7 +351526,7 @@ "support" ], "mimesniff/mime-types/resources/mime-types.json": [ - "e036eb74e27d8f35c411bb4d29d0b0621778e882", + "9271134541b22f4af44b6d179606c7a6cb8f3227", "support" ], "mixed-content/OWNERS": [ @@ -359696,6 +360181,26 @@ "11d5baa9206313270be6289205b002b623af85db", "testharness" ], + "pointerevents/extension/pointerevent_touch-action-pan-down-css_touch-manual.html": [ + "4743453e64f6d2006f7e4034a5e2e6729b2f3ff8", + "manual" + ], + "pointerevents/extension/pointerevent_touch-action-pan-left-css_touch-manual.html": [ + "07c68a3e30fed012a6eb5a33e9548e516e4ea027", + "manual" + ], + "pointerevents/extension/pointerevent_touch-action-pan-right-css_touch-manual.html": [ + "dd4ad4a8060ae08d3fdd013b299e5cc8ca0906bc", + "manual" + ], + "pointerevents/extension/pointerevent_touch-action-pan-up-css_touch-manual.html": [ + "5470d896c20335be39b3276d4dc6a49b00923e25", + "manual" + ], + "pointerevents/extension/pointerevent_touch-action-verification.html": [ + "f3188cc408b651f05ad946768c8233d0f7586b38", + "testharness" + ], "pointerevents/html/pointerevent_drag_interaction-manual.html": [ "1eb570dbed48373f9e840b7694b774448b689879", "manual" @@ -359916,22 +360421,6 @@ "d60ccd5a174204dd5baf8ad1db690b1b67b969fe", "manual" ], - "pointerevents/pointerevent_touch-action-pan-down-css_touch-manual.html": [ - "e400167599193b73aca776bb49fa372094b560ec", - "manual" - ], - "pointerevents/pointerevent_touch-action-pan-left-css_touch-manual.html": [ - "e940ad98c2e63c82ec2977e0bbc87364d24aaf88", - "manual" - ], - "pointerevents/pointerevent_touch-action-pan-right-css_touch-manual.html": [ - "48ed6d4e7966fad84479eaf5990136154e31242c", - "manual" - ], - "pointerevents/pointerevent_touch-action-pan-up-css_touch-manual.html": [ - "9f63a5efe3fe642ce6787fdb1bf9d68184d7ce96", - "manual" - ], "pointerevents/pointerevent_touch-action-pan-x-css_touch-manual.html": [ "e3adda44b02879ead5681d0e1bb8fc6bc47e4f39", "manual" @@ -359965,7 +360454,7 @@ "manual" ], "pointerevents/pointerevent_touch-action-verification.html": [ - "c2c952d562f601f2104014f6236368a7f6b84801", + "66e0cde3be274124cc2a015bbce59e8e42e5de69", "testharness" ], "pointerevents/pointerlock/pointerevent_movementxy-manual.html": [ @@ -368761,7 +369250,7 @@ "support" ], "server-timing/cross_origin.html": [ - "74333db517babacbb84bb20c91ccfc8b2627b934", + "661cf7f329590a89aa2644a102a10d1ba34feb75", "testharness" ], "server-timing/resources/blue.png": [ @@ -368781,7 +369270,7 @@ "support" ], "server-timing/resources/parsing/0.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/0.js.sub.headers": [ @@ -368789,7 +369278,7 @@ "support" ], "server-timing/resources/parsing/1.js": [ - "1a6924ba411a7f92aef048336bd117ece499f90a", + "db03fe36244bd2c07fc92720fd1d24825f9a4d11", "support" ], "server-timing/resources/parsing/1.js.sub.headers": [ @@ -368797,7 +369286,7 @@ "support" ], "server-timing/resources/parsing/10.js": [ - "1a6924ba411a7f92aef048336bd117ece499f90a", + "db03fe36244bd2c07fc92720fd1d24825f9a4d11", "support" ], "server-timing/resources/parsing/10.js.sub.headers": [ @@ -368805,7 +369294,7 @@ "support" ], "server-timing/resources/parsing/11.js": [ - "1a6924ba411a7f92aef048336bd117ece499f90a", + "db03fe36244bd2c07fc92720fd1d24825f9a4d11", "support" ], "server-timing/resources/parsing/11.js.sub.headers": [ @@ -368813,7 +369302,7 @@ "support" ], "server-timing/resources/parsing/12.js": [ - "1c6ca0aa58035fba39cfe8284c04468787149469", + "aca5ff6a4ec3da6fcd8f537e75f189ab52396576", "support" ], "server-timing/resources/parsing/12.js.sub.headers": [ @@ -368821,7 +369310,7 @@ "support" ], "server-timing/resources/parsing/13.js": [ - "266ee41ae7b440ab43e87a087d10fa2b1e193a8f", + "3e2173bd78dca0e60e6fee7ad9e893010195234e", "support" ], "server-timing/resources/parsing/13.js.sub.headers": [ @@ -368829,7 +369318,7 @@ "support" ], "server-timing/resources/parsing/14.js": [ - "b45df4c8581d127f4738887a009611092e06fae9", + "2016e06fed61d3375251e0cb832bb1141cf62a2e", "support" ], "server-timing/resources/parsing/14.js.sub.headers": [ @@ -368837,7 +369326,7 @@ "support" ], "server-timing/resources/parsing/15.js": [ - "57529824e71a124c2ff69e9153163de9f4c3433d", + "e3a2150ea44b2abb27b5640cd85bf299973dafcf", "support" ], "server-timing/resources/parsing/15.js.sub.headers": [ @@ -368845,7 +369334,7 @@ "support" ], "server-timing/resources/parsing/16.js": [ - "8d82b5abff0bfc1884a350836cb27c8b124129bd", + "010f58074c2169b7cec8fcf175bd8168182ba7a0", "support" ], "server-timing/resources/parsing/16.js.sub.headers": [ @@ -368853,7 +369342,7 @@ "support" ], "server-timing/resources/parsing/17.js": [ - "b45df4c8581d127f4738887a009611092e06fae9", + "2016e06fed61d3375251e0cb832bb1141cf62a2e", "support" ], "server-timing/resources/parsing/17.js.sub.headers": [ @@ -368861,7 +369350,7 @@ "support" ], "server-timing/resources/parsing/18.js": [ - "e37a27e8de7cb0d7da20de4b4738f868321f4f7d", + "c818182cc29f9bbefa7b3ebd403b7b1520fee25d", "support" ], "server-timing/resources/parsing/18.js.sub.headers": [ @@ -368869,7 +369358,7 @@ "support" ], "server-timing/resources/parsing/19.js": [ - "945c0786a390786f6bc648fb80ffe2da2c14c4b1", + "0d95ec03d3f26555f3063a0f41eb643e83a1ed0d", "support" ], "server-timing/resources/parsing/19.js.sub.headers": [ @@ -368877,7 +369366,7 @@ "support" ], "server-timing/resources/parsing/2.js": [ - "1bc5932490ce45826ee11e124924c9588b3e8c4d", + "b40f75f2522ae8277f5c391472fe285a9b504a02", "support" ], "server-timing/resources/parsing/2.js.sub.headers": [ @@ -368885,7 +369374,7 @@ "support" ], "server-timing/resources/parsing/20.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/20.js.sub.headers": [ @@ -368893,7 +369382,7 @@ "support" ], "server-timing/resources/parsing/21.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/21.js.sub.headers": [ @@ -368901,7 +369390,7 @@ "support" ], "server-timing/resources/parsing/22.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/22.js.sub.headers": [ @@ -368909,7 +369398,7 @@ "support" ], "server-timing/resources/parsing/23.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/23.js.sub.headers": [ @@ -368917,7 +369406,7 @@ "support" ], "server-timing/resources/parsing/24.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/24.js.sub.headers": [ @@ -368925,7 +369414,7 @@ "support" ], "server-timing/resources/parsing/25.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/25.js.sub.headers": [ @@ -368933,7 +369422,7 @@ "support" ], "server-timing/resources/parsing/26.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/26.js.sub.headers": [ @@ -368941,7 +369430,7 @@ "support" ], "server-timing/resources/parsing/27.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/27.js.sub.headers": [ @@ -368949,7 +369438,7 @@ "support" ], "server-timing/resources/parsing/28.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/28.js.sub.headers": [ @@ -368957,7 +369446,7 @@ "support" ], "server-timing/resources/parsing/29.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/29.js.sub.headers": [ @@ -368965,7 +369454,7 @@ "support" ], "server-timing/resources/parsing/3.js": [ - "1bc5932490ce45826ee11e124924c9588b3e8c4d", + "b40f75f2522ae8277f5c391472fe285a9b504a02", "support" ], "server-timing/resources/parsing/3.js.sub.headers": [ @@ -368973,7 +369462,7 @@ "support" ], "server-timing/resources/parsing/30.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/30.js.sub.headers": [ @@ -368981,7 +369470,7 @@ "support" ], "server-timing/resources/parsing/31.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/31.js.sub.headers": [ @@ -368989,7 +369478,7 @@ "support" ], "server-timing/resources/parsing/32.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/32.js.sub.headers": [ @@ -368997,7 +369486,7 @@ "support" ], "server-timing/resources/parsing/33.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/33.js.sub.headers": [ @@ -369005,7 +369494,7 @@ "support" ], "server-timing/resources/parsing/34.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/34.js.sub.headers": [ @@ -369013,7 +369502,7 @@ "support" ], "server-timing/resources/parsing/35.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/35.js.sub.headers": [ @@ -369021,7 +369510,7 @@ "support" ], "server-timing/resources/parsing/36.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/36.js.sub.headers": [ @@ -369029,7 +369518,7 @@ "support" ], "server-timing/resources/parsing/37.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/37.js.sub.headers": [ @@ -369037,7 +369526,7 @@ "support" ], "server-timing/resources/parsing/38.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/38.js.sub.headers": [ @@ -369045,7 +369534,7 @@ "support" ], "server-timing/resources/parsing/39.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/39.js.sub.headers": [ @@ -369053,7 +369542,7 @@ "support" ], "server-timing/resources/parsing/4.js": [ - "b45df4c8581d127f4738887a009611092e06fae9", + "2016e06fed61d3375251e0cb832bb1141cf62a2e", "support" ], "server-timing/resources/parsing/4.js.sub.headers": [ @@ -369061,7 +369550,7 @@ "support" ], "server-timing/resources/parsing/40.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/40.js.sub.headers": [ @@ -369069,7 +369558,7 @@ "support" ], "server-timing/resources/parsing/41.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/41.js.sub.headers": [ @@ -369077,7 +369566,7 @@ "support" ], "server-timing/resources/parsing/42.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/42.js.sub.headers": [ @@ -369085,7 +369574,7 @@ "support" ], "server-timing/resources/parsing/43.js": [ - "dcf2d8477422cfa60c7eb5da68629925fcc653e2", + "26b6479e14f035125f95f6a979d65883e16c2755", "support" ], "server-timing/resources/parsing/43.js.sub.headers": [ @@ -369093,7 +369582,7 @@ "support" ], "server-timing/resources/parsing/44.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/44.js.sub.headers": [ @@ -369101,7 +369590,7 @@ "support" ], "server-timing/resources/parsing/45.js": [ - "72dcb467c3d7fb4a2491a0ba68b612a4033738f3", + "2d92b3d068a2be9688eb5897c12c852c58fbb684", "support" ], "server-timing/resources/parsing/45.js.sub.headers": [ @@ -369109,7 +369598,7 @@ "support" ], "server-timing/resources/parsing/46.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/46.js.sub.headers": [ @@ -369117,7 +369606,7 @@ "support" ], "server-timing/resources/parsing/47.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/47.js.sub.headers": [ @@ -369125,7 +369614,7 @@ "support" ], "server-timing/resources/parsing/48.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/48.js.sub.headers": [ @@ -369133,7 +369622,7 @@ "support" ], "server-timing/resources/parsing/49.js": [ - "6c2c1b45ab69ed8b1da28849accaa69a99d07340", + "d8de868c77f5926b438c4740c8f30e01bc6a714f", "support" ], "server-timing/resources/parsing/49.js.sub.headers": [ @@ -369141,7 +369630,7 @@ "support" ], "server-timing/resources/parsing/5.js": [ - "b45df4c8581d127f4738887a009611092e06fae9", + "2016e06fed61d3375251e0cb832bb1141cf62a2e", "support" ], "server-timing/resources/parsing/5.js.sub.headers": [ @@ -369149,7 +369638,7 @@ "support" ], "server-timing/resources/parsing/50.js": [ - "71068640ee55f176c283ce788237e26059c043c5", + "020df20a8afdf2d67ff37f017e400a90247f510e", "support" ], "server-timing/resources/parsing/50.js.sub.headers": [ @@ -369157,7 +369646,7 @@ "support" ], "server-timing/resources/parsing/51.js": [ - "1c6ca0aa58035fba39cfe8284c04468787149469", + "aca5ff6a4ec3da6fcd8f537e75f189ab52396576", "support" ], "server-timing/resources/parsing/51.js.sub.headers": [ @@ -369165,7 +369654,7 @@ "support" ], "server-timing/resources/parsing/52.js": [ - "d0a406b076d345dc36d1792781bd078fb9b65ef3", + "84e265d2e41da883a09eacc7c0448fb55068cfe2", "support" ], "server-timing/resources/parsing/52.js.sub.headers": [ @@ -369173,7 +369662,7 @@ "support" ], "server-timing/resources/parsing/53.js": [ - "235f1ee6973489be765e8edec753b94c9f6d5773", + "0ab0b4d6a9b95a749e9292da467f0fb58a729012", "support" ], "server-timing/resources/parsing/53.js.sub.headers": [ @@ -369181,7 +369670,7 @@ "support" ], "server-timing/resources/parsing/54.js": [ - "235f1ee6973489be765e8edec753b94c9f6d5773", + "0ab0b4d6a9b95a749e9292da467f0fb58a729012", "support" ], "server-timing/resources/parsing/54.js.sub.headers": [ @@ -369189,7 +369678,7 @@ "support" ], "server-timing/resources/parsing/55.js": [ - "2209fc9eff24dc4f0d7df2f31e5911dd4e05d78d", + "ad58eaac1a11e8b6daa4a6f29fa33e85d6a1003e", "support" ], "server-timing/resources/parsing/55.js.sub.headers": [ @@ -369197,7 +369686,7 @@ "support" ], "server-timing/resources/parsing/56.js": [ - "1bc5932490ce45826ee11e124924c9588b3e8c4d", + "b40f75f2522ae8277f5c391472fe285a9b504a02", "support" ], "server-timing/resources/parsing/56.js.sub.headers": [ @@ -369205,7 +369694,7 @@ "support" ], "server-timing/resources/parsing/57.js": [ - "235f1ee6973489be765e8edec753b94c9f6d5773", + "0ab0b4d6a9b95a749e9292da467f0fb58a729012", "support" ], "server-timing/resources/parsing/57.js.sub.headers": [ @@ -369213,7 +369702,7 @@ "support" ], "server-timing/resources/parsing/58.js": [ - "3fddff4eee055bf54f23be4ddd0e277cb79d492d", + "c708c93be1d25301433f97ff41973115f5441990", "support" ], "server-timing/resources/parsing/58.js.sub.headers": [ @@ -369221,7 +369710,7 @@ "support" ], "server-timing/resources/parsing/59.js": [ - "63d1c9fc862e586f387e1715c47c14075b9dc39e", + "888df69076ddb4e5f86219fad670dbe7df290716", "support" ], "server-timing/resources/parsing/59.js.sub.headers": [ @@ -369229,7 +369718,7 @@ "support" ], "server-timing/resources/parsing/6.js": [ - "1c6ca0aa58035fba39cfe8284c04468787149469", + "aca5ff6a4ec3da6fcd8f537e75f189ab52396576", "support" ], "server-timing/resources/parsing/6.js.sub.headers": [ @@ -369237,7 +369726,7 @@ "support" ], "server-timing/resources/parsing/60.js": [ - "63d1c9fc862e586f387e1715c47c14075b9dc39e", + "888df69076ddb4e5f86219fad670dbe7df290716", "support" ], "server-timing/resources/parsing/60.js.sub.headers": [ @@ -369245,7 +369734,7 @@ "support" ], "server-timing/resources/parsing/61.js": [ - "3560177cc96b27c6ca4dfd3f4755685f067a9c77", + "f81cfcef6ff2f5166110945a56050d1a6749cfa8", "support" ], "server-timing/resources/parsing/61.js.sub.headers": [ @@ -369253,7 +369742,7 @@ "support" ], "server-timing/resources/parsing/62.js": [ - "3560177cc96b27c6ca4dfd3f4755685f067a9c77", + "f81cfcef6ff2f5166110945a56050d1a6749cfa8", "support" ], "server-timing/resources/parsing/62.js.sub.headers": [ @@ -369261,7 +369750,7 @@ "support" ], "server-timing/resources/parsing/63.js": [ - "5c07fca48386d2d35c248c2053a7cb426ade6b7b", + "71ee194e6955b8b9b4ee4069f4a14df89b2cf1bc", "support" ], "server-timing/resources/parsing/63.js.sub.headers": [ @@ -369269,7 +369758,7 @@ "support" ], "server-timing/resources/parsing/64.js": [ - "df2fb9e4e7999d2bda0c6e435b541fa37a55c788", + "f617f0f8f7cf9040e6409b0ce74b9d0574674a1f", "support" ], "server-timing/resources/parsing/64.js.sub.headers": [ @@ -369277,7 +369766,7 @@ "support" ], "server-timing/resources/parsing/65.js": [ - "5c07fca48386d2d35c248c2053a7cb426ade6b7b", + "71ee194e6955b8b9b4ee4069f4a14df89b2cf1bc", "support" ], "server-timing/resources/parsing/65.js.sub.headers": [ @@ -369285,7 +369774,7 @@ "support" ], "server-timing/resources/parsing/66.js": [ - "df2fb9e4e7999d2bda0c6e435b541fa37a55c788", + "f617f0f8f7cf9040e6409b0ce74b9d0574674a1f", "support" ], "server-timing/resources/parsing/66.js.sub.headers": [ @@ -369293,7 +369782,7 @@ "support" ], "server-timing/resources/parsing/67.js": [ - "1a6924ba411a7f92aef048336bd117ece499f90a", + "db03fe36244bd2c07fc92720fd1d24825f9a4d11", "support" ], "server-timing/resources/parsing/67.js.sub.headers": [ @@ -369301,7 +369790,7 @@ "support" ], "server-timing/resources/parsing/68.js": [ - "b5b95d8349cbbc3b92edb61891608b04d004527b", + "6101bd375a67052cb449c83494dc32691b6e6146", "support" ], "server-timing/resources/parsing/68.js.sub.headers": [ @@ -369309,7 +369798,7 @@ "support" ], "server-timing/resources/parsing/69.js": [ - "235f1ee6973489be765e8edec753b94c9f6d5773", + "0ab0b4d6a9b95a749e9292da467f0fb58a729012", "support" ], "server-timing/resources/parsing/69.js.sub.headers": [ @@ -369317,7 +369806,7 @@ "support" ], "server-timing/resources/parsing/7.js": [ - "266ee41ae7b440ab43e87a087d10fa2b1e193a8f", + "3e2173bd78dca0e60e6fee7ad9e893010195234e", "support" ], "server-timing/resources/parsing/7.js.sub.headers": [ @@ -369325,7 +369814,7 @@ "support" ], "server-timing/resources/parsing/70.js": [ - "1a6924ba411a7f92aef048336bd117ece499f90a", + "db03fe36244bd2c07fc92720fd1d24825f9a4d11", "support" ], "server-timing/resources/parsing/70.js.sub.headers": [ @@ -369333,7 +369822,7 @@ "support" ], "server-timing/resources/parsing/71.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/71.js.sub.headers": [ @@ -369341,7 +369830,7 @@ "support" ], "server-timing/resources/parsing/72.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/72.js.sub.headers": [ @@ -369349,7 +369838,7 @@ "support" ], "server-timing/resources/parsing/73.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/73.js.sub.headers": [ @@ -369357,7 +369846,7 @@ "support" ], "server-timing/resources/parsing/74.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/74.js.sub.headers": [ @@ -369365,7 +369854,7 @@ "support" ], "server-timing/resources/parsing/75.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/75.js.sub.headers": [ @@ -369373,7 +369862,7 @@ "support" ], "server-timing/resources/parsing/76.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/76.js.sub.headers": [ @@ -369381,7 +369870,7 @@ "support" ], "server-timing/resources/parsing/77.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/77.js.sub.headers": [ @@ -369389,7 +369878,7 @@ "support" ], "server-timing/resources/parsing/78.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/78.js.sub.headers": [ @@ -369397,7 +369886,7 @@ "support" ], "server-timing/resources/parsing/79.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/79.js.sub.headers": [ @@ -369405,7 +369894,7 @@ "support" ], "server-timing/resources/parsing/8.js": [ - "e30f08cfab17bcd0229ebbf0da701f65a193485b", + "e049716bbac11f558b9fc61af72941a702f8cfb6", "support" ], "server-timing/resources/parsing/8.js.sub.headers": [ @@ -369413,7 +369902,7 @@ "support" ], "server-timing/resources/parsing/80.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/80.js.sub.headers": [ @@ -369421,7 +369910,7 @@ "support" ], "server-timing/resources/parsing/81.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/81.js.sub.headers": [ @@ -369429,7 +369918,7 @@ "support" ], "server-timing/resources/parsing/82.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/82.js.sub.headers": [ @@ -369437,7 +369926,7 @@ "support" ], "server-timing/resources/parsing/83.js": [ - "4b374f4e2751e3c75af68df671c0287e41d617ae", + "5d6b847c554a9c38b97f1a540db9375b47b6208f", "support" ], "server-timing/resources/parsing/83.js.sub.headers": [ @@ -369445,7 +369934,7 @@ "support" ], "server-timing/resources/parsing/9.js": [ - "30695307f7a50b46a799f3cf6f5763a359acc0ce", + "5660bb21eb42f322a58f80c6c001d14c6e0fc0c9", "support" ], "server-timing/resources/parsing/9.js.sub.headers": [ @@ -369453,7 +369942,7 @@ "support" ], "server-timing/server_timing_header-parsing.html": [ - "15768941cac8f5adeed09e6d204715d5fa59e5aa", + "bde9c39ce610bd7178800f92f3181bef3cd55918", "testharness" ], "server-timing/test_server_timing.html": [ @@ -375164,12 +375653,8 @@ "4713dfec8b4277cc29520dbd25958bd74e440c19", "testharness" ], - "url/urlsearchparams-foreach-expected.txt": [ - "fce6b61e524374ce234726c4e21063b99b646757", - "support" - ], "url/urlsearchparams-foreach.html": [ - "5bdc17d623884a8916681f19df55c4bef5965ff2", + "604154351de9db97183b3cfc149d3ca6c5132723", "testharness" ], "url/urlsearchparams-get.html": [ @@ -375860,12 +376345,8 @@ "d9fc177ebbc3fa0317125912e38a4bfd65f727c8", "testharness" ], - "web-animations/interfaces/Document/getAnimations-expected.txt": [ - "a61dc959961b5e6c389e2bb04c1930f04c4ff66a", - "support" - ], "web-animations/interfaces/Document/getAnimations.html": [ - "7fbd5eed47955fdaeccd329f82f0884b86654784", + "41edbdf1f03889156068f38d87875387f129924f", "testharness" ], "web-animations/interfaces/Document/timeline.html": [ @@ -377693,7 +378174,7 @@ "testharness" ], "webrtc/RTCPeerConnection-getStats.https-expected.txt": [ - "47ec6999d09c69c52a69e71104ea7bbc6f4cea36", + "dde1a0f72c91a106ed9b6bc05da5a287a3e2fb86", "support" ], "webrtc/RTCPeerConnection-getStats.https.html": [ @@ -377873,11 +378354,11 @@ "testharness" ], "webrtc/RTCPeerConnection-track-stats.https-expected.txt": [ - "0125406c581e8a3a0f309575374ff6e26a83d947", + "e0a6ac0951476e880e81895409db5c97a97063ec", "support" ], "webrtc/RTCPeerConnection-track-stats.https.html": [ - "55ab0ca3d364b020320fa45a14e50d2897dda13a", + "512e40d1b6f95c86b90ba7b536b6ae049f6a04c0", "testharness" ], "webrtc/RTCPeerConnectionIceEvent-constructor-expected.txt": [ @@ -383056,6 +383537,10 @@ "12d12036aa5937ae79aa152468cc574ac4bf4e94", "testharness" ], + "workers/interfaces/WorkerUtils/WindowTimers/005.html": [ + "11f0d7b6ea4a3c883d6c5cc8bde52c8ae9f7091b", + "testharness" + ], "workers/interfaces/WorkerUtils/importScripts/001.worker.js": [ "138e3be5d6375c8a784faabb4f2f4c82c2423bc3", "testharness" @@ -384296,6 +384781,14 @@ "9a27f71e6e5738d2625ed30f91f3d514fc3646e8", "testharness" ], + "xhr/header-user-agent-async.htm": [ + "07833728cf33836e854681d8e53c2b5357f8f810", + "testharness" + ], + "xhr/header-user-agent-sync.htm": [ + "e7f02cf698647785d332e4ad517ff0df357eea70", + "testharness" + ], "xhr/headers-normalize-response-expected.txt": [ "beeb26685c597767e2b460f6b62ea3f0a9966554", "support" @@ -384732,6 +385225,10 @@ "a191134704e09ff9bb6591dc8c6aa78307edf6c9", "support" ], + "xhr/resources/header-user-agent.py": [ + "26af60bcffd2c78dd7ee89a98a02fde12aee41a9", + "support" + ], "xhr/resources/headers-basic.asis": [ "718e90fc73ec596127d26fba5433c5355e93fa3f", "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/FileAPI/url/sandboxed-iframe-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/url/sandboxed-iframe-expected.txt index b40122b..41e6cc0 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/FileAPI/url/sandboxed-iframe-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/FileAPI/url/sandboxed-iframe-expected.txt
@@ -6,7 +6,7 @@ PASS Blob URL parses correctly PASS Origin of Blob URL matches our origin for Files PASS Blob URLs can be used in XHR -FAIL XHR with a fragment should succeed promise_test: Unhandled rejection with value: "Got unexpected error event" +PASS XHR with a fragment should succeed PASS XHR of a revoked URL should fail PASS Only exact matches should revoke URLs, using XHR PASS Appending a query string should cause XHR to fail @@ -20,7 +20,7 @@ PASS XHR should return Content-Type from Blob FAIL Revoke blob URL after open(), will fetch assert_unreached: Got unexpected error event Reached unreachable code PASS Blob URLs can be used in fetch -FAIL fetch with a fragment should succeed promise_test: Unhandled rejection with value: object "TypeError: Failed to fetch" +PASS fetch with a fragment should succeed PASS fetch of a revoked URL should fail PASS Only exact matches should revoke URLs, using fetch PASS Appending a query string should cause fetch to fail
diff --git a/third_party/WebKit/LayoutTests/external/wpt/bluetooth/idl/idl-Bluetooth.html b/third_party/WebKit/LayoutTests/external/wpt/bluetooth/idl/idl-Bluetooth.https.html similarity index 100% rename from third_party/WebKit/LayoutTests/external/wpt/bluetooth/idl/idl-Bluetooth.html rename to third_party/WebKit/LayoutTests/external/wpt/bluetooth/idl/idl-Bluetooth.https.html
diff --git a/third_party/WebKit/LayoutTests/external/wpt/bluetooth/resources/bluetooth-helpers.js b/third_party/WebKit/LayoutTests/external/wpt/bluetooth/resources/bluetooth-helpers.js index f3dc8b7..725e56d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/bluetooth/resources/bluetooth-helpers.js +++ b/third_party/WebKit/LayoutTests/external/wpt/bluetooth/resources/bluetooth-helpers.js
@@ -469,6 +469,15 @@ }]; } +// Causes |fake_peripheral| to disconnect and returns a promise that resolves +// once `gattserverdisconnected` has been fired on |device|. +function simulateGATTDisconnectionAndWait(device, fake_peripheral) { + return Promise.all([ + eventPromise(device, 'gattserverdisconnected'), + fake_peripheral.simulateGATTDisconnection(), + ]); +} + // Simulates a pre-connected device with |address|, |name| and // |knownServiceUUIDs|. function setUpPreconnectedDevice({
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/child-navigates-parent-allowed.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/child-navigates-parent-allowed.html index 3848c2f..6c05478 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/child-navigates-parent-allowed.html +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/child-navigates-parent-allowed.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <head> +<meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> @@ -15,4 +16,4 @@ <iframe srcdoc="<iframe src='support/navigate_parent.sub.html?csp=navigate-to%20%27self%27'>"> -</body> \ No newline at end of file +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/child-navigates-parent-blocked.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/child-navigates-parent-blocked.html index a5bea3ff..b665b7a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/child-navigates-parent-blocked.html +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/child-navigates-parent-blocked.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <head> +<meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> @@ -16,4 +17,4 @@ <iframe srcdoc="<iframe src='support/navigate_parent.sub.html?csp=navigate-to%20%27none%27'>"> -</body> \ No newline at end of file +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-allowed.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-allowed.html index 977b85d..3f7f678 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-allowed.html +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-allowed.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <head> +<meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> @@ -13,4 +14,4 @@ }); </script> <iframe src="support/link_click_navigation.sub.html?csp=navigate-to%20%27self%27&target=post_message_to_frame_owner.html"> -</body> \ No newline at end of file +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-blocked.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-blocked.html index 6817da2..65de768 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-blocked.html +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-blocked.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <head> +<meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> @@ -14,4 +15,4 @@ }); </script> <iframe src="support/link_click_navigation.sub.html?csp=navigate-to%20%27none%27&target=post_message_to_frame_owner.html"> -</body> \ No newline at end of file +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-cross-origin-allowed.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-cross-origin-allowed.sub.html index 4381bcb..360ede37 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-cross-origin-allowed.sub.html +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-cross-origin-allowed.sub.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <head> +<meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> @@ -13,4 +14,4 @@ }); </script> <iframe src="support/link_click_navigation.sub.html?csp=navigate-to%20http%3A%2F%2F{{domains[www1]}}:{{ports[http][0]}}&target=http%3A%2F%2F{{domains[www1]}}:{{ports[http][0]}}%2Fcontent-security-policy%2Fnavigate-to%2Fsupport%2Fpost_message_to_frame_owner.html"> -</body> \ No newline at end of file +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-cross-origin-blocked.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-cross-origin-blocked.sub.html index 1041506e..50f258ba 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-cross-origin-blocked.sub.html +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-cross-origin-blocked.sub.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <head> +<meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> @@ -14,4 +15,4 @@ }); </script> <iframe src="support/link_click_navigation.sub.html?csp=navigate-to%20%27self%27&target=http%3A%2F%2F{{domains[www1]}}:{{ports[http][0]}}%2Fcontent-security-policy%2Fnavigate-to%2Fsupport%2Fpost_message_to_frame_owner.html"> -</body> \ No newline at end of file +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-redirected-allowed.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-redirected-allowed.html index 87dea95..e75a7e5a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-redirected-allowed.html +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-redirected-allowed.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <head> +<meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> @@ -13,4 +14,4 @@ }); </script> <iframe src="support/link_click_navigation.sub.html?csp=navigate-to%20%27self%27&target=redirect_to_post_message_to_frame_owner.py"> -</body> \ No newline at end of file +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-redirected-blocked.sub.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-redirected-blocked.sub.html index f0bf4df..355e2c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-redirected-blocked.sub.html +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/navigate-to/link-click-redirected-blocked.sub.html
@@ -1,6 +1,7 @@ <!DOCTYPE html> <head> +<meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> </head> @@ -14,4 +15,4 @@ }); </script> <iframe src="support/link_click_navigation.sub.html?csp=navigate-to%20{{location[server]}}/content-security-policy/navigate-to/support/redirect_to_post_message_to_frame_owner.py&target=redirect_to_post_message_to_frame_owner.py"> -</body> \ No newline at end of file +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/prefetch-src/prefetch-allowed.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/prefetch-src/prefetch-allowed.html index e103a9f..95177c1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/prefetch-src/prefetch-allowed.html +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/prefetch-src/prefetch-allowed.html
@@ -1,20 +1,27 @@ <!DOCTYPE html> <html> <head> - <meta http-equiv="Content-Security-Policy" content="prefetch-src 'self'"> <script src='/resources/testharness.js'></script> <script src='/resources/testharnessreport.js'></script> <script src='/content-security-policy/support/testharness-helper.js'></script> <script src='/content-security-policy/support/prefetch-helper.js'></script> <script> async_test(t => { - let url = window.origin + '/content-security-policy/support/pass.png'; + var win = window.open('/content-security-policy/support/' + + 'file-prefetch-allowed.html'); + win.addEventListener('load', function () { + // Cache control headers are added,since they are needed + // to enable prefetching. + let url = '/content-security-policy/support/pass.png' + + '?pipe=header(Cache-Control, max-age=604800)'; - let link = document.createElement('link'); - link.rel = 'prefetch'; - link.href = url; - - assert_link_prefetches(t, link); + // Link element is created on the new opened window. + let link = win.document.createElement('link'); + link.rel = 'prefetch'; + link.href = url; + assert_link_prefetches(t, link); + win.close(); + }, false); }, 'Prefetch succeeds when allowed by prefetch-src'); </script> </head>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/file-prefetch-allowed.html b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/file-prefetch-allowed.html new file mode 100644 index 0000000..bd60d262 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/support/file-prefetch-allowed.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> +<head> + <!-- CSP directive 'prefetch-src' is not supported via meta tag though --> + <meta http-equiv="Content-Security-Policy" content="prefetch-src 'self'"> +</head> +<body> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-001.xht b/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-001.xht index 28ff467..ce5d4c6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-001.xht +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-001.xht
@@ -6,8 +6,8 @@ <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2013-08-05 --> <link rel="help" href="http://www.w3.org/TR/css3-multicol/#column-gap" title="4.1. 'column-gap'" /> <link rel="match" href="multicol-gap-001-ref.xht" /> - <meta name="flags" content="ahem may" /> - <meta name="assert" content="This test checks that the 'normal' column gap is 1em, which is suggested -- and not prescribed -- by the specification." /> + <meta name="flags" content="ahem" /> + <meta name="assert" content="This test checks that the 'normal' column gap is 1em." /> <style type="text/css"><![CDATA[ div {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-003.xht b/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-003.xht index 180fd3c..33011b8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-003.xht +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-multicol/multicol-gap-003.xht
@@ -6,7 +6,7 @@ <link rel="reviewer" title="Gérard Talbot" href="http://www.gtalbot.org/BrowserBugsSection/css21testsuite/" /> <!-- 2013-08-05 --> <link rel="help" href="http://www.w3.org/TR/css3-multicol/#column-gap" title="4.1. 'column-gap'" /> <link rel="match" href="multicol-gap-002-ref.xht" /> - <meta name="flags" content="ahem may" /> + <meta name="flags" content="ahem" /> <style type="text/css"><![CDATA[ div {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/shadow-reassign-dynamic-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/shadow-reassign-dynamic-001.html new file mode 100644 index 0000000..e8fe49a --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-scoping/shadow-reassign-dynamic-001.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSS Scoping: Dynamic reassignment of a slot.</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="help" href="https://drafts.csswg.org/css-scoping/#selectors-data-model"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1435632"> +<link rel="match" href="reference/green-box.html"/> +<div id="host"> + <div id="green" style="background: green"></div> + <div id="red" style="background: red" slot="myslot"></div> +</div> +<script> + let root = host.attachShadow({ mode: "open" }); + root.innerHTML = ` + <style>::slotted(div) { width: 100px; height: 100px }</style> + <p>Test passes if you see a single 100px by 100px green box below.</p> + <slot name="myslot">FAIL</slot> + `; + document.body.offsetTop; + green.setAttribute("slot", "myslot"); + red.removeAttribute("slot"); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/cssom-getBoxQuads-001-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/cssom-getBoxQuads-001-expected.txt new file mode 100644 index 0000000..900edfa8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/cssom-getBoxQuads-001-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +FAIL CSSOM View - getBoxQuads() returns proper border and margin boxes for block and flex bb.getBoxQuads is not a function +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/cssom-getBoxQuads-001.html b/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/cssom-getBoxQuads-001.html new file mode 100644 index 0000000..813c245 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/cssom-view/cssom-getBoxQuads-001.html
@@ -0,0 +1,51 @@ +<!DOCTYPE html> +<html> + <head> + <title>CSSOM View - getBoxQuads() returns proper border and margin boxes for block and flex</title> + <link rel="help" href="https://drafts.csswg.org/cssom-view/#the-geometryutils-interface"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + + <style> + .container { + width: 100px; + height: 50px; + background-color: gray; + } + span { + display: block; + background: gold; + height: 4px; + width: 14px; + margin: auto; + padding: 0px; + border: 3px solid blue; + } + </style> + </head> + <body> + <div class="container"> + <span id="block-block"></span> + </div> + + <div class="container" style="display:flex"> + <span id="flex-block"></span> + </div> + + <script> + test(function() { + let bb = document.getElementById("block-block"); + assert_equals(bb.getBoxQuads({box: "border"})[0].bounds.width, 20, "Block layout border box is expected width."); + assert_equals(bb.getBoxQuads({box: "margin"})[0].bounds.width, 100, "Block layout margin box is expected width."); + + // For containers that expand items to fill block-axis space, measure the box heights also. + let fb = document.getElementById("flex-block"); + assert_equals(fb.getBoxQuads({box: "border"})[0].bounds.width, 20, "Flex layout border box is expected width."); + assert_equals(fb.getBoxQuads({box: "margin"})[0].bounds.width, 100, "Flex layout margin box is expected width."); + + assert_equals(fb.getBoxQuads({box: "border"})[0].bounds.height, 10, "Flex layout border box is expected height."); + assert_equals(fb.getBoxQuads({box: "margin"})[0].bounds.height, 50, "Flex layout margin box is expected height."); + }); + </script> + </body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002-ref.html new file mode 100644 index 0000000..876e5d6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002-ref.html
@@ -0,0 +1,44 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <meta charset="utf-8"> + <title>CSS Reftest Reference</title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <style> + .tealBlock { + background: teal; + width: 10px; + height: 10px; + margin-bottom: 5px; + } + .purpleBlock { + background: purple; + width: 10px; + height: 10px; + margin-bottom: 5px; + } + </style> +</head> +<body> + + <div class="purpleBlock"></div> + <div class="purpleBlock"></div> + <div class="purpleBlock"></div> + <div class="purpleBlock"></div> + + <div class="tealBlock"></div> + <div class="tealBlock"></div> + <div class="tealBlock"></div> + <div class="tealBlock"></div> + + <div class="tealBlock"></div> + <div class="tealBlock"></div> + <div class="tealBlock"></div> + <div class="tealBlock"></div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002.html new file mode 100644 index 0000000..2bbb5f0 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-abspos-child-002.html
@@ -0,0 +1,62 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <meta charset="utf-8"> + <title> + CSS Test: Test that "flex-basis" doesn't affect layout of abspos flex child + </title> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="http://www.w3.org/TR/css-flexbox-1/#abspos-items"> + <link rel="match" href="flexbox-abspos-child-001-ref.html"> + <style> + .flex { + display: flex; + height: 10px; + width: 10px; + background: purple; + margin-bottom: 5px; + position: relative; + } + .flex > * { + position: absolute; + background: teal; + height: 10px; + } + .sized { + width: 10px; + } + .implied { + left: 0; + right: 0; + } + </style> +</head> +<body> + <!-- In all cases below, flex-basis should have no effect on layout (because + it's on an element that is abspos and hence not a flex item). --> + + <!-- Abspos child has auto width (which should end up 0): --> + <div class="flex"><div style="flex-basis: 2px"></div></div> + <div class="flex"><div style="flex-basis: 100px"></div></div> + <div class="flex"><div style="flex-basis: 80%"></div></div> + <div class="flex"><div style="flex-basis: content"></div></div> + + <!-- Abspos child has explicit 10px width: --> + <div class="flex"><div class="sized" style="flex-basis: 2px"></div></div> + <div class="flex"><div class="sized" style="flex-basis: 100px"></div></div> + <div class="flex"><div class="sized" style="flex-basis: 80%"></div></div> + <div class="flex"><div class="sized" style="flex-basis: content"></div></div> + + <!-- Abspos child has implicit 10px width (implied by auto width and + constrained left/right properties): --> + <div class="flex"><div class="implied" style="flex-basis: 2px"></div></div> + <div class="flex"><div class="implied" style="flex-basis: 100px"></div></div> + <div class="flex"><div class="implied" style="flex-basis: 80%"></div></div> + <div class="flex"><div class="implied" style="flex-basis: content"></div></div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001-ref.html new file mode 100644 index 0000000..b537711 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001-ref.html
@@ -0,0 +1,77 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title>CSS Reftest Reference</title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: row; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-bottom: 2em; + height: 50px; + width: 200px; + } + + .container > * { + flex-shrink: 0; + min-width: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas width="20"></canvas> +</div> + +<!-- Various specified main-size values, in testcase + (removed here in reference case, because they shouldn't affect sizing): --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas width="20"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="height: 0px">a b</div> + <div class="bigText" style="height: 40px">c</div> + <div class="spacerChild" style="height: 20px"></div> + <div class="justPadding" style="height: 10px"></div> + <canvas width="20" style="height: 8px"></canvas> +</div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001a.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001a.html new file mode 100644 index 0000000..4227f68 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001a.html
@@ -0,0 +1,83 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing "flex-basis: content" in a row-oriented flex container + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#propdef-flex-basis"> + <link rel="match" href="flexbox-flex-basis-content-001-ref.html"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: row; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-bottom: 2em; + height: 50px; + width: 200px; + } + + .container > * { + /* All flex items have "flex-basis: content" (and zero flex-shrink and + min-main-size, to avoid any influence from those). */ + flex-basis: content; + flex-shrink: 0; + min-width: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas width="20"></canvas> +</div> + +<!-- Various specified main-size values (should be ignored): --> +<div class="container"> + <div class="smallText" style="width: 0px">a b</div> + <div class="bigText" style="width: 40px">c</div> + <div class="spacerChild" style="width: 20px"></div> + <div class="justPadding" style="width: 10px"></div> + <canvas width="20" style="width: 8px"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="height: 0px">a b</div> + <div class="bigText" style="height: 40px">c</div> + <div class="spacerChild" style="height: 20px"></div> + <div class="justPadding" style="height: 10px"></div> + <canvas width="20" style="height: 8px"></canvas> +</div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001b.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001b.html new file mode 100644 index 0000000..489ce65 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-001b.html
@@ -0,0 +1,83 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing "flex-basis: content" (set via the "flex" shorthand) + in a row-oriented flex container. + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#propdef-flex-basis"> + <link rel="match" href="flexbox-flex-basis-content-001-ref.html"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: row; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-bottom: 2em; + height: 50px; + width: 200px; + } + + .container > * { + /* All flex items have "flex-basis: content" (and zero flex-shrink and + min-main-size, to avoid any influence from those). */ + flex: 0 0 content; + min-width: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas width="20"></canvas> +</div> + +<!-- Various specified main-size values (should be ignored): --> +<div class="container"> + <div class="smallText" style="width: 0px">a b</div> + <div class="bigText" style="width: 40px">c</div> + <div class="spacerChild" style="width: 20px"></div> + <div class="justPadding" style="width: 10px"></div> + <canvas width="20" style="width: 8px"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="height: 0px">a b</div> + <div class="bigText" style="height: 40px">c</div> + <div class="spacerChild" style="height: 20px"></div> + <div class="justPadding" style="height: 10px"></div> + <canvas width="20" style="height: 8px"></canvas> +</div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002-ref.html new file mode 100644 index 0000000..a7d1bcf --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002-ref.html
@@ -0,0 +1,78 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title>CSS Reftest Reference</title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: column; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-right: 2em; + width: 50px; + height: 200px; + float: left; + } + + .container > * { + flex-shrink: 0; + min-height: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas height="20"></canvas> +</div> + +<!-- Various specified main-size values, in testcase + (removed here in reference case, because they shouldn't affect sizing): --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas height="20"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="width: 0px">a b</div> + <div class="bigText" style="width: 40px">c</div> + <div class="spacerChild" style="width: 20px"></div> + <div class="justPadding" style="width: 10px"></div> + <canvas height="20" style="width: 8px"></canvas> +</div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002a.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002a.html new file mode 100644 index 0000000..481a3f22 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002a.html
@@ -0,0 +1,84 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing "flex-basis: content" in a column-oriented flex container + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#propdef-flex-basis"> + <link rel="match" href="flexbox-flex-basis-content-002-ref.html"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: column; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-right: 2em; + width: 50px; + height: 200px; + float: left; + } + + .container > * { + /* All flex items have "flex-basis: content" (and zero flex-shrink and + min-main-size, to avoid any influence from those). */ + flex-basis: content; + flex-shrink: 0; + min-height: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas height="20"></canvas> +</div> + +<!-- Various specified main-size values (should be ignored): --> +<div class="container"> + <div class="smallText" style="height: 0px">a b</div> + <div class="bigText" style="height: 40px">c</div> + <div class="spacerChild" style="height: 20px"></div> + <div class="justPadding" style="height: 10px"></div> + <canvas height="20" style="height: 8px"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="width: 0px">a b</div> + <div class="bigText" style="width: 40px">c</div> + <div class="spacerChild" style="width: 20px"></div> + <div class="justPadding" style="width: 10px"></div> + <canvas height="20" style="width: 8px"></canvas> +</div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002b.html b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002b.html new file mode 100644 index 0000000..694e672 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/vendor-imports/mozilla/mozilla-central-reftests/flexbox/flexbox-flex-basis-content-002b.html
@@ -0,0 +1,84 @@ +<!DOCTYPE html> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html> +<head> + <title> + CSS Test: Testing "flex-basis: content" (set via the "flex" shorthand) + in a column-oriented flex container. + </title> + <meta charset="utf-8"> + <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com"> + <link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#propdef-flex-basis"> + <link rel="match" href="flexbox-flex-basis-content-002-ref.html"> + <link rel="stylesheet" type="text/css" href="support/ahem.css"> + <style> + .container { + display: flex; + flex-direction: column; + justify-content: space-between; + border: 2px solid purple; + padding: 2px; + margin-right: 2em; + width: 50px; + height: 200px; + float: left; + } + + .container > * { + /* All flex items have "flex-basis: content" (and zero flex-shrink and + min-main-size, to avoid any influence from those). */ + flex: 0 0 content; + min-height: 0; + border: 2px solid teal; + } + + .smallText { font: 10px Ahem; } + .bigText { font: 20px Ahem; } + .spacerChild::before { + content: ''; + display: block; + background: brown; + height: 10px; + width: 10px; + } + .justPadding { + /* Empty div with 5px padding on each side */ + padding: 5px; + background: cyan; + } + canvas { background: fuchsia } + </style> +</head> +<body> +<!-- Flex items have unspecified size properties: --> +<div class="container"> + <div class="smallText">a b</div> + <div class="bigText">c</div> + <div class="spacerChild"></div> + <div class="justPadding"></div> + <canvas height="20"></canvas> +</div> + +<!-- Various specified main-size values (should be ignored): --> +<div class="container"> + <div class="smallText" style="height: 0px">a b</div> + <div class="bigText" style="height: 40px">c</div> + <div class="spacerChild" style="height: 20px"></div> + <div class="justPadding" style="height: 10px"></div> + <canvas height="20" style="height: 8px"></canvas> +</div> + +<!-- Various specified cross-size values (should be honored): --> +<div class="container"> + <div class="smallText" style="width: 0px">a b</div> + <div class="bigText" style="width: 40px">c</div> + <div class="spacerChild" style="width: 20px"></div> + <div class="justPadding" style="width: 10px"></div> + <canvas height="20" style="width: 8px"></canvas> +</div> + +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/HTMLElement-constructor-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/HTMLElement-constructor-expected.txt new file mode 100644 index 0000000..ca5b35f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/HTMLElement-constructor-expected.txt
@@ -0,0 +1,18 @@ +This is a testharness.js-based test. +PASS HTMLElement constructor must throw a TypeError when NewTarget is equal to itself +PASS HTMLElement constructor must throw a TypeError when NewTarget is equal to itself via a Proxy object +PASS HTMLElement constructor must throw TypeError when it has not been defined by customElements.define +PASS Custom element constructor must throw TypeError when it does not extend HTMLElement +PASS Custom element constructor must throw TypeError when it does not extend the proper element interface +PASS HTMLElement constructor must infer the tag name from the element interface +PASS HTMLElement constructor must allow subclassing a custom element +PASS HTMLElement constructor must allow subclassing an user-defined subclass of HTMLElement +FAIL HTMLElement constructor must only get .prototype once, calling proxy constructor directly assert_equals: Should have gotten .prototype once expected 1 but got 2 +FAIL HTMLElement constructor must only get .prototype once, calling proxy constructor via Reflect assert_equals: Should have gotten .prototype once expected 1 but got 2 +FAIL HTMLElement constructor must only get .prototype once, calling proxy constructor via Reflect with no inheritance assert_equals: Should have gotten .prototype once expected 1 but got 2 +FAIL HTMLElement constructor must not get .prototype until it finishes its extends sanity checks, calling proxy constructor directly assert_equals: Should never have gotten .prototype expected 0 but got 1 +FAIL HTMLElement constructor must not get .prototype until it finishes its extends sanity checks, calling via Reflect assert_equals: Should never have gotten .prototype expected 0 but got 1 +FAIL HTMLElement constructor must not get .prototype until it finishes its registration sanity checks, calling proxy constructor directly assert_equals: Should never have gotten .prototype expected 0 but got 1 +FAIL HTMLElement constructor must not get .prototype until it finishes its registration sanity checks, calling via Reflect assert_equals: Should never have gotten .prototype expected 0 but got 1 +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/HTMLElement-constructor.html b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/HTMLElement-constructor.html index cb6d540..a0bfa90 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/HTMLElement-constructor.html +++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/HTMLElement-constructor.html
@@ -91,6 +91,159 @@ }, 'HTMLElement constructor must allow subclassing an user-defined subclass of HTMLElement'); +test(function() { + class SomeCustomElement extends HTMLElement {}; + var getCount = 0; + var countingProxy = new Proxy(SomeCustomElement, { + get: function(target, prop, receiver) { + if (prop == "prototype") { + ++getCount; + } + return Reflect.get(target, prop, receiver); + } + }); + customElements.define("success-counting-element-1", countingProxy); + // define() gets the prototype of the constructor it's passed, so + // reset the counter. + getCount = 0; + var instance = new countingProxy(); + assert_equals(getCount, 1, "Should have gotten .prototype once"); + assert_true(instance instanceof countingProxy); + assert_true(instance instanceof HTMLElement); + assert_true(instance instanceof SomeCustomElement); + assert_equals(instance.localName, "success-counting-element-1"); + assert_equals(instance.nodeName, "SUCCESS-COUNTING-ELEMENT-1"); +}, 'HTMLElement constructor must only get .prototype once, calling proxy constructor directly'); + +test(function() { + class SomeCustomElement extends HTMLElement {}; + var getCount = 0; + var countingProxy = new Proxy(SomeCustomElement, { + get: function(target, prop, receiver) { + if (prop == "prototype") { + ++getCount; + } + return Reflect.get(target, prop, receiver); + } + }); + customElements.define("success-counting-element-2", countingProxy); + // define() gets the prototype of the constructor it's passed, so + // reset the counter. + getCount = 0; + var instance = Reflect.construct(HTMLElement, [], countingProxy); + assert_equals(getCount, 1, "Should have gotten .prototype once"); + assert_true(instance instanceof countingProxy); + assert_true(instance instanceof HTMLElement); + assert_true(instance instanceof SomeCustomElement); + assert_equals(instance.localName, "success-counting-element-2"); + assert_equals(instance.nodeName, "SUCCESS-COUNTING-ELEMENT-2"); +}, 'HTMLElement constructor must only get .prototype once, calling proxy constructor via Reflect'); + +test(function() { + class SomeCustomElement {}; + var getCount = 0; + var countingProxy = new Proxy(SomeCustomElement, { + get: function(target, prop, receiver) { + if (prop == "prototype") { + ++getCount; + } + return Reflect.get(target, prop, receiver); + } + }); + customElements.define("success-counting-element-3", countingProxy); + // define() gets the prototype of the constructor it's passed, so + // reset the counter. + getCount = 0; + var instance = Reflect.construct(HTMLElement, [], countingProxy); + assert_equals(getCount, 1, "Should have gotten .prototype once"); + assert_true(instance instanceof countingProxy); + assert_true(instance instanceof SomeCustomElement); + assert_equals(instance.localName, undefined); + assert_equals(instance.nodeName, undefined); +}, 'HTMLElement constructor must only get .prototype once, calling proxy constructor via Reflect with no inheritance'); + +test(function() { + class SomeCustomElement extends HTMLElement {}; + var getCount = 0; + var countingProxy = new Proxy(SomeCustomElement, { + get: function(target, prop, receiver) { + if (prop == "prototype") { + ++getCount; + } + return Reflect.get(target, prop, receiver); + } + }); + customElements.define("failure-counting-element-1", countingProxy, + { extends: "button" }); + // define() gets the prototype of the constructor it's passed, so + // reset the counter. + getCount = 0; + assert_throws({'name': 'TypeError'}, + function () { new countingProxy() }, + "Should not be able to construct an HTMLElement named 'button'"); + assert_equals(getCount, 0, "Should never have gotten .prototype"); +}, 'HTMLElement constructor must not get .prototype until it finishes its extends sanity checks, calling proxy constructor directly'); + +test(function() { + class SomeCustomElement extends HTMLElement {}; + var getCount = 0; + var countingProxy = new Proxy(SomeCustomElement, { + get: function(target, prop, receiver) { + if (prop == "prototype") { + ++getCount; + } + return Reflect.get(target, prop, receiver); + } + }); + customElements.define("failure-counting-element-2", countingProxy, + { extends: "button" }); + // define() gets the prototype of the constructor it's passed, so + // reset the counter. + getCount = 0; + assert_throws({'name': 'TypeError'}, + function () { Reflect.construct(HTMLElement, [], countingProxy) }, + "Should not be able to construct an HTMLElement named 'button'"); + assert_equals(getCount, 0, "Should never have gotten .prototype"); +}, 'HTMLElement constructor must not get .prototype until it finishes its extends sanity checks, calling via Reflect'); + +test(function() { + class SomeCustomElement extends HTMLElement {}; + var getCount = 0; + var countingProxy = new Proxy(SomeCustomElement, { + get: function(target, prop, receiver) { + if (prop == "prototype") { + ++getCount; + } + return Reflect.get(target, prop, receiver); + } + }); + + // Purposefully don't register it. + assert_throws({'name': 'TypeError'}, + function () { new countingProxy() }, + "Should not be able to construct an HTMLElement named 'button'"); + assert_equals(getCount, 0, "Should never have gotten .prototype"); +}, 'HTMLElement constructor must not get .prototype until it finishes its registration sanity checks, calling proxy constructor directly'); + +test(function() { + class SomeCustomElement extends HTMLElement {}; + var getCount = 0; + var countingProxy = new Proxy(SomeCustomElement, { + get: function(target, prop, receiver) { + if (prop == "prototype") { + ++getCount; + } + return Reflect.get(target, prop, receiver); + } + }); + + // Purposefully don't register it. + assert_throws({'name': 'TypeError'}, + function () { Reflect.construct(HTMLElement, [], countingProxy) }, + "Should not be able to construct an HTMLElement named 'button'"); + assert_equals(getCount, 0, "Should never have gotten .prototype"); +}, 'HTMLElement constructor must not get .prototype until it finishes its registration sanity checks, calling via Reflect'); </script> </body> </html> +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/htmlconstructor/newtarget-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/htmlconstructor/newtarget-expected.txt new file mode 100644 index 0000000..46c1cf2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/htmlconstructor/newtarget-expected.txt
@@ -0,0 +1,15 @@ +This is a testharness.js-based test. +PASS Use NewTarget's prototype, not the one stored at definition time +PASS Rethrow any exceptions thrown while getting the prototype +PASS If prototype is not object (null), derives the fallback from NewTarget's realm (autonomous custom elements) +PASS If prototype is not object (undefined), derives the fallback from NewTarget's realm (autonomous custom elements) +PASS If prototype is not object (5), derives the fallback from NewTarget's realm (autonomous custom elements) +PASS If prototype is not object (string), derives the fallback from NewTarget's realm (autonomous custom elements) +PASS If prototype is not object (null), derives the fallback from NewTarget's realm (customized built-in elements) +PASS If prototype is not object (undefined), derives the fallback from NewTarget's realm (customized built-in elements) +PASS If prototype is not object (5), derives the fallback from NewTarget's realm (customized built-in elements) +PASS If prototype is not object (string), derives the fallback from NewTarget's realm (customized built-in elements) +FAIL HTMLParagraphElement constructor must not get .prototype until it finishes its extends sanity checks, calling proxy constructor directly assert_equals: Should never have gotten .prototype expected 0 but got 1 +FAIL HTMLParagraphElement constructor must not get .prototype until it finishes its extends sanity checks, calling via Reflect assert_equals: Should never have gotten .prototype expected 0 but got 1 +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/htmlconstructor/newtarget.html b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/htmlconstructor/newtarget.html index ab43803..7dad264 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/custom-elements/htmlconstructor/newtarget.html +++ b/third_party/WebKit/LayoutTests/external/wpt/custom-elements/htmlconstructor/newtarget.html
@@ -124,5 +124,46 @@ }, "If prototype is not object (" + notAnObject + "), derives the fallback from NewTarget's realm (customized built-in elements)"); }); +test_with_window(w => { + class SomeCustomElement extends HTMLParagraphElement {}; + var getCount = 0; + var countingProxy = new Proxy(SomeCustomElement, { + get: function(target, prop, receiver) { + if (prop == "prototype") { + ++getCount; + } + return Reflect.get(target, prop, receiver); + } + }); + w.customElements.define("failure-counting-element", countingProxy); + // define() gets the prototype of the constructor it's passed, so + // reset the counter. + getCount = 0; + assert_throws({'name': 'TypeError'}, + function () { new countingProxy() }, + "Should not be able to construct an HTMLParagraphElement not named 'p'"); + assert_equals(getCount, 0, "Should never have gotten .prototype"); +}, 'HTMLParagraphElement constructor must not get .prototype until it finishes its extends sanity checks, calling proxy constructor directly'); + +test_with_window(w => { + class SomeCustomElement extends HTMLParagraphElement {}; + var getCount = 0; + var countingProxy = new Proxy(SomeCustomElement, { + get: function(target, prop, receiver) { + if (prop == "prototype") { + ++getCount; + } + return Reflect.get(target, prop, receiver); + } + }); + w.customElements.define("failure-counting-element", countingProxy); + // define() gets the prototype of the constructor it's passed, so + // reset the counter. + getCount = 0; + assert_throws({'name': 'TypeError'}, + function () { Reflect.construct(HTMLParagraphElement, [], countingProxy) }, + "Should not be able to construct an HTMLParagraphElement not named 'p'"); + assert_equals(getCount, 0, "Should never have gotten .prototype"); +}, 'HTMLParagraphElement constructor must not get .prototype until it finishes its extends sanity checks, calling via Reflect'); </script> -</body> \ No newline at end of file +</body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext-subframe.txt b/third_party/WebKit/LayoutTests/external/wpt/html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext-subframe.txt new file mode 100644 index 0000000..3e71550 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext-subframe.txt
@@ -0,0 +1 @@ +Some text.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext.window.js b/third_party/WebKit/LayoutTests/external/wpt/html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext.window.js new file mode 100644 index 0000000..52edd00 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/dom/dynamic-markup-insertion/opening-the-input-stream/type-argument-plaintext.window.js
@@ -0,0 +1,23 @@ +["replace", + "NOBODY", + "@ FD ;", + "it does not matter, you see \f", + "text/plain", + "text/xml", + "application/octet-stream", + "\0"].forEach(type => { + async_test(t => { + const frame = document.createElement("iframe"); + frame.src = "type-argument-plaintext-subframe.txt"; + document.body.appendChild(frame); + t.add_cleanup(() => frame.remove()); + frame.onload = t.step_func_done(() => { + frame.contentDocument.open(type); + frame.contentDocument.write("<B>heya</b>"); + frame.contentDocument.close(); + assert_equals(frame.contentDocument.body.firstChild.localName, "b"); + assert_equals(frame.contentDocument.body.textContent, "heya"); + assert_equals(frame.contentDocument.contentType, "text/plain"); + }); + }, "document.open() on plaintext document with type set to: " + type + " (type argument is supposed to be ignored)"); +});
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/text-level-semantics/the-a-element/a-download-click-404-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/text-level-semantics/the-a-element/a-download-click-404-expected.txt deleted file mode 100644 index d3c5fc6..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/text-level-semantics/the-a-element/a-download-click-404-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -FAIL Do not navigate to 404 for anchor with download Blocked a frame with origin "http://web-platform.test:8001" from accessing a cross-origin frame. -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/charset-parameter.window-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/charset-parameter.window-expected.txt index a6a7b25..5a6cb4b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/charset-parameter.window-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/charset-parameter.window-expected.txt
@@ -5,26 +5,34 @@ FAIL text/html;charset=gbk( assert_equals: expected "UTF-8" but got "GBK" PASS text/html;x=(;charset=gbk FAIL text/html;charset=gbk;charset=windows-1255 assert_equals: expected "GBK" but got "windows-1255" +FAIL text/html;charset=();charset=GBK assert_equals: expected "UTF-8" but got "GBK" PASS text/html;charset =gbk PASS text/html ;charset=gbk PASS text/html; charset=gbk PASS text/html;charset= gbk +FAIL text/html;charset= "gbk" assert_equals: expected "UTF-8" but got "GBK" PASS text/html;charset='gbk' PASS text/html;charset='gbk PASS text/html;charset=gbk' +FAIL text/html;charset=';charset=GBK assert_equals: expected "UTF-8" but got "GBK" PASS text/html;test;charset=gbk PASS text/html;test=;charset=gbk PASS text/html;';charset=gbk PASS text/html;";charset=gbk PASS text/html ; ; charset=gbk PASS text/html;;;;charset=gbk +FAIL text/html;charset= ";charset=GBK assert_equals: expected "GBK" but got "UTF-8" +PASS text/html;charset=";charset=foo";charset=GBK PASS text/html;charset="gbk" PASS text/html;charset="gbk PASS text/html;charset=gbk" FAIL text/html;charset=" gbk" assert_equals: expected "GBK" but got "UTF-8" +FAIL text/html;charset="gbk " assert_equals: expected "GBK" but got "UTF-8" FAIL text/html;charset="\ gbk" assert_equals: expected "GBK" but got "UTF-8" PASS text/html;charset="\g\b\k" PASS text/html;charset="gbk"x +PASS text/html;charset="";charset=GBK +PASS text/html;charset=";charset=GBK PASS text/html;charset={gbk} PASS text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk PASS text/html;test=ÿ;charset=gbk
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/parsing.any-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/parsing.any-expected.txt index 77f8830..c81d9773 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/parsing.any-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/parsing.any-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 1857 tests; 697 PASS, 1160 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 1873 tests; 699 PASS, 1174 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… PASS text/html;charset=gbk (Blob/File) PASS text/html;charset=gbk (Request/Response) @@ -11,6 +11,8 @@ FAIL text/html;x=(;charset=gbk (Request/Response) assert_equals: expected "text/html;x=\"(\";charset=gbk" but got "text/html;x=(;charset=gbk" FAIL text/html;charset=gbk;charset=windows-1255 (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=gbk;charset=windows-1255" FAIL text/html;charset=gbk;charset=windows-1255 (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=gbk;charset=windows-1255" +FAIL text/html;charset=();charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=\"()\"" but got "text/html;charset=();charset=gbk" +FAIL text/html;charset=();charset=GBK (Request/Response) assert_equals: expected "text/html;charset=\"()\"" but got "text/html;charset=();charset=gbk" FAIL text/html;charset =gbk (Blob/File) assert_equals: Blob expected "text/html" but got "text/html;charset =gbk" FAIL text/html;charset =gbk (Request/Response) assert_equals: expected "text/html" but got "text/html;charset =gbk" FAIL text/html ;charset=gbk (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html ;charset=gbk" @@ -19,12 +21,16 @@ FAIL text/html; charset=gbk (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html; charset=gbk" FAIL text/html;charset= gbk (Blob/File) assert_equals: Blob expected "text/html;charset=\" gbk\"" but got "text/html;charset= gbk" FAIL text/html;charset= gbk (Request/Response) assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html;charset= gbk" +FAIL text/html;charset= "gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=\" \\\"gbk\\"\"" but got "text/html;charset= \"gbk\"" +FAIL text/html;charset= "gbk" (Request/Response) assert_equals: expected "text/html;charset=\" \\\"gbk\\"\"" but got "text/html;charset= \"gbk\"" PASS text/html;charset='gbk' (Blob/File) PASS text/html;charset='gbk' (Request/Response) PASS text/html;charset='gbk (Blob/File) PASS text/html;charset='gbk (Request/Response) PASS text/html;charset=gbk' (Blob/File) PASS text/html;charset=gbk' (Request/Response) +FAIL text/html;charset=';charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset='" but got "text/html;charset=';charset=gbk" +FAIL text/html;charset=';charset=GBK (Request/Response) assert_equals: expected "text/html;charset='" but got "text/html;charset=';charset=gbk" FAIL text/html;test;charset=gbk (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;test;charset=gbk" FAIL text/html;test;charset=gbk (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;test;charset=gbk" FAIL text/html;test=;charset=gbk (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;test=;charset=gbk" @@ -37,6 +43,10 @@ FAIL text/html ; ; charset=gbk (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html ; ; charset=gbk" FAIL text/html;;;;charset=gbk (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;;;;charset=gbk" FAIL text/html;;;;charset=gbk (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;;;;charset=gbk" +FAIL text/html;charset= ";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=GBK" but got "" +FAIL text/html;charset= ";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=GBK" but got "" +FAIL text/html;charset=";charset=foo";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=GBK" but got "" +FAIL text/html;charset=";charset=foo";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=GBK" but got "" FAIL text/html;charset="gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"" FAIL text/html;charset="gbk" (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"" FAIL text/html;charset="gbk (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"gbk" @@ -45,12 +55,18 @@ FAIL text/html;charset=gbk" (Request/Response) assert_equals: expected "text/html;charset=\"gbk\\\"\"" but got "text/html;charset=gbk\"" PASS text/html;charset=" gbk" (Blob/File) PASS text/html;charset=" gbk" (Request/Response) +PASS text/html;charset="gbk " (Blob/File) +PASS text/html;charset="gbk " (Request/Response) FAIL text/html;charset="\ gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=\" gbk\"" but got "text/html;charset=\"\\ gbk\"" FAIL text/html;charset="\ gbk" (Request/Response) assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html;charset=\"\\ gbk\"" FAIL text/html;charset="\g\b\k" (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\b\k\"" FAIL text/html;charset="\g\b\k" (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\b\k\"" FAIL text/html;charset="gbk"x (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"x" FAIL text/html;charset="gbk"x (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"x" +FAIL text/html;charset="";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=GBK" but got "text/html;charset=\"\";charset=gbk" +FAIL text/html;charset="";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=GBK" but got "text/html;charset=\"\";charset=gbk" +FAIL text/html;charset=";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=\";charset=GBK\"" but got "text/html;charset=\";charset=gbk" +FAIL text/html;charset=";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=\";charset=GBK\"" but got "text/html;charset=\";charset=gbk" FAIL text/html;charset={gbk} (Blob/File) assert_equals: Blob expected "text/html;charset=\"{gbk}\"" but got "text/html;charset={gbk}" FAIL text/html;charset={gbk} (Request/Response) assert_equals: expected "text/html;charset=\"{gbk}\"" but got "text/html;charset={gbk}" PASS text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk (Blob/File)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/parsing.any.worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/parsing.any.worker-expected.txt index 77f8830..c81d9773 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/parsing.any.worker-expected.txt +++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/parsing.any.worker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 1857 tests; 697 PASS, 1160 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 1873 tests; 699 PASS, 1174 FAIL, 0 TIMEOUT, 0 NOTRUN. PASS Loading data… PASS text/html;charset=gbk (Blob/File) PASS text/html;charset=gbk (Request/Response) @@ -11,6 +11,8 @@ FAIL text/html;x=(;charset=gbk (Request/Response) assert_equals: expected "text/html;x=\"(\";charset=gbk" but got "text/html;x=(;charset=gbk" FAIL text/html;charset=gbk;charset=windows-1255 (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=gbk;charset=windows-1255" FAIL text/html;charset=gbk;charset=windows-1255 (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=gbk;charset=windows-1255" +FAIL text/html;charset=();charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=\"()\"" but got "text/html;charset=();charset=gbk" +FAIL text/html;charset=();charset=GBK (Request/Response) assert_equals: expected "text/html;charset=\"()\"" but got "text/html;charset=();charset=gbk" FAIL text/html;charset =gbk (Blob/File) assert_equals: Blob expected "text/html" but got "text/html;charset =gbk" FAIL text/html;charset =gbk (Request/Response) assert_equals: expected "text/html" but got "text/html;charset =gbk" FAIL text/html ;charset=gbk (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html ;charset=gbk" @@ -19,12 +21,16 @@ FAIL text/html; charset=gbk (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html; charset=gbk" FAIL text/html;charset= gbk (Blob/File) assert_equals: Blob expected "text/html;charset=\" gbk\"" but got "text/html;charset= gbk" FAIL text/html;charset= gbk (Request/Response) assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html;charset= gbk" +FAIL text/html;charset= "gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=\" \\\"gbk\\"\"" but got "text/html;charset= \"gbk\"" +FAIL text/html;charset= "gbk" (Request/Response) assert_equals: expected "text/html;charset=\" \\\"gbk\\"\"" but got "text/html;charset= \"gbk\"" PASS text/html;charset='gbk' (Blob/File) PASS text/html;charset='gbk' (Request/Response) PASS text/html;charset='gbk (Blob/File) PASS text/html;charset='gbk (Request/Response) PASS text/html;charset=gbk' (Blob/File) PASS text/html;charset=gbk' (Request/Response) +FAIL text/html;charset=';charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset='" but got "text/html;charset=';charset=gbk" +FAIL text/html;charset=';charset=GBK (Request/Response) assert_equals: expected "text/html;charset='" but got "text/html;charset=';charset=gbk" FAIL text/html;test;charset=gbk (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;test;charset=gbk" FAIL text/html;test;charset=gbk (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;test;charset=gbk" FAIL text/html;test=;charset=gbk (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;test=;charset=gbk" @@ -37,6 +43,10 @@ FAIL text/html ; ; charset=gbk (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html ; ; charset=gbk" FAIL text/html;;;;charset=gbk (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;;;;charset=gbk" FAIL text/html;;;;charset=gbk (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;;;;charset=gbk" +FAIL text/html;charset= ";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=GBK" but got "" +FAIL text/html;charset= ";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=GBK" but got "" +FAIL text/html;charset=";charset=foo";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=GBK" but got "" +FAIL text/html;charset=";charset=foo";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=GBK" but got "" FAIL text/html;charset="gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"" FAIL text/html;charset="gbk" (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"" FAIL text/html;charset="gbk (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"gbk" @@ -45,12 +55,18 @@ FAIL text/html;charset=gbk" (Request/Response) assert_equals: expected "text/html;charset=\"gbk\\\"\"" but got "text/html;charset=gbk\"" PASS text/html;charset=" gbk" (Blob/File) PASS text/html;charset=" gbk" (Request/Response) +PASS text/html;charset="gbk " (Blob/File) +PASS text/html;charset="gbk " (Request/Response) FAIL text/html;charset="\ gbk" (Blob/File) assert_equals: Blob expected "text/html;charset=\" gbk\"" but got "text/html;charset=\"\\ gbk\"" FAIL text/html;charset="\ gbk" (Request/Response) assert_equals: expected "text/html;charset=\" gbk\"" but got "text/html;charset=\"\\ gbk\"" FAIL text/html;charset="\g\b\k" (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\b\k\"" FAIL text/html;charset="\g\b\k" (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"\\g\b\k\"" FAIL text/html;charset="gbk"x (Blob/File) assert_equals: Blob expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"x" FAIL text/html;charset="gbk"x (Request/Response) assert_equals: expected "text/html;charset=gbk" but got "text/html;charset=\"gbk\"x" +FAIL text/html;charset="";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=GBK" but got "text/html;charset=\"\";charset=gbk" +FAIL text/html;charset="";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=GBK" but got "text/html;charset=\"\";charset=gbk" +FAIL text/html;charset=";charset=GBK (Blob/File) assert_equals: Blob expected "text/html;charset=\";charset=GBK\"" but got "text/html;charset=\";charset=gbk" +FAIL text/html;charset=";charset=GBK (Request/Response) assert_equals: expected "text/html;charset=\";charset=GBK\"" but got "text/html;charset=\";charset=gbk" FAIL text/html;charset={gbk} (Blob/File) assert_equals: Blob expected "text/html;charset=\"{gbk}\"" but got "text/html;charset={gbk}" FAIL text/html;charset={gbk} (Request/Response) assert_equals: expected "text/html;charset=\"{gbk}\"" but got "text/html;charset={gbk}" PASS text/html;0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789=x;charset=gbk (Blob/File)
diff --git a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/mime-types.json b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/mime-types.json index 6bee02d..3dcdf55e 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/mime-types.json +++ b/third_party/WebKit/LayoutTests/external/wpt/mimesniff/mime-types/resources/mime-types.json
@@ -32,6 +32,12 @@ "navigable": true, "encoding": "GBK" }, + { + "input": "text/html;charset=();charset=GBK", + "output": "text/html;charset=\"()\"", + "navigable": true, + "encoding": null + }, "Spaces", { "input": "text/html;charset =gbk", @@ -57,6 +63,12 @@ "navigable": true, "encoding": "GBK" }, + { + "input": "text/html;charset= \"gbk\"", + "output": "text/html;charset=\" \\\"gbk\\\"\"", + "navigable": true, + "encoding": null + }, "Single quotes are a token, not a delimiter", { "input": "text/html;charset='gbk'", @@ -76,6 +88,12 @@ "navigable": true, "encoding": null }, + { + "input": "text/html;charset=';charset=GBK", + "output": "text/html;charset='", + "navigable": true, + "encoding": null + }, "Invalid parameters", { "input": "text/html;test;charset=gbk", @@ -113,6 +131,18 @@ "navigable": true, "encoding": "GBK" }, + { + "input": "text/html;charset= \"\u007F;charset=GBK", + "output": "text/html;charset=GBK", + "navigable": true, + "encoding": "GBK" + }, + { + "input": "text/html;charset=\"\u007F;charset=foo\";charset=GBK", + "output": "text/html;charset=GBK", + "navigable": true, + "encoding": "GBK" + }, "Double quotes", { "input": "text/html;charset=\"gbk\"", @@ -139,6 +169,12 @@ "encoding": "GBK" }, { + "input": "text/html;charset=\"gbk \"", + "output": "text/html;charset=\"gbk \"", + "navigable": true, + "encoding": "GBK" + }, + { "input": "text/html;charset=\"\\ gbk\"", "output": "text/html;charset=\" gbk\"", "navigable": true, @@ -156,6 +192,18 @@ "navigable": true, "encoding": "GBK" }, + { + "input": "text/html;charset=\"\";charset=GBK", + "output": "text/html;charset=GBK", + "navigable": true, + "encoding": "GBK" + }, + { + "input": "text/html;charset=\";charset=GBK", + "output": "text/html;charset=\";charset=GBK\"", + "navigable": true, + "encoding": null + }, "Unexpected code points", { "input": "text/html;charset={gbk}",
diff --git a/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-insecure.http.html b/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-insecure.http.html index 0212220..c097bf1 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-insecure.http.html +++ b/third_party/WebKit/LayoutTests/external/wpt/payment-request/payment-request-insecure.http.html
@@ -1,5 +1,4 @@ <!DOCTYPE html> -<!-- Copyright © 2017 Chromium authors and World Wide Web Consortium, (Massachusetts Institute of Technology, ERCIM, Keio University, Beihang). --> <meta charset="utf-8"> <title>Test for PaymentRequest Constructor (insecure)</title> <link rel="help" href="https://w3c.github.io/payment-request/#paymentrequest-interface"> @@ -8,6 +7,8 @@ <script> test(() => { assert_false(isSecureContext); - assert_false("PaymentRequest" in window); + assert_false('PaymentRequest' in window); + assert_false('PaymentResponse' in window); + assert_false('PaymentRequestUpdateEvent' in window); }, "PaymentRequest constructor must not be exposed in insecure context"); </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/fake_bluetooth.mojom.js b/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/fake_bluetooth.mojom.js index 08c26b6..a8d79556 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/fake_bluetooth.mojom.js +++ b/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/fake_bluetooth.mojom.js
@@ -2896,6 +2896,306 @@ encoder.skip(1); encoder.skip(1); }; + function FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.prototype.initDefaults_ = function() { + this.gattCode = 0; + this.characteristicId = null; + this.serviceId = null; + this.peripheralAddress = null; + }; + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 40} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + + // validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.characteristicId + err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) + if (err !== validator.validationError.NONE) + return err; + + + // validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.serviceId + err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) + if (err !== validator.validationError.NONE) + return err; + + + // validate FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.peripheralAddress + err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 24, false) + if (err !== validator.validationError.NONE) + return err; + + return validator.validationError.NONE; + }; + + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize = codec.kStructHeaderSize + 32; + + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.decode = function(decoder) { + var packed; + var val = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.gattCode = decoder.decodeStruct(codec.Uint16); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + val.characteristicId = decoder.decodeStruct(codec.String); + val.serviceId = decoder.decodeStruct(codec.String); + val.peripheralAddress = decoder.decodeStruct(codec.String); + return val; + }; + + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encode = function(encoder, val) { + var packed; + encoder.writeUint32(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize); + encoder.writeUint32(0); + encoder.encodeStruct(codec.Uint16, val.gattCode); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.encodeStruct(codec.String, val.characteristicId); + encoder.encodeStruct(codec.String, val.serviceId); + encoder.encodeStruct(codec.String, val.peripheralAddress); + }; + function FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.prototype.initDefaults_ = function() { + this.success = false; + }; + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 16} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + return validator.validationError.NONE; + }; + + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; + + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.decode = function(decoder) { + var packed; + var val = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + packed = decoder.readUint8(); + val.success = (packed >> 0) & 1 ? true : false; + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + return val; + }; + + FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encode = function(encoder, val) { + var packed; + encoder.writeUint32(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize); + encoder.writeUint32(0); + packed = 0; + packed |= (val.success & 1) << 0 + encoder.writeUint8(packed); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + }; + function FakeCentral_IsNotifying_Params(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + FakeCentral_IsNotifying_Params.prototype.initDefaults_ = function() { + this.characteristicId = null; + this.serviceId = null; + this.peripheralAddress = null; + }; + FakeCentral_IsNotifying_Params.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + FakeCentral_IsNotifying_Params.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 32} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + // validate FakeCentral_IsNotifying_Params.characteristicId + err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 0, false) + if (err !== validator.validationError.NONE) + return err; + + + // validate FakeCentral_IsNotifying_Params.serviceId + err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 8, false) + if (err !== validator.validationError.NONE) + return err; + + + // validate FakeCentral_IsNotifying_Params.peripheralAddress + err = messageValidator.validateStringPointer(offset + codec.kStructHeaderSize + 16, false) + if (err !== validator.validationError.NONE) + return err; + + return validator.validationError.NONE; + }; + + FakeCentral_IsNotifying_Params.encodedSize = codec.kStructHeaderSize + 24; + + FakeCentral_IsNotifying_Params.decode = function(decoder) { + var packed; + var val = new FakeCentral_IsNotifying_Params(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + val.characteristicId = decoder.decodeStruct(codec.String); + val.serviceId = decoder.decodeStruct(codec.String); + val.peripheralAddress = decoder.decodeStruct(codec.String); + return val; + }; + + FakeCentral_IsNotifying_Params.encode = function(encoder, val) { + var packed; + encoder.writeUint32(FakeCentral_IsNotifying_Params.encodedSize); + encoder.writeUint32(0); + encoder.encodeStruct(codec.String, val.characteristicId); + encoder.encodeStruct(codec.String, val.serviceId); + encoder.encodeStruct(codec.String, val.peripheralAddress); + }; + function FakeCentral_IsNotifying_ResponseParams(values) { + this.initDefaults_(); + this.initFields_(values); + } + + + FakeCentral_IsNotifying_ResponseParams.prototype.initDefaults_ = function() { + this.success = false; + this.isNotifying = false; + }; + FakeCentral_IsNotifying_ResponseParams.prototype.initFields_ = function(fields) { + for(var field in fields) { + if (this.hasOwnProperty(field)) + this[field] = fields[field]; + } + }; + + FakeCentral_IsNotifying_ResponseParams.validate = function(messageValidator, offset) { + var err; + err = messageValidator.validateStructHeader(offset, codec.kStructHeaderSize); + if (err !== validator.validationError.NONE) + return err; + + var kVersionSizes = [ + {version: 0, numBytes: 16} + ]; + err = messageValidator.validateStructVersion(offset, kVersionSizes); + if (err !== validator.validationError.NONE) + return err; + + + + return validator.validationError.NONE; + }; + + FakeCentral_IsNotifying_ResponseParams.encodedSize = codec.kStructHeaderSize + 8; + + FakeCentral_IsNotifying_ResponseParams.decode = function(decoder) { + var packed; + var val = new FakeCentral_IsNotifying_ResponseParams(); + var numberOfBytes = decoder.readUint32(); + var version = decoder.readUint32(); + packed = decoder.readUint8(); + val.success = (packed >> 0) & 1 ? true : false; + val.isNotifying = (packed >> 1) & 1 ? true : false; + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + decoder.skip(1); + return val; + }; + + FakeCentral_IsNotifying_ResponseParams.encode = function(encoder, val) { + var packed; + encoder.writeUint32(FakeCentral_IsNotifying_ResponseParams.encodedSize); + encoder.writeUint32(0); + packed = 0; + packed |= (val.success & 1) << 0 + packed |= (val.isNotifying & 1) << 1 + encoder.writeUint8(packed); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + encoder.skip(1); + }; function FakeCentral_GetLastWrittenCharacteristicValue_Params(values) { this.initDefaults_(); this.initFields_(values); @@ -3786,10 +4086,12 @@ var kFakeCentral_SetNextReadCharacteristicResponse_Name = 12; var kFakeCentral_SetNextWriteCharacteristicResponse_Name = 13; var kFakeCentral_SetNextSubscribeToNotificationsResponse_Name = 14; - var kFakeCentral_GetLastWrittenCharacteristicValue_Name = 15; - var kFakeCentral_SetNextReadDescriptorResponse_Name = 16; - var kFakeCentral_SetNextWriteDescriptorResponse_Name = 17; - var kFakeCentral_GetLastWrittenDescriptorValue_Name = 18; + var kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name = 15; + var kFakeCentral_IsNotifying_Name = 16; + var kFakeCentral_GetLastWrittenCharacteristicValue_Name = 17; + var kFakeCentral_SetNextReadDescriptorResponse_Name = 18; + var kFakeCentral_SetNextWriteDescriptorResponse_Name = 19; + var kFakeCentral_GetLastWrittenDescriptorValue_Name = 20; function FakeCentralPtr(handleOrPtrInfo) { this.ptr = new bindings.InterfacePtrController(FakeCentral, @@ -4211,6 +4513,61 @@ }); }.bind(this)); }; + FakeCentralPtr.prototype.setNextUnsubscribeFromNotificationsResponse = function() { + return FakeCentralProxy.prototype.setNextUnsubscribeFromNotificationsResponse + .apply(this.ptr.getProxy(), arguments); + }; + + FakeCentralProxy.prototype.setNextUnsubscribeFromNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) { + var params = new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params(); + params.gattCode = gattCode; + params.characteristicId = characteristicId; + params.serviceId = serviceId; + params.peripheralAddress = peripheralAddress; + return new Promise(function(resolve, reject) { + var builder = new codec.MessageV1Builder( + kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name, + codec.align(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params.encodedSize), + codec.kMessageExpectsResponse, 0); + builder.encodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params, params); + var message = builder.finish(); + this.receiver_.acceptAndExpectResponse(message).then(function(message) { + var reader = new codec.MessageReader(message); + var responseParams = + reader.decodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams); + resolve(responseParams); + }).catch(function(result) { + reject(Error("Connection error: " + result)); + }); + }.bind(this)); + }; + FakeCentralPtr.prototype.isNotifying = function() { + return FakeCentralProxy.prototype.isNotifying + .apply(this.ptr.getProxy(), arguments); + }; + + FakeCentralProxy.prototype.isNotifying = function(characteristicId, serviceId, peripheralAddress) { + var params = new FakeCentral_IsNotifying_Params(); + params.characteristicId = characteristicId; + params.serviceId = serviceId; + params.peripheralAddress = peripheralAddress; + return new Promise(function(resolve, reject) { + var builder = new codec.MessageV1Builder( + kFakeCentral_IsNotifying_Name, + codec.align(FakeCentral_IsNotifying_Params.encodedSize), + codec.kMessageExpectsResponse, 0); + builder.encodeStruct(FakeCentral_IsNotifying_Params, params); + var message = builder.finish(); + this.receiver_.acceptAndExpectResponse(message).then(function(message) { + var reader = new codec.MessageReader(message); + var responseParams = + reader.decodeStruct(FakeCentral_IsNotifying_ResponseParams); + resolve(responseParams); + }).catch(function(result) { + reject(Error("Connection error: " + result)); + }); + }.bind(this)); + }; FakeCentralPtr.prototype.getLastWrittenCharacteristicValue = function() { return FakeCentralProxy.prototype.getLastWrittenCharacteristicValue .apply(this.ptr.getProxy(), arguments); @@ -4374,6 +4731,12 @@ FakeCentralStub.prototype.setNextSubscribeToNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) { return this.delegate_ && this.delegate_.setNextSubscribeToNotificationsResponse && this.delegate_.setNextSubscribeToNotificationsResponse(gattCode, characteristicId, serviceId, peripheralAddress); } + FakeCentralStub.prototype.setNextUnsubscribeFromNotificationsResponse = function(gattCode, characteristicId, serviceId, peripheralAddress) { + return this.delegate_ && this.delegate_.setNextUnsubscribeFromNotificationsResponse && this.delegate_.setNextUnsubscribeFromNotificationsResponse(gattCode, characteristicId, serviceId, peripheralAddress); + } + FakeCentralStub.prototype.isNotifying = function(characteristicId, serviceId, peripheralAddress) { + return this.delegate_ && this.delegate_.isNotifying && this.delegate_.isNotifying(characteristicId, serviceId, peripheralAddress); + } FakeCentralStub.prototype.getLastWrittenCharacteristicValue = function(characteristicId, serviceId, peripheralAddress) { return this.delegate_ && this.delegate_.getLastWrittenCharacteristicValue && this.delegate_.getLastWrittenCharacteristicValue(characteristicId, serviceId, peripheralAddress); } @@ -4637,6 +5000,39 @@ responder.accept(message); }); return true; + case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name: + var params = reader.decodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params); + this.setNextUnsubscribeFromNotificationsResponse(params.gattCode, params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { + var responseParams = + new FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams(); + responseParams.success = response.success; + var builder = new codec.MessageV1Builder( + kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name, + codec.align(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams.encodedSize), + codec.kMessageIsResponse, reader.requestID); + builder.encodeStruct(FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams, + responseParams); + var message = builder.finish(); + responder.accept(message); + }); + return true; + case kFakeCentral_IsNotifying_Name: + var params = reader.decodeStruct(FakeCentral_IsNotifying_Params); + this.isNotifying(params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { + var responseParams = + new FakeCentral_IsNotifying_ResponseParams(); + responseParams.success = response.success; + responseParams.isNotifying = response.isNotifying; + var builder = new codec.MessageV1Builder( + kFakeCentral_IsNotifying_Name, + codec.align(FakeCentral_IsNotifying_ResponseParams.encodedSize), + codec.kMessageIsResponse, reader.requestID); + builder.encodeStruct(FakeCentral_IsNotifying_ResponseParams, + responseParams); + var message = builder.finish(); + responder.accept(message); + }); + return true; case kFakeCentral_GetLastWrittenCharacteristicValue_Name: var params = reader.decodeStruct(FakeCentral_GetLastWrittenCharacteristicValue_Params); this.getLastWrittenCharacteristicValue(params.characteristicId, params.serviceId, params.peripheralAddress).then(function(response) { @@ -4772,6 +5168,14 @@ if (message.expectsResponse()) paramsClass = FakeCentral_SetNextSubscribeToNotificationsResponse_Params; break; + case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name: + if (message.expectsResponse()) + paramsClass = FakeCentral_SetNextUnsubscribeFromNotificationsResponse_Params; + break; + case kFakeCentral_IsNotifying_Name: + if (message.expectsResponse()) + paramsClass = FakeCentral_IsNotifying_Params; + break; case kFakeCentral_GetLastWrittenCharacteristicValue_Name: if (message.expectsResponse()) paramsClass = FakeCentral_GetLastWrittenCharacteristicValue_Params; @@ -4858,6 +5262,14 @@ if (message.isResponse()) paramsClass = FakeCentral_SetNextSubscribeToNotificationsResponse_ResponseParams; break; + case kFakeCentral_SetNextUnsubscribeFromNotificationsResponse_Name: + if (message.isResponse()) + paramsClass = FakeCentral_SetNextUnsubscribeFromNotificationsResponse_ResponseParams; + break; + case kFakeCentral_IsNotifying_Name: + if (message.isResponse()) + paramsClass = FakeCentral_IsNotifying_ResponseParams; + break; case kFakeCentral_GetLastWrittenCharacteristicValue_Name: if (message.isResponse()) paramsClass = FakeCentral_GetLastWrittenCharacteristicValue_ResponseParams;
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/web-bluetooth-test.js b/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/web-bluetooth-test.js index e08c8c4a..1700b04 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/web-bluetooth-test.js +++ b/third_party/WebKit/LayoutTests/external/wpt/resources/chromium/web-bluetooth-test.js
@@ -393,6 +393,30 @@ if (!success) throw 'setNextSubscribeToNotificationsResponse failed'; } + // Sets the next unsubscribe to notifications response for characteristic with + // |characteristic_id| in |service_id| and in |peripheral_address| to + // |code|. |code| could be a GATT Error Response from BT 4.2 Vol 3 Part F + // 3.4.1.1 Error Response or a number outside that range returned by + // specific platforms e.g. Android returns 0x101 to signal a GATT failure. + async setNextUnsubscribeFromNotificationsResponse(gatt_code) { + let {success} = + await this.fake_central_ptr_.setNextUnsubscribeFromNotificationsResponse( + gatt_code, ...this.ids_); + + if (!success) throw 'setNextUnsubscribeToNotificationsResponse failed'; + } + + // Returns true if notifications from the characteristic have been subscribed + // to. + async isNotifying() { + let {success, isNotifying} = + await this.fake_central_ptr_.isNotifying(...this.ids_); + + if (!success) throw 'isNotifying failed'; + + return isNotifying; + } + // Gets the last successfully written value to the characteristic. // Returns null if no value has yet been written to the characteristic. async getLastWrittenValue() {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/cross_origin.html b/third_party/WebKit/LayoutTests/external/wpt/server-timing/cross_origin.html index 80035888..f525103 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/cross_origin.html +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/cross_origin.html
@@ -4,13 +4,16 @@ <script src="/resources/testharness.js"></script> <script src='/resources/testharnessreport.js'></script> <script src="/common/performance-timeline-utils.js"></script> + <script src="/common/get-host-info.sub.js"></script> <script> setup({explicit_done: true}) - const {location: {href}} = document - const urls = {} - urls['same-origin'] = `${href.substring(0, href.lastIndexOf('/'))}/resources/blue.png` - urls['cross-origin'] = urls['same-origin'].replace('://', '://www.') + const hostInfo = get_host_info() + const resourceUrl = 'server-timing/resources/blue.png' + const urls = { + 'same-origin': `${hostInfo.HTTP_ORIGIN}/${resourceUrl}`, + 'cross-origin': `${hostInfo.HTTP_REMOTE_ORIGIN}/${resourceUrl}` + } Object.keys(urls).forEach(function(key) { const img = document.createElement('img') img.src = urls[key]
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/0.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/0.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/0.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/0.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/1.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/1.js index 220cf1a..03b778b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/1.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/1.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric"}]) +testServerTiming(document.currentScript, [{"name":"metric"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/10.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/10.js index 220cf1a..03b778b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/10.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/10.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric"}]) +testServerTiming(document.currentScript, [{"name":"metric"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/11.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/11.js index 220cf1a..03b778b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/11.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/11.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric"}]) +testServerTiming(document.currentScript, [{"name":"metric"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/12.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/12.js index c32491d..fc827f8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/12.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/12.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":123.4,"desc":"description"}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":123.4,"desc":"description"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/13.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/13.js index 9b767142..02f8c3c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/13.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/13.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"description","dur":123.4}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"description","dur":123.4}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/14.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/14.js index 153607bf..966e963 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/14.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/14.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"description"}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"description"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/15.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/15.js index 311cabe..afef77d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/15.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/15.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric1","dur":12.3,"desc":"description1"},{"name":"metric2","dur":45.6,"desc":"description2"},{"name":"metric3","dur":78.9,"desc":"description3"}]) +testServerTiming(document.currentScript, [{"name":"metric1","dur":12.3,"desc":"description1"},{"name":"metric2","dur":45.6,"desc":"description2"},{"name":"metric3","dur":78.9,"desc":"description3"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/16.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/16.js index ab8597f..b49b1785 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/16.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/16.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric1"},{"name":"metric2"},{"name":"metric3"},{"name":"metric4"},{"name":"metric5"}]) +testServerTiming(document.currentScript, [{"name":"metric1"},{"name":"metric2"},{"name":"metric3"},{"name":"metric4"},{"name":"metric5"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/17.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/17.js index 153607bf..966e963 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/17.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/17.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"description"}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"description"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/18.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/18.js index 5924751..3c47d76 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/18.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/18.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"\t description \t"}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"\t description \t"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/19.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/19.js index d8cc6b72..83fb4f3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/19.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/19.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"descr\"iption"}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"descr\"iption"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/2.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/2.js index 6fd97fa..b763b814 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/2.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/2.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":123.4}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":123.4}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/20.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/20.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/20.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/20.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/21.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/21.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/21.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/21.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/22.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/22.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/22.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/22.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/23.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/23.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/23.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/23.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/24.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/24.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/24.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/24.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/25.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/25.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/25.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/25.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/26.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/26.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/26.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/26.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/27.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/27.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/27.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/27.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/28.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/28.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/28.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/28.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/29.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/29.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/29.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/29.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/3.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/3.js index 6fd97fa..b763b814 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/3.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/3.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":123.4}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":123.4}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/30.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/30.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/30.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/30.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/31.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/31.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/31.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/31.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/32.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/32.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/32.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/32.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/33.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/33.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/33.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/33.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/34.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/34.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/34.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/34.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/35.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/35.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/35.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/35.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/36.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/36.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/36.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/36.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/37.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/37.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/37.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/37.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/38.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/38.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/38.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/38.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/39.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/39.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/39.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/39.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/4.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/4.js index 153607bf..966e963 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/4.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/4.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"description"}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"description"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/40.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/40.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/40.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/40.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/41.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/41.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/41.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/41.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/42.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/42.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/42.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/42.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/43.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/43.js index b318cb7..f3ac7dc 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/43.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/43.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"\\"}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"\\"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/44.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/44.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/44.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/44.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/45.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/45.js index 993a690..82de6a40 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/45.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/45.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"\""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"\""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/46.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/46.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/46.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/46.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/47.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/47.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/47.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/47.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/48.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/48.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/48.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/48.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/49.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/49.js index 107695e..349a7e0dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/49.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/49.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":""}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":""}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/5.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/5.js index 153607bf..966e963 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/5.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/5.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"description"}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"description"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/50.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/50.js index 61ec691..413d9b6 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/50.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/50.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":12.3,"desc":"description1"},{"name":"metric","dur":45.6,"desc":"description2"}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":12.3,"desc":"description1"},{"name":"metric","dur":45.6,"desc":"description2"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/51.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/51.js index c32491d..fc827f8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/51.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/51.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":123.4,"desc":"description"}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":123.4,"desc":"description"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/52.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/52.js index 6617af5..a97e9d0 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/52.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/52.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"MeTrIc","desc":"DeScRiPtIoN"}]) +testServerTiming(document.currentScript, [{"name":"MeTrIc","desc":"DeScRiPtIoN"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/53.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/53.js index 40faf41..adf74fa 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/53.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/53.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":0}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":0}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/54.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/54.js index 40faf41..adf74fa 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/54.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/54.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":0}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":0}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/55.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/55.js index 4e2b14b..429b528 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/55.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/55.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric1","desc":"description","dur":123.4},{"name":"metric2"}]) +testServerTiming(document.currentScript, [{"name":"metric1","desc":"description","dur":123.4},{"name":"metric2"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/56.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/56.js index 6fd97fa..b763b814 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/56.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/56.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":123.4}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":123.4}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/57.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/57.js index 40faf41..adf74fa 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/57.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/57.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":0}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":0}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/58.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/58.js index 13250bb..05004e5 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/58.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/58.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"description1"}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"description1"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/59.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/59.js index 0282f7d..c9a9a98 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/59.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/59.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":0,"desc":"description"}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":0,"desc":"description"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/6.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/6.js index c32491d..fc827f8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/6.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/6.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":123.4,"desc":"description"}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":123.4,"desc":"description"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/60.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/60.js index 0282f7d..c9a9a98 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/60.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/60.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":0,"desc":"description"}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":0,"desc":"description"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/61.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/61.js index 62b744cc..ce7d800 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/61.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/61.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"","dur":123.4}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"","dur":123.4}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/62.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/62.js index 62b744cc..ce7d800 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/62.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/62.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"","dur":123.4}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"","dur":123.4}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/63.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/63.js index 839f8064..d6842ba 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/63.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/63.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"d1","dur":123.4}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"d1","dur":123.4}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/64.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/64.js index d64ea0a9..88037d15d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/64.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/64.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric1","desc":"d1"},{"name":"metric2"}]) +testServerTiming(document.currentScript, [{"name":"metric1","desc":"d1"},{"name":"metric2"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/65.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/65.js index 839f8064..d6842ba 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/65.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/65.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"d1","dur":123.4}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"d1","dur":123.4}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/66.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/66.js index d64ea0a9..88037d15d 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/66.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/66.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric1","desc":"d1"},{"name":"metric2"}]) +testServerTiming(document.currentScript, [{"name":"metric1","desc":"d1"},{"name":"metric2"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/67.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/67.js index 220cf1a..03b778b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/67.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/67.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric"}]) +testServerTiming(document.currentScript, [{"name":"metric"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/68.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/68.js index 4077b26a..e6946c3 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/68.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/68.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric1"}]) +testServerTiming(document.currentScript, [{"name":"metric1"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/69.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/69.js index 40faf41..adf74fa 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/69.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/69.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","dur":0}]) +testServerTiming(document.currentScript, [{"name":"metric","dur":0}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/7.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/7.js index 9b767142..02f8c3c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/7.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/7.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"description","dur":123.4}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"description","dur":123.4}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/70.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/70.js index 220cf1a..03b778b 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/70.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/70.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric"}]) +testServerTiming(document.currentScript, [{"name":"metric"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/71.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/71.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/71.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/71.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/72.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/72.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/72.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/72.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/73.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/73.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/73.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/73.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/74.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/74.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/74.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/74.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/75.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/75.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/75.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/75.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/76.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/76.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/76.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/76.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/77.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/77.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/77.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/77.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/78.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/78.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/78.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/78.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/79.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/79.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/79.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/79.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/8.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/8.js index 8581efd9..711e381 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/8.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/8.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"aB3!#$%&'*+-.^_`|~"}]) +testServerTiming(document.currentScript, [{"name":"aB3!#$%&'*+-.^_`|~"}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/80.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/80.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/80.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/80.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/81.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/81.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/81.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/81.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/82.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/82.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/82.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/82.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/83.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/83.js index 8de2c01..2848a1c8 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/83.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/83.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, []) +testServerTiming(document.currentScript, [])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/9.js b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/9.js index e03b07a2..3048f3fa 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/9.js +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/resources/parsing/9.js
@@ -1 +1 @@ -testServerTiming(document.currentScript.src, [{"name":"metric","desc":"descr;,=iption","dur":123.4}]) +testServerTiming(document.currentScript, [{"name":"metric","desc":"descr;,=iption","dur":123.4}])
diff --git a/third_party/WebKit/LayoutTests/external/wpt/server-timing/server_timing_header-parsing.html b/third_party/WebKit/LayoutTests/external/wpt/server-timing/server_timing_header-parsing.html index a598a71..4049c3dd 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/server-timing/server_timing_header-parsing.html +++ b/third_party/WebKit/LayoutTests/external/wpt/server-timing/server_timing_header-parsing.html
@@ -11,28 +11,40 @@ <script src="/common/performance-timeline-utils.js"></script> <script> setup({explicit_done: true}) - function testServerTiming(resource, expectedResults) { - const {serverTiming} = performance.getEntriesByName(resource)[0] - const fileName = resource.substring(resource.lastIndexOf('/') + 1) - test_equals(serverTiming.length, expectedResults.length, `${fileName} - count (${serverTiming.length} ?== ${expectedResults.length})`) + const tests = [] + const urlToIndex = {} + function testServerTiming(script, expectedResults) { + const url = script.src + tests[urlToIndex[url]] = {url, expectedResults} + } + function runTests() { + tests.forEach(function({url, expectedResults}) { + debugger; + const {serverTiming} = performance.getEntriesByName(url)[0] + const fileName = url.substring(url.lastIndexOf('/') + 1) - expectedResults.forEach(function(expectedResult, i) { - const dur = expectedResult.dur || 0 - const desc = expectedResult.desc || '' - const index = expectedResults.length === 1 ? '' : `[${i}].` - test_equals(expectedResult.name, serverTiming[i].name, - `${fileName} - ${index}name (${expectedResult.name} ?== ${serverTiming[i].name})`) - test_equals(dur, serverTiming[i].duration, - `${fileName} - ${index}duration (${dur} ?== ${serverTiming[i].duration})`) - test_equals(desc, serverTiming[i].description, - `${fileName} - ${index}description (${desc} ?== ${serverTiming[i].description})`) + test_equals(serverTiming.length, expectedResults.length, `${fileName} - count (${serverTiming.length} ?== ${expectedResults.length})`) + + expectedResults.forEach(function(expectedResult, i) { + const dur = expectedResult.dur || 0 + const desc = expectedResult.desc || '' + const index = expectedResults.length === 1 ? '' : `[${i}].` + test_equals(expectedResult.name, serverTiming[i].name, + `${fileName} - ${index}name (${expectedResult.name} ?== ${serverTiming[i].name})`) + test_equals(dur, serverTiming[i].duration, + `${fileName} - ${index}duration (${dur} ?== ${serverTiming[i].duration})`) + test_equals(desc, serverTiming[i].description, + `${fileName} - ${index}description (${desc} ?== ${serverTiming[i].description})`) + }) }) + done() } for (let i = 0; i <= 83; i++) { - var script = document.createElement('script') + const script = document.createElement('script') script.src = `./resources/parsing/${i}.js` document.getElementsByTagName('head')[0].appendChild(script) + urlToIndex[script.src] = i } - window.addEventListener('load', done) + window.addEventListener('load', runTests) </script> </head>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/WorkerUtils/WindowTimers/005.html b/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/WorkerUtils/WindowTimers/005.html new file mode 100644 index 0000000..b86eff1 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/workers/interfaces/WorkerUtils/WindowTimers/005.html
@@ -0,0 +1,23 @@ +<!-- +self.close(); +var t = setInterval(function() {}, 10); +postMessage(t); +/* +--> +<!doctype html> +<title>setInterval when closing</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id=log></div> +<script> +async_test(function() { + var worker = new Worker('#'); + worker.onmessage = this.step_func(function(e) { + assert_equals(e.data, 1); + this.done(); + }); +}); +</script> +<!-- +*/ +//-->
diff --git a/third_party/WebKit/LayoutTests/external/wpt/xhr/header-user-agent-async.htm b/third_party/WebKit/LayoutTests/external/wpt/xhr/header-user-agent-async.htm new file mode 100644 index 0000000..8c1d0b6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/xhr/header-user-agent-async.htm
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test that async requests (both OPTIONS preflight and regular) are sent with the User-Agent header</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/common/get-host-info.sub.js"></script> +</head> +<body> +<script type="text/javascript"> + async_test((test) => { + let xhr = new XMLHttpRequest; + xhr.open("GET", get_host_info().HTTP_REMOTE_ORIGIN + "/xhr/resources/header-user-agent.py"); + xhr.setRequestHeader("x-test", "foobar"); + + xhr.onerror = test.unreached_func("Unexpected error"); + + xhr.onload = test.step_func_done(() => { + assert_equals(xhr.responseText, "PASS"); + }); + + xhr.send(); + }, "Async request has User-Agent header"); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/xhr/header-user-agent-sync.htm b/third_party/WebKit/LayoutTests/external/wpt/xhr/header-user-agent-sync.htm new file mode 100644 index 0000000..d88aac2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/xhr/header-user-agent-sync.htm
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> +<head> + <title>Test that sync requests (both OPTIONS preflight and regular) are sent with the User-Agent header</title> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/common/get-host-info.sub.js"></script> +</head> +<body> +<script type="text/javascript"> + test(function() { + let xhr = new XMLHttpRequest; + xhr.open("post", get_host_info().HTTP_REMOTE_ORIGIN + "/xhr/resources/header-user-agent.py", false); + xhr.setRequestHeader("x-test", "foobar"); + xhr.send(); + assert_equals(xhr.responseText, "PASS"); + }, "Sync request has User-Agent header"); +</script> +</body> +</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/xhr/resources/header-user-agent.py b/third_party/WebKit/LayoutTests/external/wpt/xhr/resources/header-user-agent.py new file mode 100644 index 0000000..4778de4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/xhr/resources/header-user-agent.py
@@ -0,0 +1,15 @@ +def main(request, response): + response.headers.set("Access-Control-Allow-Origin", "*") + response.headers.set("Access-Control-Max-Age", 0) + response.headers.set('Access-Control-Allow-Headers', "x-test") + + if request.method == "OPTIONS": + if not request.headers.get("User-Agent"): + response.content = "FAIL: User-Agent header missing in preflight request." + response.status = 400 + else: + if request.headers.get("User-Agent"): + response.content = "PASS" + else: + response.content = "FAIL: User-Agent header missing in request" + response.status = 400
diff --git a/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-background-size-longhand.html b/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-background-size-longhand.html new file mode 100644 index 0000000..796b415 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-background-size-longhand.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +'use strict'; + +test(() => { + let NegativeBackgroundSize = 2402; // From web_feature.mojom + + let isCounted = () => internals.isUseCounted(document, NegativeBackgroundSize); + var div = document.createElement('div'); + + div.style = 'background-size: 1px 2px;'; + div.style = '-webkit-mask-size: -1px -2px;'; + assert_false(isCounted(), + '-webkit-mask-size should not be counted'); + + div.style = 'background-size: 1px -2px;'; + assert_true(isCounted(), + 'background-size should be counted'); +}, 'Negative size is use counted for background-size'); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-background-size-shorthand.html b/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-background-size-shorthand.html new file mode 100644 index 0000000..e9cdaa4 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-background-size-shorthand.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +'use strict'; + +test(() => { + let NegativeBackgroundSize = 2402; // From web_feature.mojom + + let isCounted = () => internals.isUseCounted(document, NegativeBackgroundSize); + var div = document.createElement('div'); + + div.style = 'background: none, red none 50% 50% / 1px 2px round space local padding-box content-box;'; + div.style = '-webkit-mask: none -1px -2px, none -3px -4px;'; + assert_false(isCounted(), + '-webkit-mask should not be counted'); + + div.style = 'background: none, red none 50% 50% / -1px 2px round space local padding-box content-box;'; + assert_true(isCounted(), + 'background should be counted'); +}, 'Negative size is use counted for background-size in shorthand'); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-mask-size-longhand.html b/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-mask-size-longhand.html new file mode 100644 index 0000000..4c77f5b --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-mask-size-longhand.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +'use strict'; + +test(() => { + let NegativeMaskSize = 2403; // From web_feature.mojom + + let isCounted = () => internals.isUseCounted(document, NegativeMaskSize); + var div = document.createElement('div'); + + div.style = '-webkit-mask-size: 1px 2px;'; + div.style = 'background-size: -1px -2px;'; + assert_false(isCounted(), + 'background-size should not be counted'); + + div.style = '-webkit-mask-size: 1px -2px;'; + assert_true(isCounted(), + '-webkit-mask-size should be counted'); +}, 'Negative size is use counted for -webkit-mask-size'); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-mask-size-shorthand.html b/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-mask-size-shorthand.html new file mode 100644 index 0000000..8b3b516 --- /dev/null +++ b/third_party/WebKit/LayoutTests/fast/css/usecounter-negative-mask-size-shorthand.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<script> +'use strict'; + +test(() => { + let NegativeMaskSize = 2403; // From web_feature.mojom + + let isCounted = () => internals.isUseCounted(document, NegativeMaskSize); + var div = document.createElement('div'); + + div.style = '-webkit-mask: -3px -4px / 1px 2px;'; + div.style = 'background: none, red none 50% 50% / -1px -2px round space local padding-box content-box;'; + assert_false(isCounted(), + 'background should not be counted'); + + div.style = '-webkit-mask: 3px 4px / -1px 2px;'; + assert_true(isCounted(), + '-webkit-mask should be counted'); +}, 'Negative size is use counted for -webkit-mask-size in shorthand'); +</script>
diff --git a/third_party/WebKit/LayoutTests/fast/dom/HTMLAreaElement/area-download-expected.txt b/third_party/WebKit/LayoutTests/fast/dom/HTMLAreaElement/area-download-expected.txt index edf7cec..f95efff 100644 --- a/third_party/WebKit/LayoutTests/fast/dom/HTMLAreaElement/area-download-expected.txt +++ b/third_party/WebKit/LayoutTests/fast/dom/HTMLAreaElement/area-download-expected.txt
@@ -1,2 +1,2 @@ -Downloading URL with suggested filename "foo" +Download started
diff --git a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-AddRemoveTrack.html b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-AddRemoveTrack.html index 811f19e..f177172 100644 --- a/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-AddRemoveTrack.html +++ b/third_party/WebKit/LayoutTests/fast/peerconnection/RTCPeerConnection-AddRemoveTrack.html
@@ -44,25 +44,23 @@ }); }, 'addTrack() for a single track and a different stream.'); -promise_test(function() { - let pc = new RTCPeerConnection(); - return createStreams({audio:true, video:false}, 2) - .then(function(streams) { - let streamA = streams[0]; - let streamB = streams[1]; - let track = streamA.getAudioTracks()[0]; - let exception = null; - try { - pc.addTrack(track, streamA, streamB); - } catch (e) { - exception = e; - } - // The spec supports multiple streams per track but our implementation - // doesn't. Fix test when resolving https://crbug.com/webrtc/7932. - assert_true(exception != null); - assert_equals('NotSupportedError', exception.name); - }); -}, 'addTrack() for a single track and two streams throws NotSupportedError.'); +promise_test(async t => { + let pc = new RTCPeerConnection({sdpSemantics: "plan-b"}); + let [streamA, streamB] = await createStreams({audio:true, video:false}, 2); + let track = streamA.getAudioTracks()[0]; + assert_throws('NotSupportedError', () => { + pc.addTrack(track, streamA, streamB) + }); +}, 'addTrack() for a single track and two streams (Plan B) throws NotSupportedError.'); + +promise_test(async t => { + let pc = new RTCPeerConnection({sdpSemantics: "unified-plan"}); + let [streamA, streamB] = await createStreams({audio:true, video:false}, 2); + let track = streamA.getAudioTracks()[0]; + let sender = pc.addTrack(track, streamA, streamB); + assert_equals(sender.track, track); + assert_array_equals(pc.getLocalStreams(), [ streamA, streamB ]); +}, 'addTrack() for a single track and two streams (Unified Plan).'); promise_test(function() { let pc = new RTCPeerConnection();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-message-from-script-inside-svg-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-message-from-script-inside-svg-expected.txt new file mode 100644 index 0000000..cb0a27e --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-message-from-script-inside-svg-expected.txt
@@ -0,0 +1,4 @@ +Tests that message from script inside svg has correct source location. + +svg.html:2 42 +
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-message-from-script-inside-svg.js b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-message-from-script-inside-svg.js new file mode 100644 index 0000000..35e4b0b09 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/console-message-from-script-inside-svg.js
@@ -0,0 +1,13 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult( + `Tests that message from script inside svg has correct source location.\n`); + await TestRunner.loadModule('console_test_runner'); + await TestRunner.showPanel('console'); + await TestRunner.navigatePromise('resources/svg.html'); + ConsoleTestRunner.dumpConsoleMessages(); + TestRunner.completeTest(); +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/console/resources/svg.html b/third_party/WebKit/LayoutTests/http/tests/devtools/console/resources/svg.html new file mode 100644 index 0000000..96329e6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/console/resources/svg.html
@@ -0,0 +1,3 @@ +<svg> + <script>console.log(42);</script> +</svg>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing-session-id.js b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing-session-id.js index f6796f1..ff36ed9 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/tracing-session-id.js +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/tracing-session-id.js
@@ -33,7 +33,6 @@ return; if (event.name === TimelineModel.TimelineModel.RecordType.TracingStartedInPage) { - TestRunner.assertEquals(PerformanceTestRunner.timelineModel()._sessionId, event.args['sessionId'] || event.args['data']['sessionId']); TestRunner.addResult('Got DevTools metadata event: ' + event.name); frameId = event.args['data']['frames'][0]['frame']; } else if (event.name === TimelineModel.TimelineModel.RecordType.SetLayerTreeId) {
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-blob-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-blob-expected.txt index 7f241e4a..4062599 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-blob-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-blob-expected.txt
@@ -1,4 +1,4 @@ -Downloading URL with suggested filename "foo.pdf" +Download started Tests that a suggested filename on a download attribute is allowed if the link is a blob URL. The suggested filename at the top should be foo.pdf.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-data-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-data-expected.txt index d7ff96c..2514ead8 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-data-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-data-expected.txt
@@ -1,4 +1,4 @@ -Downloading URL with suggested filename "foo.pdf" +Download started Tests that a suggested filename on a download attribute is allowed if the link is a data URL. The suggested filename at the top should be foo.pdf.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-sameorigin-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-sameorigin-expected.txt index 2ec4ee2..7eab87a1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-sameorigin-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/anchor-download-allow-sameorigin-expected.txt
@@ -1,4 +1,4 @@ -Downloading URL with suggested filename "foo.pdf" +Download started Tests that a suggested filename on a download attribute is allowed if the link is in the same origin. The suggested filename at the top should be foo.pdf.
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/bluetooth-on-insecure-origin.html b/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/bluetooth-on-insecure-origin.html index 18a902e..96aeec8 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/bluetooth-on-insecure-origin.html +++ b/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/bluetooth-on-insecure-origin.html
@@ -7,11 +7,8 @@ if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) { window.location = get_host_info().UNAUTHENTICATED_ORIGIN + window.location.pathname; } else { - promise_test(function(test) { - return promise_rejects(test, 'SecurityError', - navigator.bluetooth.requestDevice({ - filters: [{services: ['generic_access']}] - })); - }, "Requires secure context before user gesture"); + test(t => { + assert_false('requestDevice' in navigator.bluetooth, 'navigator.bluetooth.requestDevice should not be present'); + }, 'navigator.bluetooth.requestDevice requires a secure context'); } </script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-inside-svg-tag4-expected.txt b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-inside-svg-tag4-expected.txt index 3db4e687..49db853 100644 --- a/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-inside-svg-tag4-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/security/xssAuditor/script-tag-inside-svg-tag4-expected.txt
@@ -1,3 +1,3 @@ CONSOLE ERROR: line 4: The XSS Auditor refused to execute a script in 'http://localhost:8000/security/xssAuditor/resources/echo-intertag.pl?q=%3Csvg%3E%3Cscript%3E/%3C1/%3Ealert(0)%3C/script%3E%3C/svg%3E' because its source code was found within the request. The server sent an 'X-XSS-Protection' header requesting this behavior. -CONSOLE ERROR: line -1: Uncaught SyntaxError: Invalid regular expression: missing / +CONSOLE ERROR: line 4: Uncaught SyntaxError: Invalid regular expression: missing / Ensures regexps are handled in even with nested script blocks.
diff --git a/third_party/WebKit/LayoutTests/media/content/counting.webm b/third_party/WebKit/LayoutTests/media/content/counting.webm new file mode 100644 index 0000000..de2abba --- /dev/null +++ b/third_party/WebKit/LayoutTests/media/content/counting.webm Binary files differ
diff --git a/third_party/WebKit/LayoutTests/media/video-canvas.html b/third_party/WebKit/LayoutTests/media/video-canvas.html index f3b1c88..550ddd0a 100644 --- a/third_party/WebKit/LayoutTests/media/video-canvas.html +++ b/third_party/WebKit/LayoutTests/media/video-canvas.html
@@ -57,6 +57,6 @@ video.currentTime = results.values[results.current].time; } - video.src = "content/counting.ogv"; + video.src = "content/counting.webm"; }); -</script> \ No newline at end of file +</script>
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/svg/custom/use-events-crash-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/svg/custom/use-events-crash-expected.txt index 7eeda58..9303f95 100644 --- a/third_party/WebKit/LayoutTests/platform/mac-mac10.12/svg/custom/use-events-crash-expected.txt +++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.12/svg/custom/use-events-crash-expected.txt
@@ -18,4 +18,4 @@ LayoutSVGContainer {g} at (0,0) size 40x40 [transform={m=((1.00,0.00)(0.00,1.00)) t=(350.00,25.00)}] LayoutSVGContainer {use} at (0,0) size 40x40 LayoutSVGRect {rect} at (0,0) size 40x40 [fill={[type=SOLID] [color=#00FF00]}] [x=0.00] [y=0.00] [width=40.00] [height=40.00] -caret: position 47 of child 0 {#text} of child 1 {text} of child 1 {g} of child 3 {g} of child 3 {g} of child 1 {svg} of document +caret: position 47 of child 0 {#text} of child 1 {text} of child 3 {g} of child 3 {g} of child 3 {g} of child 1 {svg} of document
diff --git a/third_party/WebKit/LayoutTests/svg/custom/use-events-crash.svg b/third_party/WebKit/LayoutTests/svg/custom/use-events-crash.svg index 311f5913..ab3d105 100644 --- a/third_party/WebKit/LayoutTests/svg/custom/use-events-crash.svg +++ b/third_party/WebKit/LayoutTests/svg/custom/use-events-crash.svg
@@ -6,7 +6,7 @@ function test() { if (window.eventSender) { - eventSender.mouseMoveTo(370, 45); + eventSender.mouseMoveTo(370, 60); eventSender.contextClick(); } }
diff --git a/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.cpp b/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.cpp index 6c29bad8..e263ccf69 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.cpp +++ b/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.cpp
@@ -792,8 +792,28 @@ CSSValueLuminance>(range); } +CSSPrimitiveValue* ConsumeLengthOrPercentCountNegative( + CSSParserTokenRange& range, + const CSSParserContext& context, + WTF::Optional<WebFeature> negativeSize) { + CSSPrimitiveValue* result = + ConsumeLengthOrPercent(range, context.Mode(), kValueRangeNonNegative, + CSSPropertyParserHelpers::UnitlessQuirk::kForbid); + if (result || !negativeSize) + return result; + + result = + ConsumeLengthOrPercent(range, context.Mode(), kValueRangeAll, + CSSPropertyParserHelpers::UnitlessQuirk::kForbid); + + if (result) + context.Count(*negativeSize); + return result; +} + CSSValue* ConsumeBackgroundSize(CSSParserTokenRange& range, - CSSParserMode css_parser_mode, + const CSSParserContext& context, + WTF::Optional<WebFeature> negativeSize, ParsingStyle parsing_style) { if (CSSPropertyParserHelpers::IdentMatches<CSSValueContain, CSSValueCover>( range.Peek().Id())) { @@ -803,9 +823,8 @@ CSSValue* horizontal = CSSPropertyParserHelpers::ConsumeIdent<CSSValueAuto>(range); if (!horizontal) { - horizontal = CSSPropertyParserHelpers::ConsumeLengthOrPercent( - range, css_parser_mode, kValueRangeAll, - CSSPropertyParserHelpers::UnitlessQuirk::kForbid); + horizontal = + ConsumeLengthOrPercentCountNegative(range, context, negativeSize); } CSSValue* vertical = nullptr; @@ -813,9 +832,8 @@ if (range.Peek().Id() == CSSValueAuto) { // `auto' is the default range.ConsumeIncludingWhitespace(); } else { - vertical = CSSPropertyParserHelpers::ConsumeLengthOrPercent( - range, css_parser_mode, kValueRangeAll, - CSSPropertyParserHelpers::UnitlessQuirk::kForbid); + vertical = + ConsumeLengthOrPercentCountNegative(range, context, negativeSize); } } else if (parsing_style == ParsingStyle::kLegacy) { // Legacy syntax: "-webkit-background-size: 10px" is equivalent to @@ -870,12 +888,12 @@ ConsumeBackgroundBox, range); } -CSSValue* ParseBackgroundOrMaskSize( - CSSParserTokenRange& range, - const CSSParserContext& context, - const CSSParserLocalContext& local_context) { +CSSValue* ParseBackgroundOrMaskSize(CSSParserTokenRange& range, + const CSSParserContext& context, + const CSSParserLocalContext& local_context, + WTF::Optional<WebFeature> negativeSize) { return CSSPropertyParserHelpers::ConsumeCommaSeparatedList( - ConsumeBackgroundSize, range, context.Mode(), + ConsumeBackgroundSize, range, context, negativeSize, local_context.UseAliasParsing() ? ParsingStyle::kLegacy : ParsingStyle::kNotLegacy); } @@ -904,8 +922,12 @@ return ConsumePositionLonghand<CSSValueTop, CSSValueBottom>( range, context.Mode()); case CSSPropertyBackgroundSize: + return ConsumeBackgroundSize(range, context, + WebFeature::kNegativeBackgroundSize, + ParsingStyle::kNotLegacy); case CSSPropertyWebkitMaskSize: - return ConsumeBackgroundSize(range, context.Mode(), + return ConsumeBackgroundSize(range, context, + WebFeature::kNegativeMaskSize, ParsingStyle::kNotLegacy); case CSSPropertyBackgroundColor: return CSSPropertyParserHelpers::ConsumeColor(range, context.Mode()); @@ -972,8 +994,12 @@ property.IDEquals(CSSPropertyWebkitMaskSize)) { if (!CSSPropertyParserHelpers::ConsumeSlashIncludingWhitespace(range)) continue; - value = ConsumeBackgroundSize(range, context.Mode(), - ParsingStyle::kNotLegacy); + value = + ConsumeBackgroundSize(range, context, + property.IDEquals(CSSPropertyBackgroundSize) + ? WebFeature::kNegativeBackgroundSize + : WebFeature::kNegativeMaskSize, + ParsingStyle::kNotLegacy); if (!value || !parsed_longhand[i - 1]) // Position must have been // parsed in the current layer.
diff --git a/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.h b/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.h index a5c6606..02a9f52 100644 --- a/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.h +++ b/third_party/WebKit/Source/core/css/properties/CSSParsingUtils.h
@@ -77,9 +77,6 @@ CSSValue* ConsumeBackgroundBox(CSSParserTokenRange&); CSSValue* ConsumeBackgroundComposite(CSSParserTokenRange&); CSSValue* ConsumeMaskSourceType(CSSParserTokenRange&); -CSSValue* ConsumeBackgroundSize(CSSParserTokenRange&, - CSSParserMode, - ParsingStyle); bool ConsumeBackgroundPosition(CSSParserTokenRange&, const CSSParserContext&, CSSPropertyParserHelpers::UnitlessQuirk, @@ -90,7 +87,8 @@ const CSSParserLocalContext&); CSSValue* ParseBackgroundOrMaskSize(CSSParserTokenRange&, const CSSParserContext&, - const CSSParserLocalContext&); + const CSSParserLocalContext&, + WTF::Optional<WebFeature> negativeSize); bool ParseBackgroundOrMask(bool, CSSParserTokenRange&, const CSSParserContext&,
diff --git a/third_party/WebKit/Source/core/css/properties/longhands/BackgroundSizeCustom.cpp b/third_party/WebKit/Source/core/css/properties/longhands/BackgroundSizeCustom.cpp index 1f65e5d..5cdff7a 100644 --- a/third_party/WebKit/Source/core/css/properties/longhands/BackgroundSizeCustom.cpp +++ b/third_party/WebKit/Source/core/css/properties/longhands/BackgroundSizeCustom.cpp
@@ -6,6 +6,7 @@ #include "core/css/properties/CSSParsingUtils.h" #include "core/css/properties/ComputedStyleUtils.h" +#include "core/frame/WebFeature.h" #include "core/style/ComputedStyle.h" namespace blink { @@ -15,8 +16,8 @@ CSSParserTokenRange& range, const CSSParserContext& context, const CSSParserLocalContext& local_context) const { - return CSSParsingUtils::ParseBackgroundOrMaskSize(range, context, - local_context); + return CSSParsingUtils::ParseBackgroundOrMaskSize( + range, context, local_context, WebFeature::kNegativeBackgroundSize); } const CSSValue* BackgroundSize::CSSValueFromComputedStyleInternal(
diff --git a/third_party/WebKit/Source/core/css/properties/longhands/WebkitMaskSizeCustom.cpp b/third_party/WebKit/Source/core/css/properties/longhands/WebkitMaskSizeCustom.cpp index 9fd89cb7..6d78891 100644 --- a/third_party/WebKit/Source/core/css/properties/longhands/WebkitMaskSizeCustom.cpp +++ b/third_party/WebKit/Source/core/css/properties/longhands/WebkitMaskSizeCustom.cpp
@@ -6,6 +6,7 @@ #include "core/css/properties/CSSParsingUtils.h" #include "core/css/properties/ComputedStyleUtils.h" +#include "core/frame/WebFeature.h" #include "core/style/ComputedStyle.h" namespace blink { @@ -15,8 +16,8 @@ CSSParserTokenRange& range, const CSSParserContext& context, const CSSParserLocalContext& local_context) const { - return CSSParsingUtils::ParseBackgroundOrMaskSize(range, context, - local_context); + return CSSParsingUtils::ParseBackgroundOrMaskSize( + range, context, local_context, WebFeature::kNegativeMaskSize); } const CSSValue* WebkitMaskSize::CSSValueFromComputedStyleInternal(
diff --git a/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp b/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp index 836f371d..3eb8ef9 100644 --- a/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp +++ b/third_party/WebKit/Source/core/exported/LocalFrameClientImpl.cpp
@@ -394,7 +394,7 @@ WebHistoryItem(item), static_cast<WebHistoryCommitType>(commit_type), content_initiated); } - virtual_time_pauser_.PauseVirtualTime(false); + virtual_time_pauser_.UnpauseVirtualTime(); } void LocalFrameClientImpl::DispatchWillCommitProvisionalLoad() { @@ -412,7 +412,7 @@ } if (WebDevToolsAgentImpl* dev_tools = DevToolsAgent()) dev_tools->DidStartProvisionalLoad(web_frame_->GetFrame()); - virtual_time_pauser_.PauseVirtualTime(true); + virtual_time_pauser_.PauseVirtualTime(); } void LocalFrameClientImpl::DispatchDidReceiveTitle(const String& title) { @@ -444,14 +444,14 @@ if (WebDevToolsAgentImpl* dev_tools = DevToolsAgent()) dev_tools->DidCommitLoadForLocalFrame(web_frame_->GetFrame()); - virtual_time_pauser_.PauseVirtualTime(false); + virtual_time_pauser_.UnpauseVirtualTime(); } void LocalFrameClientImpl::DispatchDidFailProvisionalLoad( const ResourceError& error, HistoryCommitType commit_type) { web_frame_->DidFail(error, true, commit_type); - virtual_time_pauser_.PauseVirtualTime(false); + virtual_time_pauser_.UnpauseVirtualTime(); } void LocalFrameClientImpl::DispatchDidFailLoad(const ResourceError& error,
diff --git a/third_party/WebKit/Source/core/exported/WebFrame.cpp b/third_party/WebKit/Source/core/exported/WebFrame.cpp index a641f8d0..58487bb2 100644 --- a/third_party/WebKit/Source/core/exported/WebFrame.cpp +++ b/third_party/WebKit/Source/core/exported/WebFrame.cpp
@@ -112,7 +112,10 @@ local_frame.View()); } } else { - local_frame.GetPage()->SetMainFrame(&local_frame); + Page* other_page = local_frame.GetPage(); + other_page->SetMainFrame(&local_frame); + if (PageScheduler* page_scheduler = other_page->GetPageScheduler()) + page_scheduler->SetIsMainFrameLocal(true); // This trace event is needed to detect the main frame of the // renderer in telemetry metrics. See crbug.com/692112#c11. TRACE_EVENT_INSTANT1("loading", "markAsMainFrame",
diff --git a/third_party/WebKit/Source/core/fileapi/PublicURLManager.cpp b/third_party/WebKit/Source/core/fileapi/PublicURLManager.cpp index 8a65267..129a3e00 100644 --- a/third_party/WebKit/Source/core/fileapi/PublicURLManager.cpp +++ b/third_party/WebKit/Source/core/fileapi/PublicURLManager.cpp
@@ -72,6 +72,7 @@ // that the origin can be retrieved when doing security origin check. // // See the definition of the origin of a Blob URL in the File API spec. + DCHECK(!url.HasFragmentIdentifier()); if (origin && BlobURL::GetOrigin(url) == "null") OriginMap()->insert(url.GetString(), origin); } @@ -86,8 +87,11 @@ } SecurityOrigin* BlobOriginMap::GetOrigin(const KURL& url) { - if (url.ProtocolIs("blob")) - return OriginMap()->at(url.GetString()); + if (url.ProtocolIs("blob")) { + KURL url_without_fragment = url; + url_without_fragment.RemoveFragmentIdentifier(); + return OriginMap()->at(url_without_fragment.GetString()); + } return nullptr; }
diff --git a/third_party/WebKit/Source/core/frame/LocalFrame.cpp b/third_party/WebKit/Source/core/frame/LocalFrame.cpp index af0e28f..7820504 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrame.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrame.cpp
@@ -168,6 +168,7 @@ } PageScheduler* GetPageScheduler() const override { return nullptr; } WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser( + const String&, WebScopedVirtualTimePauser::VirtualTaskDuration) { return WebScopedVirtualTimePauser(); } @@ -195,6 +196,9 @@ client, page, owner, interface_registry ? interface_registry : InterfaceRegistry::GetEmptyInterfaceRegistry()); + PageScheduler* page_scheduler = page.GetPageScheduler(); + if (frame->IsMainFrame() && page_scheduler) + page_scheduler->SetIsMainFrameLocal(true); probe::frameAttachedToParent(frame); return frame; }
diff --git a/third_party/WebKit/Source/core/frame/RemoteFrame.cpp b/third_party/WebKit/Source/core/frame/RemoteFrame.cpp index bac97e7..435099a 100644 --- a/third_party/WebKit/Source/core/frame/RemoteFrame.cpp +++ b/third_party/WebKit/Source/core/frame/RemoteFrame.cpp
@@ -14,6 +14,7 @@ #include "core/layout/LayoutEmbeddedContent.h" #include "core/loader/FrameLoadRequest.h" #include "core/loader/FrameLoader.h" +#include "core/page/Page.h" #include "core/paint/PaintLayer.h" #include "platform/graphics/GraphicsLayer.h" #include "platform/loader/fetch/ResourceRequest.h" @@ -36,7 +37,11 @@ RemoteFrame* RemoteFrame::Create(RemoteFrameClient* client, Page& page, FrameOwner* owner) { - return new RemoteFrame(client, page, owner); + RemoteFrame* frame = new RemoteFrame(client, page, owner); + PageScheduler* page_scheduler = page.GetPageScheduler(); + if (frame->IsMainFrame() && page_scheduler) + page_scheduler->SetIsMainFrameLocal(false); + return frame; } RemoteFrame::~RemoteFrame() {
diff --git a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp index d550e49..616482d 100644 --- a/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp +++ b/third_party/WebKit/Source/core/frame/WebLocalFrameImpl.cpp
@@ -1791,6 +1791,7 @@ local_frame_client_->SetVirtualTimePauser( frame_ ? frame_->GetFrameScheduler()->CreateWebScopedVirtualTimePauser( + "WebLocalFrameImpl", WebScopedVirtualTimePauser::VirtualTaskDuration::kInstant) : WebScopedVirtualTimePauser()); }
diff --git a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp index 8b91b84..30d677f00 100644 --- a/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp +++ b/third_party/WebKit/Source/core/html/HTMLAnchorElement.cpp
@@ -367,8 +367,16 @@ : WebFeature:: kHTMLAnchorElementDownloadInSandboxWithoutUserGesture); } + // TODO(jochen): Only set the suggested filename for URLs we can request. request.SetSuggestedFilename( static_cast<String>(FastGetAttribute(downloadAttr))); + if (GetDocument().GetSecurityOrigin()->CanReadContent(completed_url)) { + // TODO(jochen): Handle cross origin server redirects. + request.SetRequestContext(WebURLRequest::kRequestContextDownload); + request.SetRequestorOrigin(SecurityOrigin::Create(GetDocument().Url())); + frame->Client()->DownloadURL(request); + return; + } } request.SetRequestContext(WebURLRequest::kRequestContextHyperlink); FrameLoadRequest frame_request(&GetDocument(), request,
diff --git a/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp b/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp index c23facc..05ceddc0 100644 --- a/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp +++ b/third_party/WebKit/Source/core/html/parser/HTMLTreeBuilder.cpp
@@ -2678,6 +2678,8 @@ tree_.OpenElements()->PopUntilForeignContentScopeMarker(); ProcessStartTag(token); return; + } else if (token->GetName() == scriptTag) { + script_to_process_start_position_ = parser_->GetTextPosition(); } const AtomicString& current_namespace = adjusted_current_node->NamespaceURI();
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp index 2ad1ac9..94c800a 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.cpp
@@ -1256,9 +1256,11 @@ std::unique_ptr<TracedValue> InspectorTracingSessionIdForWorkerEvent::Data( LocalFrame* frame, + const String& url, WorkerThread* worker_thread) { std::unique_ptr<TracedValue> value = TracedValue::Create(); value->SetString("frame", IdentifiersFactory::FrameId(frame)); + value->SetString("url", url); value->SetString("workerId", IdentifiersFactory::IdFromToken( worker_thread->GetDevToolsWorkerToken())); value->SetDouble("workerThreadId", worker_thread->GetPlatformThreadId());
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h index 57cdb17..5e7a342 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h +++ b/third_party/WebKit/Source/core/inspector/InspectorTraceEvents.h
@@ -449,7 +449,9 @@ } namespace InspectorTracingSessionIdForWorkerEvent { -std::unique_ptr<TracedValue> Data(LocalFrame*, WorkerThread*); +std::unique_ptr<TracedValue> Data(LocalFrame*, + const String& url, + WorkerThread*); } namespace InspectorTracingStartedInFrame {
diff --git a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp index 2cbaef1..08361c4 100644 --- a/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp +++ b/third_party/WebKit/Source/core/inspector/InspectorTracingAgent.cpp
@@ -69,7 +69,7 @@ "TracingSessionIdForWorker", TRACE_EVENT_SCOPE_THREAD, "data", InspectorTracingSessionIdForWorkerEvent::Data( - frame, proxy->GetWorkerThread())); + frame, proxy->Url(), proxy->GetWorkerThread())); } }
diff --git a/third_party/WebKit/Source/core/page/Page.cpp b/third_party/WebKit/Source/core/page/Page.cpp index 1277ba1..02c7497 100644 --- a/third_party/WebKit/Source/core/page/Page.cpp +++ b/third_party/WebKit/Source/core/page/Page.cpp
@@ -282,7 +282,9 @@ // remote frames. // FIXME: Unfortunately we can't assert on this at the moment, because this // is called in the base constructor for both LocalFrame and RemoteFrame, - // when the vtables for the derived classes have not yet been setup. + // when the vtables for the derived classes have not yet been setup. Once this + // is fixed, also call page_scheduler_->SetIsMainFrameLocal() from here + // instead of from the callers of this method. main_frame_ = main_frame; } @@ -787,6 +789,8 @@ void Page::SetPageScheduler(std::unique_ptr<PageScheduler> page_scheduler) { page_scheduler_ = std::move(page_scheduler); + // The scheduler should be set before the main frame. + DCHECK(!main_frame_); } void Page::ReportIntervention(const String& text) {
diff --git a/third_party/WebKit/Source/core/page/Page.h b/third_party/WebKit/Source/core/page/Page.h index 7e554497..39134a1 100644 --- a/third_party/WebKit/Source/core/page/Page.h +++ b/third_party/WebKit/Source/core/page/Page.h
@@ -33,7 +33,6 @@ #include "core/frame/LocalFrame.h" #include "core/frame/SettingsDelegate.h" #include "core/frame/UseCounter.h" -#include "core/page/Page.h" #include "core/page/PageAnimator.h" #include "core/page/PageLifecycleState.h" #include "core/page/PageVisibilityNotifier.h" @@ -148,6 +147,9 @@ // PluginsChangedObservers. static void ResetPluginData(); + // When this method is called, page_scheduler_->SetIsMainFrameLocal should + // also be called to update accordingly. + // TODO(npm): update the |page_scheduler_| directly in this method. void SetMainFrame(Frame*); Frame* MainFrame() const { return main_frame_; } // Escape hatch for existing code that assumes that the root frame is
diff --git a/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp b/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp index 6b525a9..6a101f8 100644 --- a/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp +++ b/third_party/WebKit/Source/core/paint/BackgroundImageGeometry.cpp
@@ -529,28 +529,33 @@ // respective box, but for padding-box we also try to force alignment // with the inner border. // - // * for border-box, we can modufy individual edges iff the border fully + // * for border-box, we can modify individual edges iff the border fully // obscures the background. // - // It it unsafe to derive dest from border information if the layer is not - // painted as part of a regular background phase (e.g. paint_phase == kMask) - // or in the presence of non-SrcOver compositing. - // Also, if coordinate_offset_by_paint_rect_ is set, we're dealing with a - // LayoutView - for which dest_rect is overflowing (expanded to cover the - // whole canvas). - // Finally, table cells using the table background should not adjust - // based on borders. - bool allow_border_derived_adjustment = - ShouldPaintSelfBlockBackground(paint_phase) && - fill_layer.Composite() == CompositeOperator::kCompositeSourceOver && - !coordinate_offset_by_paint_rect_ && !painting_table_cell_; + // It it unsafe to derive dest from border information when any of the + // following is true: + // * the layer is not painted as part of a regular background phase + // (e.g.paint_phase == kMask) + // * non-SrcOver compositing is active + // * coordinate_offset_by_paint_rect_ is set, meaning we're dealing with a + // LayoutView - for which dest_rect is overflowing (expanded to cover + // the whole canvas). + // * We are painting table cells using the table background + // * There is a border image, because it may not be opaque or may be outset. + bool disallow_border_derived_adjustment = + !ShouldPaintSelfBlockBackground(paint_phase) || + fill_layer.Composite() != CompositeOperator::kCompositeSourceOver || + coordinate_offset_by_paint_rect_ || painting_table_cell_ || + positioning_box_.StyleRef().BorderImage().GetImage(); switch (fill_layer.Clip()) { case EFillBox::kContent: dest_adjust += positioning_box_.PaddingOutsets(); dest_adjust += positioning_box_.BorderBoxOutsets(); break; case EFillBox::kPadding: - if (allow_border_derived_adjustment) { + if (disallow_border_derived_adjustment) { + dest_adjust = positioning_box_.BorderBoxOutsets(); + } else { FloatRect inner_border_rect = positioning_box_.StyleRef() .GetRoundedInnerBorderFor(positioning_rect) @@ -561,12 +566,10 @@ LayoutUnit(inner_border_rect.MaxX())); dest_adjust.SetBottom(dest_rect.MaxY() - LayoutUnit(inner_border_rect.MaxY())); - } else { - dest_adjust = positioning_box_.BorderBoxOutsets(); } break; case EFillBox::kBorder: { - if (!allow_border_derived_adjustment) + if (disallow_border_derived_adjustment) break; BorderEdge edges[4];
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp index 531a99c..6a75c00 100644 --- a/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp +++ b/third_party/WebKit/Source/core/paint/compositing/CompositedLayerMapping.cpp
@@ -1311,7 +1311,7 @@ HTMLFrameOwnerElement* owner = ToHTMLFrameOwnerElement(frame->Owner()); LayoutObject* ownerLayoutObject = owner->GetLayoutObject(); - if (!ownerLayoutObject->HasLayer()) + if (!ownerLayoutObject || !ownerLayoutObject->HasLayer()) return LayoutPoint(); PaintLayer* ownerLayer = ToLayoutBoxModelObject(ownerLayoutObject)->Layer();
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositingLayerPropertyUpdater.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositingLayerPropertyUpdater.cpp index 96fe816c..14ff78f 100644 --- a/third_party/WebKit/Source/core/paint/compositing/CompositingLayerPropertyUpdater.cpp +++ b/third_party/WebKit/Source/core/paint/compositing/CompositingLayerPropertyUpdater.cpp
@@ -31,7 +31,8 @@ LayoutPoint layout_snapped_paint_offset = fragment_data.PaintOffset() - mapping->SubpixelAccumulation(); IntPoint snapped_paint_offset = RoundedIntPoint(layout_snapped_paint_offset); - DCHECK(layout_snapped_paint_offset == snapped_paint_offset); + // TODO(crbug.com/816490): Re-enable this check once it is fixed. + // DCHECK(layout_snapped_paint_offset == snapped_paint_offset); Optional<PropertyTreeState> container_layer_state; auto SetContainerLayerState =
diff --git a/third_party/WebKit/Source/core/script/PendingScript.cpp b/third_party/WebKit/Source/core/script/PendingScript.cpp index 7da7daf..447bf30 100644 --- a/third_party/WebKit/Source/core/script/PendingScript.cpp +++ b/third_party/WebKit/Source/core/script/PendingScript.cpp
@@ -42,6 +42,7 @@ .GetFrame() ->GetFrameScheduler() ->CreateWebScopedVirtualTimePauser( + "PendingScript", WebScopedVirtualTimePauser::VirtualTaskDuration::kInstant); } } // namespace @@ -82,7 +83,7 @@ if (IsReady()) { client_->PendingScriptFinished(this); } else { - virtual_time_pauser_.PauseVirtualTime(true); + virtual_time_pauser_.PauseVirtualTime(); } } @@ -92,7 +93,7 @@ CheckState(); DCHECK(IsExternalOrModule()); client_ = nullptr; - virtual_time_pauser_.PauseVirtualTime(false); + virtual_time_pauser_.UnpauseVirtualTime(); } ScriptElementBase* PendingScript::GetElement() const {
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/PerformanceModel.js b/third_party/WebKit/Source/devtools/front_end/timeline/PerformanceModel.js index 2a9510e..d8d80283 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/PerformanceModel.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/PerformanceModel.js
@@ -63,7 +63,14 @@ if (inputEvents || animationEvents) this._irModel.populate(inputEvents || [], animationEvents || []); - this._frameModel.addTraceEvents(this._mainTarget, this._timelineModel.inspectedTargetEvents()); + const mainTracks = this._timelineModel.tracks().filter( + track => track.type === TimelineModel.TimelineModel.TrackType.MainThread && track.forMainFrame && + track.events.length); + const threadData = mainTracks.map(track => { + const event = track.events[0]; + return {thread: event.thread, time: event.startTime}; + }); + this._frameModel.addTraceEvents(this._mainTarget, this._timelineModel.inspectedTargetEvents(), threadData); for (const entry of this._extensionTracingModels) { entry.model.adjustTime(
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js index 991ec2e..384c83d 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartDataProvider.js
@@ -240,7 +240,7 @@ }; const tracks = this._model.tracks().slice(); - tracks.sort((a, b) => weight(a) - weight(b)); + tracks.stableSort((a, b) => weight(a) - weight(b)); let rasterCount = 0; for (const track of tracks) { switch (track.type) { @@ -265,19 +265,19 @@ case TimelineModel.TimelineModel.TrackType.MainThread: if (track.forMainFrame) { const group = this._appendSyncEvents( - track, track.events, ls`Main`, this._headerLevel1, eventEntryType, true /* selectable */); - if (group) { - group.expanded = true; + track, track.events, track.url ? ls`Main \u2014 ${track.url}` : ls`Main`, this._headerLevel1, + eventEntryType, true /* selectable */); + if (group) this._timelineData.selectedGroup = group; - } } else { this._appendSyncEvents( - track, track.events, track.name, this._headerLevel2, eventEntryType, true /* selectable */); + track, track.events, track.url ? ls`Frame \u2014 ${track.url}` : ls`Subframe`, this._headerLevel1, + eventEntryType, true /* selectable */); } break; case TimelineModel.TimelineModel.TrackType.Worker: this._appendSyncEvents( - track, track.events, track.workerUrl ? ls`Worker ${track.workerUrl}` : ls`Dedicated worker`, + track, track.events, track.url ? ls`Worker \u2014 ${track.url}` : ls`Dedicated Worker`, this._headerLevel1, eventEntryType, true /* selectable */); break; case TimelineModel.TimelineModel.TrackType.Raster: @@ -300,6 +300,8 @@ break; } } + if (this._timelineData.selectedGroup) + this._timelineData.selectedGroup.expanded = true; for (let extensionIndex = 0; extensionIndex < this._extensionInfo.length; extensionIndex++) this._innerAppendExtensionEvents(extensionIndex);
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineFrameModel.js b/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineFrameModel.js index 2469634..577ea47a 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineFrameModel.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineFrameModel.js
@@ -239,11 +239,18 @@ /** * @param {?SDK.Target} target * @param {!Array.<!SDK.TracingModel.Event>} events + * @param {!Array<!{thread: !SDK.TracingModel.Thread, time: number}>} threadData */ - addTraceEvents(target, events) { + addTraceEvents(target, events, threadData) { this._target = target; - for (let i = 0; i < events.length; ++i) + let j = 0; + this._currentProcessMainThread = threadData.length && threadData[0].thread || null; + for (let i = 0; i < events.length; ++i) { + while (j + 1 < threadData.length && threadData[j + 1].time <= events[i].startTime) + this._currentProcessMainThread = threadData[++j].thread; this._addTraceEvent(events[i]); + } + this._currentProcessMainThread = null; } /** @@ -256,8 +263,6 @@ if (event.name === eventNames.SetLayerTreeId) { this._layerTreeId = event.args['layerTreeId'] || event.args['data']['layerTreeId']; - } else if (event.name === eventNames.TracingStartedInPage) { - this._currentProcessMainThread = event.thread; } else if ( event.phase === SDK.TracingModel.Phase.SnapshotObject && event.name === eventNames.LayerTreeHostImplSnapshot && parseInt(event.id, 0) === this._layerTreeId) {
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js b/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js index d72d11b..675727a2 100644 --- a/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js +++ b/third_party/WebKit/Source/devtools/front_end/timeline_model/TimelineModel.js
@@ -136,7 +136,8 @@ * @return {string} */ static eventFrameId(event) { - return TimelineModel.TimelineModel.globalEventId(event, 'frame'); + const data = event.args['data'] || event.args['beginData']; + return (data && data['frame']) || ''; } /** @@ -168,53 +169,149 @@ this._minimumRecordTime = tracingModel.minimumRecordTime(); this._maximumRecordTime = tracingModel.maximumRecordTime(); - const metadataEvents = this._processMetadataEvents(tracingModel, !!produceTraceStartedInPage); - if (Runtime.experiments.isEnabled('timelineShowAllProcesses')) { - const lastPageMetaEvent = metadataEvents.page.peekLast(); - for (const process of tracingModel.sortedProcesses()) { - for (const thread of process.sortedThreads()) - this._processThreadEvents(tracingModel, 0, Infinity, thread, thread === lastPageMetaEvent.thread, null); - } + this._processSyncBrowserEvents(tracingModel); + if (this._browserFrameTracking) { + this._processThreadsForBrowserFrames(tracingModel); } else { - let startTime = 0; - for (let i = 0, length = metadataEvents.page.length; i < length; i++) { - const metaEvent = metadataEvents.page[i]; - const process = metaEvent.thread.process(); - const endTime = i + 1 < length ? metadataEvents.page[i + 1].startTime : Infinity; - this._legacyCurrentPage = metaEvent.args['data'] && metaEvent.args['data']['page']; - for (const thread of process.sortedThreads()) { - let workerUrl = null; - if (thread.name() === TimelineModel.TimelineModel.WorkerThreadName || - thread.name() === TimelineModel.TimelineModel.WorkerThreadNameLegacy) { - const workerMetaEvent = metadataEvents.workers.find(e => { - if (e.args['data']['workerThreadId'] !== thread.id()) - return false; - // This is to support old traces. - if (e.args['data']['sessionId'] === this._sessionId) - return true; - return !!this._pageFrames.get(TimelineModel.TimelineModel.eventFrameId(e)); - }); - if (!workerMetaEvent) - continue; - const workerId = workerMetaEvent.args['data']['workerId']; - if (workerId) - this._workerIdByThread.set(thread, workerId); - workerUrl = workerMetaEvent.args['data']['url'] || ''; - } - this._processThreadEvents(tracingModel, startTime, endTime, thread, thread === metaEvent.thread, workerUrl); - } - startTime = endTime; - } + const metadataEvents = this._processMetadataEvents(tracingModel, !!produceTraceStartedInPage); + if (Runtime.experiments.isEnabled('timelineShowAllProcesses')) + this._processAllThreads(tracingModel, /** @type {!SDK.TracingModel.Event} */ (metadataEvents.page.peekLast())); + else + this._processMetadataAndThreads(tracingModel, metadataEvents); } this._inspectedTargetEvents.sort(SDK.TracingModel.Event.compareStartTime); - - this._processBrowserEvents(tracingModel); + this._processAsyncBrowserEvents(tracingModel); this._buildGPUEvents(tracingModel); this._resetProcessingState(); } /** * @param {!SDK.TracingModel} tracingModel + * @param {!SDK.TracingModel.Event} lastPageMetaEvent + */ + _processAllThreads(tracingModel, lastPageMetaEvent) { + for (const process of tracingModel.sortedProcesses()) { + for (const thread of process.sortedThreads()) { + this._processThreadEvents( + tracingModel, [{from: 0, to: Infinity}], thread, thread === lastPageMetaEvent.thread, false, true, null); + } + } + } + + /** + * @param {!SDK.TracingModel} tracingModel + * @param {!TimelineModel.TimelineModel.MetadataEvents} metadataEvents + */ + _processMetadataAndThreads(tracingModel, metadataEvents) { + let startTime = 0; + for (let i = 0, length = metadataEvents.page.length; i < length; i++) { + const metaEvent = metadataEvents.page[i]; + const process = metaEvent.thread.process(); + const endTime = i + 1 < length ? metadataEvents.page[i + 1].startTime : Infinity; + this._legacyCurrentPage = metaEvent.args['data'] && metaEvent.args['data']['page']; + for (const thread of process.sortedThreads()) { + let workerUrl = null; + if (thread.name() === TimelineModel.TimelineModel.WorkerThreadName || + thread.name() === TimelineModel.TimelineModel.WorkerThreadNameLegacy) { + const workerMetaEvent = metadataEvents.workers.find(e => { + if (e.args['data']['workerThreadId'] !== thread.id()) + return false; + // This is to support old traces. + if (e.args['data']['sessionId'] === this._sessionId) + return true; + return !!this._pageFrames.get(TimelineModel.TimelineModel.eventFrameId(e)); + }); + if (!workerMetaEvent) + continue; + const workerId = workerMetaEvent.args['data']['workerId']; + if (workerId) + this._workerIdByThread.set(thread, workerId); + workerUrl = workerMetaEvent.args['data']['url'] || ''; + } + this._processThreadEvents( + tracingModel, [{from: startTime, to: endTime}], thread, thread === metaEvent.thread, !!workerUrl, true, + workerUrl); + } + startTime = endTime; + } + } + + /** + * @param {!SDK.TracingModel} tracingModel + */ + _processThreadsForBrowserFrames(tracingModel) { + const processData = new Map(); + for (const frame of this._pageFrames.values()) { + for (let i = 0; i < frame.processes.length; i++) { + const pid = frame.processes[i].processId; + let data = processData.get(pid); + if (!data) { + data = []; + processData.set(pid, data); + } + const to = i === frame.processes.length - 1 ? (frame.deletedTime || this._maximumRecordTime) : + frame.processes[i + 1].time; + data.push({from: frame.processes[i].time, to: to, main: !frame.parent, url: frame.processes[i].url}); + } + } + const allMetadataEvents = tracingModel.devToolsMetadataEvents(); + for (const process of tracingModel.sortedProcesses()) { + const data = processData.get(process.id()); + if (!data) + continue; + data.sort((a, b) => a.from - b.from || a.to - b.to); + const ranges = []; + let lastUrl = null; + let lastMainUrl = null; + let hasMain = false; + for (const item of data) { + if (!ranges.length || item.from > ranges.peekLast().to) + ranges.push({from: item.from, to: item.to}); + else + ranges.peekLast().to = item.to; + if (item.main) + hasMain = true; + if (item.url) { + if (item.main) + lastMainUrl = item.url; + lastUrl = item.url; + } + } + + for (const thread of process.sortedThreads()) { + if (thread.name() === TimelineModel.TimelineModel.RendererMainThreadName) { + this._processThreadEvents( + tracingModel, ranges, thread, true /* isMainThread */, false /* isWorker */, hasMain, + hasMain ? lastMainUrl : lastUrl); + } else if ( + thread.name() === TimelineModel.TimelineModel.WorkerThreadName || + thread.name() === TimelineModel.TimelineModel.WorkerThreadNameLegacy) { + const workerMetaEvent = allMetadataEvents.find(e => { + if (e.name !== TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingSessionIdForWorker) + return false; + if (e.thread.process() !== process) + return false; + if (e.args['data']['workerThreadId'] !== thread.id()) + return false; + return !!this._pageFrames.get(TimelineModel.TimelineModel.eventFrameId(e)); + }); + if (!workerMetaEvent) + continue; + this._workerIdByThread.set(thread, workerMetaEvent.args['data']['workerId'] || ''); + this._processThreadEvents( + tracingModel, ranges, thread, false /* isMainThread */, true /* isWorker */, false /* forMainFrame */, + workerMetaEvent.args['data']['url'] || ''); + } else { + this._processThreadEvents( + tracingModel, ranges, thread, false /* isMainThread */, false /* isWorker */, false /* forMainFrame */, + null); + } + } + } + } + + /** + * @param {!SDK.TracingModel} tracingModel * @param {boolean} produceTraceStartedInPage * @return {!TimelineModel.TimelineModel.MetadataEvents} */ @@ -230,9 +327,7 @@ this._persistentIds = true; const frames = ((event.args['data'] && event.args['data']['frames']) || []); frames.forEach(payload => this._addPageFrame(event, payload)); - const rootFrame = this.rootFrames()[0]; - if (rootFrame && rootFrame.url) - this._pageURL = rootFrame.url; + this._mainFrame = this.rootFrames()[0]; } else if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingSessionIdForWorker) { workersDevToolsMetadataEvents.push(event); } else if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingStartedInBrowser) { @@ -306,14 +401,19 @@ /** * @param {!SDK.TracingModel} tracingModel */ - _processBrowserEvents(tracingModel) { + _processSyncBrowserEvents(tracingModel) { const browserMain = SDK.TracingModel.browserMainThread(tracingModel); - if (!browserMain) - return; + if (browserMain) + browserMain.events().forEach(this._processBrowserEvent, this); + } - // Disregard regular events, we don't need them yet, but still process to get proper metadata. - browserMain.events().forEach(this._processBrowserEvent, this); - this._processAsyncEvents(browserMain.asyncEvents()); + /** + * @param {!SDK.TracingModel} tracingModel + */ + _processAsyncBrowserEvents(tracingModel) { + const browserMain = SDK.TracingModel.browserMainThread(tracingModel); + if (browserMain) + this._processAsyncEvents(browserMain.asyncEvents(), [{from: 0, to: Infinity}]); } /** @@ -340,6 +440,7 @@ this._eventStack = []; /** @type {!Set<string>} */ this._knownInputEvents = new Set(); + this._browserFrameTracking = false; this._persistentIds = false; this._legacyCurrentPage = null; } @@ -423,56 +524,63 @@ /** * @param {!SDK.TracingModel} tracingModel - * @param {number} startTime - * @param {number} endTime + * @param {!Array<!{from: number, to: number}>} ranges * @param {!SDK.TracingModel.Thread} thread * @param {boolean} isMainThread - * @param {?string} workerUrl + * @param {boolean} isWorker + * @param {boolean} forMainFrame + * @param {?string} url */ - _processThreadEvents(tracingModel, startTime, endTime, thread, isMainThread, workerUrl) { - const events = this._injectJSFrameEvents(tracingModel, thread); - - let type = TimelineModel.TimelineModel.TrackType.Other; - if (workerUrl !== null) - type = TimelineModel.TimelineModel.TrackType.Worker; - else if (isMainThread) - type = TimelineModel.TimelineModel.TrackType.MainThread; - else if (thread.name().startsWith('CompositorTileWorker')) - type = TimelineModel.TimelineModel.TrackType.Raster; - const track = new TimelineModel.TimelineModel.Track( - thread.name(), type, type === TimelineModel.TimelineModel.TrackType.MainThread /* forMainFrame */, workerUrl); + _processThreadEvents(tracingModel, ranges, thread, isMainThread, isWorker, forMainFrame, url) { + const track = new TimelineModel.TimelineModel.Track(); + track.name = thread.name(); + track.type = TimelineModel.TimelineModel.TrackType.Other; + if (isMainThread) { + track.type = TimelineModel.TimelineModel.TrackType.MainThread; + track.url = url || null; + track.forMainFrame = forMainFrame; + } else if (isWorker) { + track.type = TimelineModel.TimelineModel.TrackType.Worker; + track.url = url; + } else if (thread.name().startsWith('CompositorTileWorker')) { + track.type = TimelineModel.TimelineModel.TrackType.Raster; + } this._tracks.push(track); + const events = this._injectJSFrameEvents(tracingModel, thread); this._eventStack = []; const eventStack = this._eventStack; - let i = events.lowerBound(startTime, (time, event) => time - event.startTime); - for (; i < events.length; i++) { - const event = events[i]; - if (endTime && event.startTime >= endTime) - break; - while (eventStack.length && eventStack.peekLast().endTime <= event.startTime) - eventStack.pop(); - if (!this._processEvent(event)) - continue; - if (!SDK.TracingModel.isAsyncPhase(event.phase) && event.duration) { - if (eventStack.length) { - const parent = eventStack.peekLast(); - parent.selfTime -= event.duration; - if (parent.selfTime < 0) - this._fixNegativeDuration(parent, event); - } - event.selfTime = event.duration; - if (!eventStack.length) - track.tasks.push(event); - eventStack.push(event); - } - if (TimelineModel.TimelineModel.isMarkerEvent(event)) - this._eventDividers.push(event); - track.events.push(event); - this._inspectedTargetEvents.push(event); + for (const range of ranges) { + let i = events.lowerBound(range.from, (time, event) => time - event.startTime); + for (; i < events.length; i++) { + const event = events[i]; + if (event.startTime >= range.to) + break; + while (eventStack.length && eventStack.peekLast().endTime <= event.startTime) + eventStack.pop(); + if (!this._processEvent(event)) + continue; + if (!SDK.TracingModel.isAsyncPhase(event.phase) && event.duration) { + if (eventStack.length) { + const parent = eventStack.peekLast(); + parent.selfTime -= event.duration; + if (parent.selfTime < 0) + this._fixNegativeDuration(parent, event); + } + event.selfTime = event.duration; + if (!eventStack.length) + track.tasks.push(event); + eventStack.push(event); + } + if (TimelineModel.TimelineModel.isMarkerEvent(event)) + this._eventDividers.push(event); + + track.events.push(event); + this._inspectedTargetEvents.push(event); + } } - this._processAsyncEvents(thread.asyncEvents(), startTime, endTime); + this._processAsyncEvents(thread.asyncEvents(), ranges); } /** @@ -491,10 +599,9 @@ /** * @param {!Array<!SDK.TracingModel.AsyncEvent>} asyncEvents - * @param {number=} startTime - * @param {number=} endTime + * @param {!Array<!{from: number, to: number}>} ranges */ - _processAsyncEvents(asyncEvents, startTime, endTime) { + _processAsyncEvents(asyncEvents, ranges) { const groups = new Map(); /** @@ -507,53 +614,55 @@ return groups.get(type); } - let i = startTime ? asyncEvents.lowerBound(startTime, function(time, asyncEvent) { - return time - asyncEvent.startTime; - }) : 0; + for (const range of ranges) { + let i = asyncEvents.lowerBound(range.from, function(time, asyncEvent) { + return time - asyncEvent.startTime; + }); - for (; i < asyncEvents.length; ++i) { - const asyncEvent = asyncEvents[i]; - if (endTime && asyncEvent.startTime >= endTime) - break; + for (; i < asyncEvents.length; ++i) { + const asyncEvent = asyncEvents[i]; + if (asyncEvent.startTime >= range.to) + break; - if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.Console)) { - group(TimelineModel.TimelineModel.TrackType.Console).push(asyncEvent); - continue; - } - - if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.UserTiming)) { - group(TimelineModel.TimelineModel.TrackType.UserTiming).push(asyncEvent); - continue; - } - - if (asyncEvent.name === TimelineModel.TimelineModel.RecordType.Animation) { - group(TimelineModel.TimelineModel.TrackType.Animation).push(asyncEvent); - continue; - } - - if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo) || - asyncEvent.name === TimelineModel.TimelineModel.RecordType.ImplSideFling) { - const lastStep = asyncEvent.steps.peekLast(); - // FIXME: fix event termination on the back-end instead. - if (lastStep.phase !== SDK.TracingModel.Phase.AsyncEnd) + if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.Console)) { + group(TimelineModel.TimelineModel.TrackType.Console).push(asyncEvent); continue; - const data = lastStep.args['data']; - asyncEvent.causedFrame = !!(data && data['INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT']); - if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo)) { - if (!this._knownInputEvents.has(lastStep.id)) - continue; - if (asyncEvent.name === TimelineModel.TimelineModel.RecordType.InputLatencyMouseMove && - !asyncEvent.causedFrame) - continue; - const rendererMain = data['INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT']; - if (rendererMain) { - const time = rendererMain['time'] / 1000; - TimelineModel.TimelineData.forEvent(asyncEvent.steps[0]).timeWaitingForMainThread = - time - asyncEvent.steps[0].startTime; - } } - group(TimelineModel.TimelineModel.TrackType.Input).push(asyncEvent); - continue; + + if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.UserTiming)) { + group(TimelineModel.TimelineModel.TrackType.UserTiming).push(asyncEvent); + continue; + } + + if (asyncEvent.name === TimelineModel.TimelineModel.RecordType.Animation) { + group(TimelineModel.TimelineModel.TrackType.Animation).push(asyncEvent); + continue; + } + + if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo) || + asyncEvent.name === TimelineModel.TimelineModel.RecordType.ImplSideFling) { + const lastStep = asyncEvent.steps.peekLast(); + // FIXME: fix event termination on the back-end instead. + if (lastStep.phase !== SDK.TracingModel.Phase.AsyncEnd) + continue; + const data = lastStep.args['data']; + asyncEvent.causedFrame = !!(data && data['INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT']); + if (asyncEvent.hasCategory(TimelineModel.TimelineModel.Category.LatencyInfo)) { + if (!this._knownInputEvents.has(lastStep.id)) + continue; + if (asyncEvent.name === TimelineModel.TimelineModel.RecordType.InputLatencyMouseMove && + !asyncEvent.causedFrame) + continue; + const rendererMain = data['INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT']; + if (rendererMain) { + const time = rendererMain['time'] / 1000; + TimelineModel.TimelineData.forEvent(asyncEvent.steps[0]).timeWaitingForMainThread = + time - asyncEvent.steps[0].startTime; + } + } + group(TimelineModel.TimelineModel.TrackType.Input).push(asyncEvent); + continue; + } } } @@ -604,7 +713,7 @@ let pageFrameId = TimelineModel.TimelineModel.eventFrameId(event); if (!pageFrameId && eventStack.length) pageFrameId = TimelineModel.TimelineData.forEvent(eventStack.peekLast()).frameId; - timelineData.frameId = pageFrameId || TimelineModel.TimelineModel.PageFrame.mainFrameId; + timelineData.frameId = pageFrameId || (this._mainFrame && this._mainFrame.frameId) || ''; this._asyncEventTracker.processEvent(event); switch (event.name) { case recordTypes.ResourceSendRequest: @@ -782,11 +891,13 @@ } case recordTypes.CommitLoad: { + if (this._browserFrameTracking) + break; const frameId = TimelineModel.TimelineModel.eventFrameId(event); const isMainFrame = !!eventData['isMainFrame']; const pageFrame = this._pageFrames.get(frameId); if (pageFrame) { - pageFrame.update(eventData.name || '', eventData.url || ''); + pageFrame.update(event.startTime, eventData); } else { // We should only have one main frame which has persistent id, // unless it's an old trace without 'persistentIds' flag. @@ -799,8 +910,8 @@ return false; } } - if (isMainFrame && eventData.url) - this._pageURL = eventData.url; + if (isMainFrame) + this._mainFrame = this._pageFrames.get(frameId); break; } @@ -817,11 +928,69 @@ * @param {!SDK.TracingModel.Event} event */ _processBrowserEvent(event) { - if (event.name !== TimelineModel.TimelineModel.RecordType.LatencyInfoFlow) + if (event.name === TimelineModel.TimelineModel.RecordType.LatencyInfoFlow) { + const frameId = event.args['frameTreeNodeId']; + if (typeof frameId === 'number' && frameId === this._mainFrameNodeId) + this._knownInputEvents.add(event.bind_id); return; - const frameId = event.args['frameTreeNodeId']; - if (typeof frameId === 'number' && frameId === this._mainFrameNodeId) - this._knownInputEvents.add(event.bind_id); + } + + if (event.hasCategory(SDK.TracingModel.DevToolsMetadataEventCategory) && event.args['data']) { + const data = event.args['data']; + if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.TracingStartedInBrowser) { + if (!data['persistentIds']) + return; + this._browserFrameTracking = true; + this._mainFrameNodeId = data['frameTreeNodeId']; + const frames = data['frames'] || []; + frames.forEach(payload => { + const parent = payload['parent'] && this._pageFrames.get(payload['parent']); + if (payload['parent'] && !parent) + return; + let frame = this._pageFrames.get(payload['frame']); + if (!frame) { + frame = new TimelineModel.TimelineModel.PageFrame(payload); + this._pageFrames.set(frame.frameId, frame); + if (parent) + parent.addChild(frame); + else + this._mainFrame = frame; + } + // TODO(dgozman): this should use event.startTime, but due to races between tracing start + // in different processes we cannot do this yet. + frame.update(this._minimumRecordTime, payload); + }); + return; + } + if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.FrameCommittedInBrowser && + this._browserFrameTracking) { + let frame = this._pageFrames.get(data['frame']); + if (!frame) { + const parent = data['parent'] && this._pageFrames.get(data['parent']); + if (!parent) + return; + frame = new TimelineModel.TimelineModel.PageFrame(data); + this._pageFrames.set(frame.frameId, frame); + parent.addChild(frame); + } + frame.update(event.startTime, data); + return; + } + if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.ProcessReadyInBrowser && + this._browserFrameTracking) { + const frame = this._pageFrames.get(data['frame']); + if (frame) + frame.processReady(data['processPseudoId'], data['processId']); + return; + } + if (event.name === TimelineModel.TimelineModel.DevToolsMetadataEvent.FrameDeletedInBrowser && + this._browserFrameTracking) { + const frame = this._pageFrames.get(data['frame']); + if (frame) + frame.deletedTime = event.startTime; + return; + } + } } /** @@ -830,7 +999,8 @@ */ _ensureNamedTrack(type) { if (!this._namedTracks.has(type)) { - const track = new TimelineModel.TimelineModel.Track('', type, true /* forMainFrame */, null); + const track = new TimelineModel.TimelineModel.Track(); + track.type = type; this._tracks.push(track); this._namedTracks.set(type, track); } @@ -856,12 +1026,12 @@ * @return {boolean} */ _addPageFrame(event, payload) { - const processId = event.thread.process().id(); - const parent = payload['parent'] && this._pageFrames.get(`${processId}.${payload['parent']}`); + const parent = payload['parent'] && this._pageFrames.get(payload['parent']); if (payload['parent'] && !parent) return false; - const pageFrame = new TimelineModel.TimelineModel.PageFrame(this.targetByEvent(event), processId, payload); - this._pageFrames.set(pageFrame.id, pageFrame); + const pageFrame = new TimelineModel.TimelineModel.PageFrame(payload); + this._pageFrames.set(pageFrame.frameId, pageFrame); + pageFrame.update(event.startTime, payload); if (parent) parent.addChild(pageFrame); return true; @@ -886,7 +1056,7 @@ this._workerIdByThread = new WeakMap(); /** @type {!Map<string, !TimelineModel.TimelineModel.PageFrame>} */ this._pageFrames = new Map(); - this._pageURL = ''; + this._mainFrame = null; this._minimumRecordTime = 0; this._maximumRecordTime = 0; @@ -945,7 +1115,7 @@ * @return {string} */ pageURL() { - return this._pageURL; + return this._mainFrame && this._mainFrame.url || ''; } /** @@ -1155,7 +1325,6 @@ V8Deopt: 'V8Deopt' }; -TimelineModel.TimelineModel.MainThreadName = 'main'; TimelineModel.TimelineModel.WorkerThreadName = 'DedicatedWorker thread'; TimelineModel.TimelineModel.WorkerThreadNameLegacy = 'DedicatedWorker Thread'; TimelineModel.TimelineModel.RendererMainThreadName = 'CrRendererMain'; @@ -1164,6 +1333,9 @@ TracingStartedInBrowser: 'TracingStartedInBrowser', TracingStartedInPage: 'TracingStartedInPage', TracingSessionIdForWorker: 'TracingSessionIdForWorker', + FrameCommittedInBrowser: 'FrameCommittedInBrowser', + ProcessReadyInBrowser: 'ProcessReadyInBrowser', + FrameDeletedInBrowser: 'FrameDeletedInBrowser', }; TimelineModel.TimelineModel.Thresholds = { @@ -1174,20 +1346,12 @@ }; TimelineModel.TimelineModel.Track = class { - /** - * @param {string} name - * @param {!TimelineModel.TimelineModel.TrackType} type - * @param {boolean} forMainFrame - * @param {?string} workerUrl - */ - constructor(name, type, forMainFrame, workerUrl) { - // Note that each main thread track only contains events from the - // interesting time intervals, while at least one frame from the - // page operated on the thread. - this.name = name; - this.type = type; - this.forMainFrame = forMainFrame; - this.workerUrl = workerUrl; + constructor() { + this.name = ''; + this.type = TimelineModel.TimelineModel.TrackType.Other; + // TODO(dgozman): replace forMainFrame with a list of frames, urls and time ranges. + this.forMainFrame = false; + this.url = ''; // TODO(dgozman): do not distinguish between sync and async events. /** @type {!Array<!SDK.TracingModel.Event>} */ this.events = []; @@ -1245,35 +1409,54 @@ Other: Symbol('Other'), }; -/** @typedef {!{page: !Array<!SDK.TracingModel.Event>, workers: !Array<!SDK.TracingModel.Event>}} */ -TimelineModel.TimelineModel.MetadataEvents; - - TimelineModel.TimelineModel.PageFrame = class { /** - * @param {?SDK.Target} target - * @param {number} pid * @param {!Object} payload */ - constructor(target, pid, payload) { + constructor(payload) { this.frameId = payload['frame']; this.url = payload['url'] || ''; this.name = payload['name']; - this.processId = pid; + /** @type {!Array<!TimelineModel.TimelineModel.PageFrame>} */ this.children = []; /** @type {?TimelineModel.TimelineModel.PageFrame} */ this.parent = null; - this.id = `${this.processId}.${this.frameId}`; - this.ownerNode = target && payload['nodeId'] ? new SDK.DeferredDOMNode(target, payload['nodeId']) : null; + /** @type {!Array<!{time: number, processId: number, processPseudoId: ?string, url: string}>} */ + this.processes = []; + /** @type {?number} */ + this.deletedTime = null; + // TODO(dgozman): figure this out. + // this.ownerNode = target && payload['nodeId'] ? new SDK.DeferredDOMNode(target, payload['nodeId']) : null; + this.ownerNode = null; } /** - * @param {string} name - * @param {string} url + * @param {number} time + * @param {!Object} payload */ - update(name, url) { - this.name = name; - this.url = url; + update(time, payload) { + this.url = payload['url'] || ''; + this.name = payload['name']; + if (payload['processId']) { + this.processes.push( + {time: time, processId: payload['processId'], processPseudoId: '', url: payload['url'] || ''}); + } else { + this.processes.push( + {time: time, processId: -1, processPseudoId: payload['processPseudoId'], url: payload['url'] || ''}); + } + } + + /** + * @param {string} processPseudoId + * @param {number} processId + */ + processReady(processPseudoId, processId) { + for (const process of this.processes) { + if (process.processPseudoId === processPseudoId) { + process.processPseudoId = ''; + process.processId = processId; + } + } } /** @@ -1285,8 +1468,8 @@ } }; -TimelineModel.TimelineModel.PageFrame.mainFrameId = ''; - +/** @typedef {!{page: !Array<!SDK.TracingModel.Event>, workers: !Array<!SDK.TracingModel.Event>}} */ +TimelineModel.TimelineModel.MetadataEvents; /** * @unrestricted
diff --git a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp index 231f62a..fe1208a3 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXLayoutObject.cpp
@@ -566,6 +566,9 @@ if (layout_object_->IsBR()) return false; + if (CanSetFocusAttribute()) + return false; + if (IsLink()) return false; @@ -660,28 +663,13 @@ if (RoleValue() == kTimeRole) return false; - if (RoleValue() == kProgressIndicatorRole) { + if (RoleValue() == kProgressIndicatorRole) return false; - } // if this element has aria attributes on it, it should not be ignored. if (SupportsARIAAttributes()) return false; - // <span> tags are inline tags and not meant to convey information if they - // have no other aria information on them. If we don't ignore them, they may - // emit signals expected to come from their parent. In addition, because - // included spans are GroupRole objects, and GroupRole objects are often - // containers with meaningful information, the inclusion of a span can have - // the side effect of causing the immediate parent accessible to be ignored. - // This is especially problematic for platforms which have distinct roles for - // textual block elements. - if (IsHTMLSpanElement(node)) { - if (ignored_reasons) - ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); - return true; - } - if (IsImage()) return false; @@ -714,10 +702,14 @@ !GetAttribute(altAttr).IsEmpty() || !GetAttribute(titleAttr).IsEmpty()) return false; - // Don't ignore generic focusable elements like <div tabindex=0> - // unless they're completely empty, with no children. - if (IsGenericFocusableElement() && node->hasChildren()) - return false; + // <span> tags are inline tags and not meant to convey information if they + // have no other ARIA information on them. If we don't ignore them, they may + // emit signals expected to come from their parent. + if (IsHTMLSpanElement(node)) { + if (ignored_reasons) + ignored_reasons->push_back(IgnoredReason(kAXUninteresting)); + return true; + } // Positioned elements and scrollable containers are important for // determining bounding boxes.
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp index 2b775d9b..f5bca07 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp +++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.cpp
@@ -606,41 +606,6 @@ } } -bool AXNodeObject::IsGenericFocusableElement() const { - if (!CanSetFocusAttribute()) - return false; - - // If it's a control, it's not generic. - if (IsControl()) - return false; - - // If it has an aria role, it's not generic. - if (aria_role_ != kUnknownRole) - return false; - - // If the content editable attribute is set on this element, that's the reason - // it's focusable, and existing logic should handle this case already - so - // it's not a generic focusable element. - - if (HasContentEditableAttributeSet()) - return false; - - // The web area and body element are both focusable, but existing logic - // handles these cases already, so we don't need to include them here. - if (RoleValue() == kWebAreaRole) - return false; - if (IsHTMLBodyElement(GetNode())) - return false; - - // An SVG root is focusable by default, but it's probably not interactive, so - // don't include it. It can still be made accessible by giving it an ARIA - // role. - if (RoleValue() == kSVGRootRole) - return false; - - return true; -} - AXObject* AXNodeObject::MenuButtonForMenu() const { Element* menu_item = MenuItemElementForMenu();
diff --git a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.h b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.h index 189805f1..5656ee8 100644 --- a/third_party/WebKit/Source/modules/accessibility/AXNodeObject.h +++ b/third_party/WebKit/Source/modules/accessibility/AXNodeObject.h
@@ -70,9 +70,6 @@ bool HasContentEditableAttributeSet() const; bool IsTextControl() const override; - // This returns true if it's focusable but it's not content editable and it's - // not a control or ARIA control. - bool IsGenericFocusableElement() const; AXObject* MenuButtonForMenu() const; AXObject* MenuButtonForMenuIfExists() const; Element* MenuItemElementForMenu() const;
diff --git a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp index 4184e3b7..603aba6a 100644 --- a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp +++ b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.cpp
@@ -164,13 +164,7 @@ "implementation-status.md")); #endif - // If the Relevant settings object is not a secure context, reject promise - // with a SecurityError and abort these steps. - String error_message; - if (!context->IsSecureContext(error_message)) { - return ScriptPromise::RejectWithDOMException( - script_state, DOMException::Create(kSecurityError, error_message)); - } + CHECK(context->IsSecureContext()); // If the algorithm is not allowed to show a popup, reject promise with a // SecurityError and abort these steps.
diff --git a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.idl b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.idl index 302b496..5ceef89 100644 --- a/third_party/WebKit/Source/modules/bluetooth/Bluetooth.idl +++ b/third_party/WebKit/Source/modules/bluetooth/Bluetooth.idl
@@ -7,5 +7,5 @@ [ RuntimeEnabled=WebBluetooth ] interface Bluetooth { - [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRequestDevice] Promise<BluetoothDevice> requestDevice (optional RequestDeviceOptions options); + [CallWith=ScriptState, RaisesException, MeasureAs=WebBluetoothRequestDevice, SecureContext] Promise<BluetoothDevice> requestDevice (optional RequestDeviceOptions options); };
diff --git a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css index 6a2ac3e..edb754a 100644 --- a/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css +++ b/third_party/WebKit/Source/modules/media_controls/resources/modernMediaControls.css
@@ -35,6 +35,7 @@ justify-content: flex-end; align-items: center; font-size: 14px; + will-change: transform; } audio::-webkit-media-controls-enclosure,
diff --git a/third_party/WebKit/Source/modules/payments/PaymentAddress.idl b/third_party/WebKit/Source/modules/payments/PaymentAddress.idl index c408e26..74bda420 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentAddress.idl +++ b/third_party/WebKit/Source/modules/payments/PaymentAddress.idl
@@ -2,22 +2,23 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/browser-payment-api/#paymentaddress-interface +// https://w3c.github.io/payment-request/#paymentaddress-interface [ RuntimeEnabled=PaymentRequest, + SecureContext, Exposed=Window ] interface PaymentAddress { serializer = {attribute}; - readonly attribute DOMString country; - readonly attribute FrozenArray<DOMString> addressLine; - readonly attribute DOMString region; readonly attribute DOMString city; + readonly attribute DOMString country; readonly attribute DOMString dependentLocality; - readonly attribute DOMString postalCode; - readonly attribute DOMString sortingCode; readonly attribute DOMString languageCode; readonly attribute DOMString organization; - readonly attribute DOMString recipient; readonly attribute DOMString phone; + readonly attribute DOMString postalCode; + readonly attribute DOMString recipient; + readonly attribute DOMString region; + readonly attribute DOMString sortingCode; + readonly attribute FrozenArray<DOMString> addressLine; };
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp index fc2ef5f..96c4c5e 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp +++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.cpp
@@ -1005,10 +1005,7 @@ execution_context->GetTaskRunner(TaskType::kMiscPlatformAPI), this, &PaymentRequest::OnCompleteTimeout) { - if (!GetExecutionContext()->IsSecureContext()) { - exception_state.ThrowSecurityError("Must be in a secure context"); - return; - } + DCHECK(GetExecutionContext()->IsSecureContext()); if (!AllowedToUsePaymentRequest(GetFrame())) { exception_state.ThrowSecurityError(
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequest.idl b/third_party/WebKit/Source/modules/payments/PaymentRequest.idl index 12518140..cfc59a9 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequest.idl +++ b/third_party/WebKit/Source/modules/payments/PaymentRequest.idl
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://w3c.github.io/browser-payment-api/#paymentrequest-interface +// https://w3c.github.io/payment-request/#paymentrequest-interface // http://crbug.com/587995 [ @@ -10,6 +10,7 @@ Constructor(sequence<PaymentMethodData> methodData, PaymentDetailsInit details, optional PaymentOptions options), ConstructorCallWith=ExecutionContext, RaisesException=Constructor, + SecureContext, Exposed=Window, ActiveScriptWrappable ] interface PaymentRequest : EventTarget {
diff --git a/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp b/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp index 974aab7..de649fad 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp +++ b/third_party/WebKit/Source/modules/payments/PaymentRequestTest.cpp
@@ -14,19 +14,6 @@ namespace blink { namespace { -TEST(PaymentRequestTest, SecureContextRequired) { - V8TestingScope scope; - scope.GetDocument().SetSecurityOrigin( - SecurityOrigin::Create(KURL("http://www.example.com/"))); - - PaymentRequest::Create( - scope.GetExecutionContext(), BuildPaymentMethodDataForTest(), - BuildPaymentDetailsInitForTest(), scope.GetExceptionState()); - - EXPECT_TRUE(scope.GetExceptionState().HadException()); - EXPECT_EQ(kSecurityError, scope.GetExceptionState().Code()); -} - TEST(PaymentRequestTest, NoExceptionWithValidData) { V8TestingScope scope; MakePaymentRequestOriginSecure(scope.GetDocument());
diff --git a/third_party/WebKit/Source/modules/payments/PaymentResponse.idl b/third_party/WebKit/Source/modules/payments/PaymentResponse.idl index 863b2a0..53dcc0a9 100644 --- a/third_party/WebKit/Source/modules/payments/PaymentResponse.idl +++ b/third_party/WebKit/Source/modules/payments/PaymentResponse.idl
@@ -10,22 +10,23 @@ "unknown" }; -// https://w3c.github.io/browser-payment-api/#paymentresponse-interface +// https://w3c.github.io/payment-request/#dom-paymentresponse [ RuntimeEnabled=PaymentRequest, + SecureContext, Exposed=Window ] interface PaymentResponse { serializer = {attribute}; readonly attribute DOMString requestId; readonly attribute DOMString methodName; - readonly attribute DOMString? payerName; - readonly attribute DOMString? payerEmail; - readonly attribute DOMString? payerPhone; [CallWith=ScriptState, RaisesException] readonly attribute object details; readonly attribute PaymentAddress? shippingAddress; readonly attribute DOMString? shippingOption; + readonly attribute DOMString? payerName; + readonly attribute DOMString? payerEmail; + readonly attribute DOMString? payerPhone; [CallWith=ScriptState] Promise<void> complete(optional PaymentComplete paymentResult = "unknown"); };
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp index 4ad03cb..e1fdb19 100644 --- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp +++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.cpp
@@ -535,7 +535,8 @@ negotiation_needed_(false), stopped_(false), closed_(false), - has_data_channels_(false) { + has_data_channels_(false), + sdp_semantics_(configuration.sdp_semantics) { Document* document = ToDocument(GetExecutionContext()); // If we fail, set |m_closed| and |m_stopped| to true, to avoid hitting the @@ -1424,9 +1425,13 @@ DCHECK(track->Component()); if (ThrowExceptionIfSignalingStateClosed(signaling_state_, exception_state)) return nullptr; - if (streams.size() >= 2) { - // TODO(hbos): Don't throw an exception when this is supported by the lower - // layers. https://crbug.com/webrtc/7932 + // TODO(bugs.webrtc.org/8530): Take out WebRTCSdpSemantics::kDefault check + // once default is no longer interpreted as Plan B lower down. + if ((sdp_semantics_ == WebRTCSdpSemantics::kPlanB || + sdp_semantics_ == WebRTCSdpSemantics::kDefault) && + streams.size() >= 2) { + // TODO(hbos): Update peer_handler_ to call the AddTrack() that returns the + // appropriate errors, and let the lower layers handle it. exception_state.ThrowDOMException( kNotSupportedError, "Adding a track to multiple streams is not supported.");
diff --git a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h index 496f2c2..a117adf 100644 --- a/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h +++ b/third_party/WebKit/Source/modules/peerconnection/RTCPeerConnection.h
@@ -44,6 +44,7 @@ #include "platform/heap/HeapAllocator.h" #include "platform/scheduler/public/frame_scheduler.h" #include "public/platform/WebMediaConstraints.h" +#include "public/platform/WebRTCConfiguration.h" #include "public/platform/WebRTCPeerConnectionHandler.h" #include "public/platform/WebRTCPeerConnectionHandlerClient.h" @@ -351,6 +352,7 @@ String last_answer_; bool has_data_channels_; // For RAPPOR metrics + WebRTCSdpSemantics sdp_semantics_; }; } // namespace blink
diff --git a/third_party/WebKit/Source/platform/fonts/FontDescription.cpp b/third_party/WebKit/Source/platform/fonts/FontDescription.cpp index 8250db0..d760d78 100644 --- a/third_party/WebKit/Source/platform/fonts/FontDescription.cpp +++ b/third_party/WebKit/Source/platform/fonts/FontDescription.cpp
@@ -114,22 +114,26 @@ } FontSelectionValue FontDescription::LighterWeight(FontSelectionValue weight) { - if (weight >= FontSelectionValue(100) && weight <= FontSelectionValue(500)) + // TODO(fs): Adjust to match table in + // https://drafts.csswg.org/css-fonts-4/#font-weight-prop + if (weight < FontSelectionValue(501)) return FontSelectionValue(100); - if (weight >= FontSelectionValue(600) && weight <= FontSelectionValue(700)) + if (weight < FontSelectionValue(701)) return FontSelectionValue(400); - if (weight >= FontSelectionValue(800) && weight <= FontSelectionValue(900)) + if (weight <= FontSelectionValue(1000)) return FontSelectionValue(700); NOTREACHED(); return NormalWeightValue(); } FontSelectionValue FontDescription::BolderWeight(FontSelectionValue weight) { - if (weight >= FontSelectionValue(100) && weight <= FontSelectionValue(300)) + // TODO(fs): Adjust to match table in + // https://drafts.csswg.org/css-fonts-4/#font-weight-prop + if (weight < FontSelectionValue(301)) return FontSelectionValue(400); - if (weight >= FontSelectionValue(400) && weight <= FontSelectionValue(500)) + if (weight < FontSelectionValue(501)) return FontSelectionValue(700); - if (weight >= FontSelectionValue(600) && weight <= FontSelectionValue(900)) + if (weight <= FontSelectionValue(1000)) return FontSelectionValue(900); NOTREACHED(); return NormalWeightValue();
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.cpp b/third_party/WebKit/Source/platform/heap/HeapPage.cpp index 02daa74..6519f58d 100644 --- a/third_party/WebKit/Source/platform/heap/HeapPage.cpp +++ b/third_party/WebKit/Source/platform/heap/HeapPage.cpp
@@ -210,7 +210,7 @@ } DCHECK(SweepingCompleted()); - Verify(); + VerifyObjectStartBitmap(); } size_t BaseArena::ObjectPayloadSizeForTesting() { @@ -232,7 +232,7 @@ ClearFreeLists(); // Verification depends on the allocation point being cleared. - Verify(); + VerifyObjectStartBitmap(); for (BasePage* page = first_page_; page; page = page->Next()) { page->MarkAsUnswept(); @@ -584,11 +584,14 @@ heap.Compaction()->FinishedArenaCompaction(this, freed_page_count, freed_size); - Verify(); + VerifyObjectStartBitmap(); } -void NormalPageArena::Verify() { +void NormalPageArena::VerifyObjectStartBitmap() { #if DCHECK_IS_ON() + // Verifying object start bitmap requires iterability of pages. As compaction + // may set up a new we have to reset here. + SetAllocationPoint(nullptr, 0); for (NormalPage* page = static_cast<NormalPage*>(first_page_); page; page = static_cast<NormalPage*>(page->Next())) page->VerifyObjectStartBitmapIsConsistentWithPayload();
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.h b/third_party/WebKit/Source/platform/heap/HeapPage.h index 22d72f2..6d344bc 100644 --- a/third_party/WebKit/Source/platform/heap/HeapPage.h +++ b/third_party/WebKit/Source/platform/heap/HeapPage.h
@@ -774,7 +774,7 @@ bool WillObjectBeLazilySwept(BasePage*, void*) const; - virtual void Verify(){}; + virtual void VerifyObjectStartBitmap(){}; virtual void VerifyMarking(){}; protected: @@ -836,7 +836,7 @@ void SweepAndCompact(); - void Verify() override; + void VerifyObjectStartBitmap() override; void VerifyMarking() override; Address CurrentAllocationPoint() const { return current_allocation_point_; }
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp index 92935f86..cedf80ad 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceFetcher.cpp
@@ -1444,7 +1444,7 @@ } } - resource->VirtualTimePauser().PauseVirtualTime(false); + resource->VirtualTimePauser().UnpauseVirtualTime(); Context().DispatchDidFinishLoading( resource->Identifier(), finish_time, encoded_data_length, resource->GetResponse().DecodedBodyLength(), blocked_cross_site_document); @@ -1470,7 +1470,7 @@ bool is_internal_request = resource->Options().initiator_info.name == FetchInitiatorTypeNames::internal; - resource->VirtualTimePauser().PauseVirtualTime(false); + resource->VirtualTimePauser().UnpauseVirtualTime(); Context().DispatchDidFail( resource->LastResourceRequest().Url(), resource->Identifier(), error, resource->GetResponse().EncodedDataLength(), is_internal_request); @@ -1519,8 +1519,9 @@ if (Context().GetFrameScheduler()) { WebScopedVirtualTimePauser virtual_time_pauser = Context().GetFrameScheduler()->CreateWebScopedVirtualTimePauser( + resource->Url().GetString(), WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant); - virtual_time_pauser.PauseVirtualTime(true); + virtual_time_pauser.PauseVirtualTime(); resource->VirtualTimePauser() = std::move(virtual_time_pauser); } Context().DispatchWillSendRequest(resource->Identifier(), request, response,
diff --git a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp index 341d0b7..b2f6a01f 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/ResourceLoader.cpp
@@ -167,7 +167,11 @@ void ResourceLoader::SetDefersLoading(bool defers) { DCHECK(loader_); loader_->SetDefersLoading(defers); - resource_->VirtualTimePauser().PauseVirtualTime(!defers); + if (defers) { + resource_->VirtualTimePauser().UnpauseVirtualTime(); + } else { + resource_->VirtualTimePauser().PauseVirtualTime(); + } } void ResourceLoader::DidChangePriority(ResourceLoadPriority load_priority, @@ -361,8 +365,9 @@ if (Context().GetFrameScheduler()) { WebScopedVirtualTimePauser virtual_time_pauser = Context().GetFrameScheduler()->CreateWebScopedVirtualTimePauser( + resource_->Url().GetString(), WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant); - virtual_time_pauser.PauseVirtualTime(true); + virtual_time_pauser.PauseVirtualTime(); resource_->VirtualTimePauser() = std::move(virtual_time_pauser); } Context().DispatchWillSendRequest(resource_->Identifier(), *new_request,
diff --git a/third_party/WebKit/Source/platform/mhtml/MHTMLParser.cpp b/third_party/WebKit/Source/platform/mhtml/MHTMLParser.cpp index 3cd2b12..a41a6d0 100644 --- a/third_party/WebKit/Source/platform/mhtml/MHTMLParser.cpp +++ b/third_party/WebKit/Source/platform/mhtml/MHTMLParser.cpp
@@ -221,9 +221,11 @@ HeapVector<Member<ArchiveResource>> MHTMLParser::ParseArchive() { MIMEHeader* header = MIMEHeader::ParseHeader(&line_reader_); HeapVector<Member<ArchiveResource>> resources; - if (!ParseArchiveWithHeader(header, resources)) + if (ParseArchiveWithHeader(header, resources)) { + creation_date_ = header->Date(); + } else { resources.clear(); - creation_date_ = header->Date(); + } return resources; }
diff --git a/third_party/WebKit/Source/platform/mhtml/MHTMLParserTest.cpp b/third_party/WebKit/Source/platform/mhtml/MHTMLParserTest.cpp index 37f2b1f..14eb955 100644 --- a/third_party/WebKit/Source/platform/mhtml/MHTMLParserTest.cpp +++ b/third_party/WebKit/Source/platform/mhtml/MHTMLParserTest.cpp
@@ -390,7 +390,7 @@ } TEST_F(MHTMLParserTest, DateParsing_ValidDate) { - // Missing encoding is treated as binary. + // Valid date is used. const char mhtml_data[] = "From: <Saved by Blink>\r\n" "Subject: Test Subject\r\n" @@ -415,4 +415,14 @@ EXPECT_EQ(expected_time, creation_time); } +TEST_F(MHTMLParserTest, MissingBoundary) { + // No "boundary" parameter in the content type header means that parsing will + // be a failure and the header will be |nullptr|. + const char mhtml_data[] = "Content-Type: multipart/false\r\n"; + + HeapVector<Member<ArchiveResource>> resources = + ParseArchive(mhtml_data, sizeof(mhtml_data)); + EXPECT_EQ(0U, resources.size()); +} + } // namespace blink
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.cc index 010a204..4411b92e 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -443,8 +443,9 @@ } WebScopedVirtualTimePauser FrameSchedulerImpl::CreateWebScopedVirtualTimePauser( + const WTF::String& name, WebScopedVirtualTimePauser::VirtualTaskDuration duration) { - return WebScopedVirtualTimePauser(renderer_scheduler_, duration); + return WebScopedVirtualTimePauser(renderer_scheduler_, duration, name); } void FrameSchedulerImpl::DidOpenActiveConnection() {
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.h index 017b322..3d97273 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/frame_scheduler_impl.h
@@ -77,6 +77,7 @@ bool is_reload, bool is_main_frame) override; WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser( + const WTF::String& name, WebScopedVirtualTimePauser::VirtualTaskDuration duration) override; void OnFirstMeaningfulPaint() override; std::unique_ptr<ActiveConnectionHandle> OnActiveConnectionCreated() override;
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler.cc b/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler.cc index 3aa1abf..5119f6e 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler.cc +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler.cc
@@ -2417,8 +2417,10 @@ WebScopedVirtualTimePauser RendererSchedulerImpl::CreateWebScopedVirtualTimePauser( + const char* name, WebScopedVirtualTimePauser::VirtualTaskDuration duration) { - return WebScopedVirtualTimePauser(this, duration); + return WebScopedVirtualTimePauser(this, duration, + WebString(WTF::String(name))); } void RendererSchedulerImpl::RegisterTimeDomain(TimeDomain* time_domain) { @@ -2509,6 +2511,14 @@ helper_.RemoveTaskTimeObserver(task_time_observer); } +bool RendererSchedulerImpl::ContainsLocalMainFrame() { + for (auto* page_scheduler : main_thread_only().page_schedulers) { + if (page_scheduler->IsMainFrameLocal()) + return true; + } + return false; +} + void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated( base::TimeDelta queueing_time, bool is_disjoint_window) { @@ -2526,7 +2536,7 @@ } } - if (!is_disjoint_window) + if (!is_disjoint_window || !ContainsLocalMainFrame()) return; UMA_HISTOGRAM_TIMES("RendererScheduler.ExpectedTaskQueueingDuration", @@ -2548,6 +2558,9 @@ void RendererSchedulerImpl::OnReportFineGrainedExpectedQueueingTime( const char* split_description, base::TimeDelta queueing_time) { + if (!ContainsLocalMainFrame()) + return; + base::UmaHistogramCustomCounts( split_description, queueing_time.InMicroseconds(), kMinExpectedQueueingTimeBucket, kMaxExpectedQueueingTimeBucket,
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler.h b/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler.h index 5e67c59..b20cf4de 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler.h +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler.h
@@ -138,6 +138,7 @@ base::TimeDelta main_thread_responsiveness_threshold) override; void SetRendererProcessType(RendererProcessType type) override; WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser( + const char* name, WebScopedVirtualTimePauser::VirtualTaskDuration duration) override; // AutoAdvancingVirtualTimeDomain::Observer implementation: @@ -318,6 +319,8 @@ void SetStoppedInBackground(bool) const; + bool ContainsLocalMainFrame(); + struct TaskQueuePolicy { // Default constructor of TaskQueuePolicy should match behaviour of a // newly-created task queue.
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler_unittest.cc index fca09c50..5fc2bfb3 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/main_thread_scheduler_unittest.cc
@@ -3791,14 +3791,14 @@ WebScopedVirtualTimePauser pauser = scheduler_->CreateWebScopedVirtualTimePauser( - WebScopedVirtualTimePauser::VirtualTaskDuration::kInstant); + "test", WebScopedVirtualTimePauser::VirtualTaskDuration::kInstant); base::TimeTicks before = scheduler_->GetVirtualTimeDomain()->Now(); EXPECT_TRUE(scheduler_->VirtualTimeAllowedToAdvance()); - pauser.PauseVirtualTime(true); + pauser.PauseVirtualTime(); EXPECT_FALSE(scheduler_->VirtualTimeAllowedToAdvance()); - pauser.PauseVirtualTime(false); + pauser.UnpauseVirtualTime(); EXPECT_TRUE(scheduler_->VirtualTimeAllowedToAdvance()); base::TimeTicks after = scheduler_->GetVirtualTimeDomain()->Now(); EXPECT_EQ(after, before); @@ -3812,11 +3812,11 @@ WebScopedVirtualTimePauser pauser = scheduler_->CreateWebScopedVirtualTimePauser( - WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant); + "test", WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant); base::TimeTicks before = scheduler_->GetVirtualTimeDomain()->Now(); - pauser.PauseVirtualTime(true); - pauser.PauseVirtualTime(false); + pauser.PauseVirtualTime(); + pauser.UnpauseVirtualTime(); base::TimeTicks after = scheduler_->GetVirtualTimeDomain()->Now(); EXPECT_GT(after, before); }
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.cc index 4d79dbd..8fc795f 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.cc
@@ -103,6 +103,7 @@ reported_background_throttling_since_navigation_(false), has_active_connection_(false), nested_runloop_(false), + is_main_frame_local_(false), background_time_budget_pool_(nullptr), delegate_(delegate), weak_factory_(this) { @@ -147,6 +148,14 @@ frame_scheduler->SetKeepActive(keep_active); } +bool PageSchedulerImpl::IsMainFrameLocal() const { + return is_main_frame_local_; +} + +void PageSchedulerImpl::SetIsMainFrameLocal(bool is_local) { + is_main_frame_local_ = is_local; +} + std::unique_ptr<FrameSchedulerImpl> PageSchedulerImpl::CreateFrameSchedulerImpl( base::trace_event::BlameContext* blame_context, FrameScheduler::FrameType frame_type) {
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.h index 951f14540..50cdf63 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl.h
@@ -46,6 +46,8 @@ void SetPageVisible(bool page_visible) override; void SetPageFrozen(bool) override; void SetKeepActive(bool) override; + bool IsMainFrameLocal() const override; + void SetIsMainFrameLocal(bool is_local) override; std::unique_ptr<FrameScheduler> CreateFrameScheduler( BlameContext*, @@ -118,6 +120,7 @@ bool reported_background_throttling_since_navigation_; bool has_active_connection_; bool nested_runloop_; + bool is_main_frame_local_; CPUTimeBudgetPool* background_time_budget_pool_; // Not owned. PageScheduler::Delegate* delegate_; // Not owned. base::WeakPtrFactory<PageSchedulerImpl> weak_factory_;
diff --git a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc index 1d66fc7..09dd147 100644 --- a/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/main_thread/page_scheduler_impl_unittest.cc
@@ -532,16 +532,17 @@ { WebScopedVirtualTimePauser virtual_time_pauser = frame_scheduler->CreateWebScopedVirtualTimePauser( + "test", WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant); EXPECT_TRUE(scheduler_->VirtualTimeAllowedToAdvance()); - virtual_time_pauser.PauseVirtualTime(true); + virtual_time_pauser.PauseVirtualTime(); EXPECT_FALSE(scheduler_->VirtualTimeAllowedToAdvance()); - virtual_time_pauser.PauseVirtualTime(false); + virtual_time_pauser.UnpauseVirtualTime(); EXPECT_TRUE(scheduler_->VirtualTimeAllowedToAdvance()); - virtual_time_pauser.PauseVirtualTime(true); + virtual_time_pauser.PauseVirtualTime(); EXPECT_FALSE(scheduler_->VirtualTimeAllowedToAdvance()); } @@ -563,8 +564,9 @@ { WebScopedVirtualTimePauser virtual_time_pauser = frame_scheduler->CreateWebScopedVirtualTimePauser( + "test", WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant); - virtual_time_pauser.PauseVirtualTime(true); + virtual_time_pauser.PauseVirtualTime(); } *unpaused = scheduler->GetVirtualTimeDomain()->Now(); @@ -630,21 +632,21 @@ WebScopedVirtualTimePauser virtual_time_pauser1 = frame_scheduler->CreateWebScopedVirtualTimePauser( - WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant); + "test", WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant); WebScopedVirtualTimePauser virtual_time_pauser2 = frame_scheduler->CreateWebScopedVirtualTimePauser( - WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant); + "test", WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant); EXPECT_TRUE(scheduler_->VirtualTimeAllowedToAdvance()); - virtual_time_pauser1.PauseVirtualTime(true); - virtual_time_pauser2.PauseVirtualTime(true); + virtual_time_pauser1.PauseVirtualTime(); + virtual_time_pauser2.PauseVirtualTime(); EXPECT_FALSE(scheduler_->VirtualTimeAllowedToAdvance()); - virtual_time_pauser2.PauseVirtualTime(false); + virtual_time_pauser2.UnpauseVirtualTime(); EXPECT_FALSE(scheduler_->VirtualTimeAllowedToAdvance()); - virtual_time_pauser1.PauseVirtualTime(false); + virtual_time_pauser1.UnpauseVirtualTime(); EXPECT_TRUE(scheduler_->VirtualTimeAllowedToAdvance()); }
diff --git a/third_party/WebKit/Source/platform/scheduler/public/frame_scheduler.h b/third_party/WebKit/Source/platform/scheduler/public/frame_scheduler.h index 7aa9d2be..897537e 100644 --- a/third_party/WebKit/Source/platform/scheduler/public/frame_scheduler.h +++ b/third_party/WebKit/Source/platform/scheduler/public/frame_scheduler.h
@@ -148,6 +148,7 @@ // the WebScopedVirtualTimePauser returned by this method is initially // unpaused. virtual WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser( + const String& name, WebScopedVirtualTimePauser::VirtualTaskDuration) = 0; // Tells the scheduler that a provisional load has started, the scheduler may
diff --git a/third_party/WebKit/Source/platform/scheduler/public/page_scheduler.h b/third_party/WebKit/Source/platform/scheduler/public/page_scheduler.h index 13b2227..7171ba2 100644 --- a/third_party/WebKit/Source/platform/scheduler/public/page_scheduler.h +++ b/third_party/WebKit/Source/platform/scheduler/public/page_scheduler.h
@@ -35,6 +35,9 @@ // service workers, shared workers, or fetch keep-alive. // If true, then the scheduler should not freeze relevant task queues. virtual void SetKeepActive(bool) = 0; + // Whether the main frame of this page is local or not (remote). + virtual bool IsMainFrameLocal() const = 0; + virtual void SetIsMainFrameLocal(bool) = 0; // Creates a new FrameScheduler. The caller is responsible for deleting // it. All tasks executed by the frame scheduler will be attributed to
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_scoped_virtual_time_pauser.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_scoped_virtual_time_pauser.cc index b2398f1..cb0dd97 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_scoped_virtual_time_pauser.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_scoped_virtual_time_pauser.cc
@@ -5,6 +5,7 @@ #include "public/platform/WebScopedVirtualTimePauser.h" #include "base/trace_event/trace_event.h" +#include "platform/instrumentation/tracing/TracedValue.h" #include "platform/scheduler/main_thread/main_thread_scheduler.h" namespace blink { @@ -14,9 +15,11 @@ WebScopedVirtualTimePauser::WebScopedVirtualTimePauser( scheduler::RendererSchedulerImpl* scheduler, - VirtualTaskDuration duration) + VirtualTaskDuration duration, + const WebString& name) : duration_(duration), scheduler_(scheduler), + debug_name_(name), trace_id_(WebScopedVirtualTimePauser::next_trace_id_++) {} WebScopedVirtualTimePauser::~WebScopedVirtualTimePauser() { @@ -30,6 +33,7 @@ paused_ = other.paused_; duration_ = other.duration_; scheduler_ = std::move(other.scheduler_); + debug_name_ = std::move(other.debug_name_); other.scheduler_ = nullptr; trace_id_ = other.trace_id_; } @@ -42,27 +46,32 @@ paused_ = other.paused_; duration_ = other.duration_; scheduler_ = std::move(other.scheduler_); + debug_name_ = std::move(other.debug_name_); trace_id_ = other.trace_id_; other.scheduler_ = nullptr; return *this; } -void WebScopedVirtualTimePauser::PauseVirtualTime(bool paused) { - if (paused == paused_ || !scheduler_) +void WebScopedVirtualTimePauser::PauseVirtualTime() { + if (paused_ || !scheduler_) return; - paused_ = paused; - if (paused_) { - TRACE_EVENT_NESTABLE_ASYNC_BEGIN0( - "renderer.scheduler", "WebScopedVirtualTimePauser::PauseVirtualTime", - trace_id_); - virtual_time_when_paused_ = scheduler_->IncrementVirtualTimePauseCount(); - } else { - TRACE_EVENT_NESTABLE_ASYNC_END0( - "renderer.scheduler", "WebScopedVirtualTimePauser::PauseVirtualTime", - trace_id_); - DecrementVirtualTimePauseCount(); - } + paused_ = true; + TRACE_EVENT_NESTABLE_ASYNC_BEGIN1( + "renderer.scheduler", "WebScopedVirtualTimePauser::PauseVirtualTime", + trace_id_, "name", debug_name_.Latin1()); + virtual_time_when_paused_ = scheduler_->IncrementVirtualTimePauseCount(); +} + +void WebScopedVirtualTimePauser::UnpauseVirtualTime() { + if (!paused_ || !scheduler_) + return; + + paused_ = false; + TRACE_EVENT_NESTABLE_ASYNC_END0( + "renderer.scheduler", "WebScopedVirtualTimePauser::PauseVirtualTime", + trace_id_); + DecrementVirtualTimePauseCount(); } void WebScopedVirtualTimePauser::DecrementVirtualTimePauseCount() {
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_frame_scheduler.h b/third_party/WebKit/Source/platform/scheduler/test/fake_frame_scheduler.h index 02e88c1..1303dc6 100644 --- a/third_party/WebKit/Source/platform/scheduler/test/fake_frame_scheduler.h +++ b/third_party/WebKit/Source/platform/scheduler/test/fake_frame_scheduler.h
@@ -122,6 +122,7 @@ } PageScheduler* GetPageScheduler() const override { return page_scheduler_; } WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser( + const WTF::String& name, WebScopedVirtualTimePauser::VirtualTaskDuration duration) { return WebScopedVirtualTimePauser(); }
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_page_scheduler.h b/third_party/WebKit/Source/platform/scheduler/test/fake_page_scheduler.h index f4f93a94..efff7df 100644 --- a/third_party/WebKit/Source/platform/scheduler/test/fake_page_scheduler.h +++ b/third_party/WebKit/Source/platform/scheduler/test/fake_page_scheduler.h
@@ -48,9 +48,12 @@ return is_throttling_exempt_; } + // PageScheduler implementation: void SetPageVisible(bool is_page_visible) override {} void SetPageFrozen(bool is_page_frozen) override {} void SetKeepActive(bool keep_active) override {} + bool IsMainFrameLocal() const override { return true; } + void SetIsMainFrameLocal(bool is_local) override {} std::unique_ptr<FrameScheduler> CreateFrameScheduler( BlameContext* blame_context,
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_renderer_scheduler.cc b/third_party/WebKit/Source/platform/scheduler/test/fake_renderer_scheduler.cc index f420490..72ced3e 100644 --- a/third_party/WebKit/Source/platform/scheduler/test/fake_renderer_scheduler.cc +++ b/third_party/WebKit/Source/platform/scheduler/test/fake_renderer_scheduler.cc
@@ -7,6 +7,7 @@ #include "base/message_loop/message_loop.h" #include "base/single_thread_task_runner.h" #include "build/build_config.h" +#include "platform/wtf/text/WTFString.h" #include "public/platform/WebThread.h" namespace blink { @@ -130,8 +131,10 @@ WebScopedVirtualTimePauser FakeRendererScheduler::CreateWebScopedVirtualTimePauser( + const char* name, WebScopedVirtualTimePauser::VirtualTaskDuration duration) { - return WebScopedVirtualTimePauser(nullptr, duration); + return WebScopedVirtualTimePauser(nullptr, duration, + WebString(WTF::String(name))); } } // namespace scheduler
diff --git a/third_party/WebKit/public/platform/WebScopedVirtualTimePauser.h b/third_party/WebKit/public/platform/WebScopedVirtualTimePauser.h index 5ee1de2..e9d5a50c 100644 --- a/third_party/WebKit/public/platform/WebScopedVirtualTimePauser.h +++ b/third_party/WebKit/public/platform/WebScopedVirtualTimePauser.h
@@ -7,6 +7,7 @@ #include "WebCommon.h" #include "base/time/time.h" +#include "third_party/WebKit/public/platform/WebString.h" namespace blink { namespace scheduler { @@ -25,7 +26,8 @@ // Note simply creating a WebScopedVirtualTimePauser doesn't cause VirtualTime // to pause, instead you need to call PauseVirtualTime. WebScopedVirtualTimePauser(scheduler::RendererSchedulerImpl*, - VirtualTaskDuration); + VirtualTaskDuration, + const WebString& debug_name); WebScopedVirtualTimePauser(); ~WebScopedVirtualTimePauser(); @@ -40,7 +42,8 @@ // Virtual time will be paused if any WebScopedVirtualTimePauser votes to // pause it, and only unpaused only if all WebScopedVirtualTimePauser are // either destroyed or vote to unpause. - void PauseVirtualTime(bool paused); + void PauseVirtualTime(); + void UnpauseVirtualTime(); private: void DecrementVirtualTimePauseCount(); @@ -49,6 +52,7 @@ bool paused_ = false; VirtualTaskDuration duration_ = VirtualTaskDuration::kInstant; scheduler::RendererSchedulerImpl* scheduler_; // NOT OWNED + WebString debug_name_; int trace_id_; static int next_trace_id_;
diff --git a/third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h b/third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h index 2b0ec0c..d8b75fd 100644 --- a/third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h +++ b/third_party/WebKit/public/platform/scheduler/test/fake_renderer_scheduler.h
@@ -64,6 +64,7 @@ base::TimeDelta main_thread_responsiveness_threshold) override; void SetRendererProcessType(RendererProcessType type) override; WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser( + const char* name, WebScopedVirtualTimePauser::VirtualTaskDuration duration) override; private:
diff --git a/third_party/WebKit/public/platform/scheduler/test/mock_renderer_scheduler.h b/third_party/WebKit/public/platform/scheduler/test/mock_renderer_scheduler.h index 4e36ff1..b49fe28 100644 --- a/third_party/WebKit/public/platform/scheduler/test/mock_renderer_scheduler.h +++ b/third_party/WebKit/public/platform/scheduler/test/mock_renderer_scheduler.h
@@ -69,8 +69,9 @@ MOCK_METHOD1(SetRAILModeObserver, void(RAILModeObserver*)); MOCK_METHOD1(MainThreadSeemsUnresponsive, bool(base::TimeDelta)); MOCK_METHOD1(SetRendererProcessType, void(RendererProcessType)); - MOCK_METHOD1(CreateWebScopedVirtualTimePauser, + MOCK_METHOD2(CreateWebScopedVirtualTimePauser, WebScopedVirtualTimePauser( + const char* name, WebScopedVirtualTimePauser::VirtualTaskDuration)); private:
diff --git a/third_party/WebKit/public/platform/scheduler/web_main_thread_scheduler.h b/third_party/WebKit/public/platform/scheduler/web_main_thread_scheduler.h index a9eae512..3d142487 100644 --- a/third_party/WebKit/public/platform/scheduler/web_main_thread_scheduler.h +++ b/third_party/WebKit/public/platform/scheduler/web_main_thread_scheduler.h
@@ -223,6 +223,7 @@ // the WebScopedVirtualTimePauser returned by this method is initially // unpaused. virtual WebScopedVirtualTimePauser CreateWebScopedVirtualTimePauser( + const char* name, WebScopedVirtualTimePauser::VirtualTaskDuration duration = WebScopedVirtualTimePauser::VirtualTaskDuration::kNonInstant) = 0;
diff --git a/third_party/WebKit/public/platform/web_feature.mojom b/third_party/WebKit/public/platform/web_feature.mojom index ed0d4f13..6532617 100644 --- a/third_party/WebKit/public/platform/web_feature.mojom +++ b/third_party/WebKit/public/platform/web_feature.mojom
@@ -1891,6 +1891,8 @@ kReadableStreamConstructor = 2399, kWritableStreamConstructor = 2400, kTransformStreamConstructor = 2401, + kNegativeBackgroundSize = 2402, + kNegativeMaskSize = 2403, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots.
diff --git a/tools/binary_size/README.md b/tools/binary_size/README.md index 8b9a87c..20682703 100644 --- a/tools/binary_size/README.md +++ b/tools/binary_size/README.md
@@ -1,8 +1,8 @@ # Tools for Analyzing Chrome's Binary Size -These tools currently focus on Android. They somewhat work with Linux builds, -but not as well. As for Windows, some great tools already exist and are -documented here: +These tools currently focus on supporting Android. They somewhat work with +Linux builds. As for Windows, some great tools already exist and are documented +here: * https://www.chromium.org/developers/windows-binary-sizes @@ -73,13 +73,17 @@ `.size` files are gzipped plain text files that contain: -1. A list of .so section sizes, as reported by `readelf -S`, -1. Metadata (GN args, filenames, timestamps, git revision, build id), +1. A list of section sizes, including: + * .so sections as reported by `readelf -S` + * .pak and .dex sections for apk files +1. Metadata (apk size, GN args, filenames, timestamps, git revision, build id), 1. A list of symbols, including name, address, size, - padding (caused by alignment), and associated `.o` / `.cc` files. + padding (caused by alignment), and associated source/object files. #### How are Symbols Collected? +##### Native Symbols + 1. Symbol list is Extracted from linker `.map` file. * Map files contain some unique pieces of information compared to `nm` output, such as `** merge strings` entries, and some unnamed symbols (which @@ -102,6 +106,46 @@ set to `{shared}/$SYMBOL_COUNT`. This collapsing is done only for symbols owned by a large number of paths. +##### Pak Symbols + +1. Grit creates a mapping between numeric id and textual id for grd files. + * A side effect of pak whitelist generation is a mapping of `.cc` to numeric + id. + * A complete per-apk mapping of numeric id to textual id is stored in the + `output_dir/size-info` dir. +1. `supersize` uses these two mappings to find associated source files for the + pak entries found in all of the apk's `.pak` files. + * Pak entries with the same name are merged into a single symbol. + * This is the case of pak files for translations. + * The original grd file paths are stored in the full name of each symbol. + +##### Dex Symbols + +1. Java compile targets create a mapping between java fully qualified names + (FQN) and source files. + * For `.java` files the FQN of the public class is mapped to the file. + * For `.srcjar` files the FQN of the public class is mapped to the `.srcjar` + file path. + * A complete per-apk class FQN to source mapping is stored in the + `output_dir/size-info` dir. +1. The `apkanalyzer` sdk tool is used to find the size and FQN of entries in + the dex file. + * If a proguard `.mapping` file is available, that is used to get back the + original FQN. +1. The output from `apkanalyzer` is used by `supersize` along with the mapping + file to find associated source files for the dex entries found in all of the + apk's `.dex` files. + +##### Common Symbols + +1. Shared bytes are stored in symbols with names starting with `Overhead: `. + * Elf file, dex file, pak files, apk files all have compression overhead. + * These are treated as padding-only symbols to de-emphasize them in diffs. + * It is expected that these symbols have minor fluctuations since they are + affected by changes in compressibility. +1. All other files in an apk have one symbol each under the `.other` section + with their corresponding path in the apk as their associated path. + #### What Other Processing Happens? 1. Path normalization: @@ -122,7 +166,7 @@ * `template_name`: Name without argument parameters. * `full_name`: Name with all parameters. -1. Clustering +1. Clustering: * Compiler & linker optimizations can cause symbols to be broken into multiple parts to become candidates for inlining ("partial inlining"). * These symbols are sometimes suffixed with "`[clone]`" (removed by @@ -132,9 +176,18 @@ * Clustering is done by default on `SizeInfo.symbols`. To view unclustered symbols, use `SizeInfo.raw_symbols`. -1. Diffing +1. Diffing: * Some heuristics for matching up before/after symbols. +1. Simulated compression: + * Only some `.pak` files are compressed and others are kept uncompressed. + * To get a reasonable idea of actual impact to final apk size, we use a + constant compression factor for all the compressed `.pak` files. + * This prevents swings in compressed sizes for all symbols when new + entries are added or old entries are removed. + * The constant is chosen so that it minimizes overall discrepancy with + actual total compressed sizes. + #### Is Super Size a Generic Tool? No. Most of the logic is would could work for any ELF executable. However, being @@ -142,7 +195,8 @@ * Assumes `.ninja` build rules are available. * Heuristic for locating `.so` given `.apk`. - * Roadmap includes `.pak` file analysis. + * Requires `size-info` dir in output directory to analyze `.pak` and `.dex` + files. ### Usage: archive @@ -235,12 +289,6 @@ ### Roadmap 1. [Better Linux support](https://bugs.chromium.org/p/chromium/issues/detail?id=717550) (clang+lld+lto vs gcc+gold). -1. More `archive` features: - * Find out more about 0xffffffffffffffff addresses, and why such large - gaps exist after them. ([crbug/709050](https://bugs.chromium.org/p/chromium/issues/detail?id=709050)) - * Collect .pak file information (using .o.whitelist files) - * Collect java symbol information - * Collect .apk entry information 1. More `console` features: * Add `SplitByName()` - Like `GroupByName()`, but recursive. * A canned query, that does what ShowGlobals does (as described in [Windows Binary Sizes](https://www.chromium.org/developers/windows-binary-sizes)).
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py index 2930353..28de0c7 100644 --- a/tools/binary_size/libsupersize/archive.py +++ b/tools/binary_size/libsupersize/archive.py
@@ -808,15 +808,15 @@ return symbols -def _ParseApkOtherSymbols(section_sizes, apk_path): +def _ParseApkOtherSymbols(section_sizes, apk_path, apk_so_path): apk_name = os.path.basename(apk_path) apk_symbols = [] zip_info_total = 0 with zipfile.ZipFile(apk_path) as z: for zip_info in z.infolist(): zip_info_total += zip_info.compress_size - # Skip shared library, pak, and dex files as they are accounted for. - if (zip_info.filename.endswith('.so') + # Skip main shared library, pak, and dex files as they are accounted for. + if (zip_info.filename == apk_so_path or zip_info.filename.endswith('.dex') or zip_info.filename.endswith('.pak')): continue @@ -937,7 +937,8 @@ section_sizes, metadata, apk_elf_result) raw_symbols.extend( _ParseDexSymbols(section_sizes, apk_path, output_directory)) - raw_symbols.extend(_ParseApkOtherSymbols(section_sizes, apk_path)) + raw_symbols.extend( + _ParseApkOtherSymbols(section_sizes, apk_path, apk_so_path)) elif pak_files and pak_info_file: pak_symbols_by_id = _FindPakSymbolsFromFiles( pak_files, pak_info_file, output_directory)
diff --git a/tools/binary_size/libsupersize/integration_test.py b/tools/binary_size/libsupersize/integration_test.py index 16f9cfd..54161f3 100755 --- a/tools/binary_size/libsupersize/integration_test.py +++ b/tools/binary_size/libsupersize/integration_test.py
@@ -43,6 +43,7 @@ # Generated file paths relative to apk _TEST_APK_SO_PATH = 'test.so' +_TEST_APK_SMALL_SO_PATH = 'smalltest.so' _TEST_APK_DEX_PATH = 'test.dex' update_goldens = False @@ -133,6 +134,9 @@ elf_file.write(IntegrationTest._CreateBlankData(27)) with zipfile.ZipFile(_TEST_APK_PATH, 'w') as apk_file: apk_file.write(_TEST_ELF_PATH, _TEST_APK_SO_PATH) + # Exactly 8MB of data (2^23). + apk_file.writestr( + _TEST_APK_SMALL_SO_PATH, IntegrationTest._CreateBlankData(23)) pak_rel_path = os.path.relpath(_TEST_APK_PAK_PATH, _TEST_APK_ROOT_DIR) apk_file.write(_TEST_APK_PAK_PATH, pak_rel_path) # Exactly 8MB of data (2^23).
diff --git a/tools/binary_size/libsupersize/testdata/Archive_Apk.golden b/tools/binary_size/libsupersize/testdata/Archive_Apk.golden index 4fb4366..5faea8e 100644 --- a/tools/binary_size/libsupersize/testdata/Archive_Apk.golden +++ b/tools/binary_size/libsupersize/testdata/Archive_Apk.golden
@@ -1,5 +1,5 @@ apk_file_name=test.apk -apk_size=142613786 +apk_size=151002494 elf_arch=arm elf_build_id=WhatAnAmazingBuildId elf_file_name=elf @@ -42,8 +42,8 @@ * Padding accounts for 0 bytes (0.0%) * Contains 0 aliases * 0 symbols have shared ownership -Section .other: has 100.0% of 33984483 bytes accounted for from 2 symbols. 0 bytes are unaccounted for. -* Padding accounts for 33984483 bytes (100.0%) +Section .other: has 100.0% of 42373191 bytes accounted for from 3 symbols. 0 bytes are unaccounted for. +* Padding accounts for 33984583 bytes (80.2%) * Contains 0 aliases * 0 symbols have shared ownership .data@2de7000(size_without_padding=4,padding=0,full_name=google::protobuf::internal::pLinuxKernelCmpxchg,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=1) @@ -254,7 +254,8 @@ .dex@0(size_without_padding=975347,padding=0,full_name=org.chromium,object_path=test.apk/prebuilt/org/chromium,source_path=,flags={gen},num_aliases=1) .dex@0(size_without_padding=1792,padding=0,full_name=org,object_path=test.apk/prebuilt/org,source_path=,flags={gen},num_aliases=1) .dex@0(size_without_padding=4616803,padding=0,full_name=* Unattributed Dex,object_path=test.apk/prebuilt,source_path=,flags={gen},num_aliases=1) -.other@0(size_without_padding=0,padding=312,full_name=Overhead: APK file,object_path=,source_path=,flags={},num_aliases=1) +.other@0(size_without_padding=8388608,padding=0,full_name=smalltest.so,object_path=test.apk/other/smalltest.so,source_path=,flags={},num_aliases=1) +.other@0(size_without_padding=0,padding=412,full_name=Overhead: APK file,object_path=,source_path=,flags={},num_aliases=1) .other@0(size_without_padding=0,padding=33984171,full_name=Overhead: ELF file,object_path=,source_path=,flags={},num_aliases=1) .rodata@266e600(size_without_padding=5,padding=0,full_name=string literal,object_path=base/base/page_allocator.o,source_path=base/page_allocator.cc,flags={},num_aliases=2) .rodata@266e600(size_without_padding=5,padding=0,full_name=string literal,object_path=third_party/icu/icuuc/ucnv_ext.o,source_path=third_party/icu/ucnv_ext.c,flags={gen},num_aliases=2)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 59bf22f..d819fee8 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -7737,6 +7737,14 @@ <int value="3" label="User disabled"/> </enum> +<enum name="CrosComponentManagerError"> + <int value="0" label="NONE"/> + <int value="1" label="UNKNOWN_COMPONENT"/> + <int value="2" label="INSTALL_FAILURE"/> + <int value="3" label="MOUNT_FAILURE"/> + <int value="4" label="COMPATIBILITY_CHECK_FAILED"/> +</enum> + <enum name="CrosDisksArchiveType"> <int value="0" label="Unknown"/> <int value="1" label="ZIP"/> @@ -18124,6 +18132,8 @@ <int value="2399" label="ReadableStreamConstructor"/> <int value="2400" label="WritableStreamConstructor"/> <int value="2401" label="TransformStreamConstructor"/> + <int value="2402" label="NegativeBackgroundSize"/> + <int value="2403" label="NegativeMaskSize"/> </enum> <enum name="FeedbackSource"> @@ -35079,6 +35089,13 @@ <int value="2" label="Default"/> </enum> +<enum name="PeerConnectionSdpFormatReceived"> + <int value="0" label="No tracks"/> + <int value="1" label="Simple"/> + <int value="2" label="Complex (Plan B)"/> + <int value="3" label="Complex (Unified Plan)"/> +</enum> + <enum name="PeerConnectionSdpSemanticNegotiated"> <int value="0" label="None"/> <int value="1" label="Plan B"/> @@ -45986,6 +46003,7 @@ <int value="4" label="Chrome needs audio permission for voice input"/> <int value="5" label="A non-specific unsupported feature was encountered"/> <int value="6" label="The keyboard version is out-of-date"/> + <int value="7" label="The default search engine wasn't selected"/> </enum> <enum name="VRViewerType">
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 872700f..506c8c3 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -3012,6 +3012,8 @@ </histogram> <histogram name="Arc.PlayStoreShown.TimeDelta" units="ms"> +<!-- Name completed by histogram_suffixes name="ArcUserTypes" --> + <owner>yusukes@google.com</owner> <owner>khmel@google.com</owner> <summary> @@ -3032,6 +3034,15 @@ </summary> </histogram> +<histogram name="Arc.Provisioning.Result.Child" enum="ArcProvisioningResult"> + <owner>alexchau@google.com</owner> + <owner>phweiss@google.com</owner> + <summary> + The result (success or the type of failure) of ARC provisioning for child + accounts. + </summary> +</histogram> + <histogram name="Arc.Provisioning.Result.Managed" enum="ArcProvisioningResult"> <owner>alexchau@google.com</owner> <owner>phweiss@google.com</owner> @@ -3061,6 +3072,15 @@ </summary> </histogram> +<histogram name="Arc.Provisioning.TimeDelta.Failure.Child" units="ms"> + <owner>alexchau@google.com</owner> + <owner>phweiss@google.com</owner> + <summary> + Elapsed time from the signing in process start to call to onSignInFailed for + child account. + </summary> +</histogram> + <histogram name="Arc.Provisioning.TimeDelta.Failure.Managed" units="ms"> <owner>alexchau@google.com</owner> <owner>phweiss@google.com</owner> @@ -3088,6 +3108,15 @@ </summary> </histogram> +<histogram name="Arc.Provisioning.TimeDelta.Success.Child" units="ms"> + <owner>alexchau@google.com</owner> + <owner>phweiss@google.com</owner> + <summary> + Elapsed time from the signing in process start to successful call to + onSignInComplete for child account. + </summary> +</histogram> + <histogram name="Arc.Provisioning.TimeDelta.Success.Managed" units="ms"> <owner>alexchau@google.com</owner> <owner>phweiss@google.com</owner> @@ -3116,6 +3145,14 @@ </summary> </histogram> +<histogram name="Arc.Reauthorization.Result.Child" enum="ArcProvisioningResult"> + <owner>khmel@google.com</owner> + <summary> + The result (success or the type of failure) of ARC reauthorization for child + account. + </summary> +</histogram> + <histogram name="Arc.Reauthorization.Result.Managed" enum="ArcProvisioningResult"> <owner>khmel@google.com</owner> @@ -10943,6 +10980,19 @@ </summary> </histogram> +<histogram name="ComponentUpdater.ChromeOS.InstallResult" + enum="CrosComponentManagerError"> + <owner>xiaochu@chromium.org</owner> + <summary> + Chrome OS only. Installation error code in CrosComponentManager. + </summary> +</histogram> + +<histogram name="ComponentUpdater.ChromeOS.MountTime" units="ms"> + <owner>xiaochu@chromium.org</owner> + <summary>Chrome OS only. Time it takes to mount a component image.</summary> +</histogram> + <histogram name="ComponentUpdater.UpdateCompleteResult" enum="BooleanError"> <owner>sorin@chromium.org</owner> <summary>The result of an install or an update check.</summary> @@ -103111,6 +103161,20 @@ </summary> </histogram> +<histogram name="WebRTC.PeerConnection.SdpFormatReceived" + enum="PeerConnectionSdpFormatReceived"> + <owner>steveanton@chromium.org</owner> + <summary> + What SDP format is received in the remote offer. The value "no + tracks" means that no audio or video tracks were received. The value + "simple" means that at most one audio and at most one video track + was received. The value "complex" means that more than one audio + or more than one video track was received, and how this was signaled is + indicated ("Plan B" meaning with a=ssrc lines within the same m= + section and "Unified Plan" meaning with a separate m= section). + </summary> +</histogram> + <histogram name="WebRTC.PeerConnection.SdpSemanticNegotiated" enum="PeerConnectionSdpSemanticNegotiated"> <owner>hta@chromium.org</owner> @@ -105703,7 +105767,10 @@ </histogram_suffixes> <histogram_suffixes name="ArcUserTypes" separator="."> + <suffix name="Child" label="User with child accounts."/> <suffix name="Managed" label="User with forced Play Store feature"/> + <suffix name="RobotAccount" + label="Managed devices with a robot account (Public Session or Kiosk)"/> <suffix name="Unmanaged" label="User with optional Play Store feature"/> <affected-histogram name="Arc.PlayStoreShown.TimeDelta"/> </histogram_suffixes>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index df3350a..397db437 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -3452,6 +3452,18 @@ SessionTracker::GetRoundedDurationInSeconds. </summary> </metric> + <metric name="StartAction"> + <summary> + A metric to track specifically how the user got into XR presentation. 0: + Other, catch all. 1: RequestFrom2DBrowsing, the page requested + presentation while Chrome was in 2D mode. 2: RequestFromVRBrowsing, the + page requested presentation while Chrome was in VR browsing mode. 3: + HeadsetActivation, the user activated the VR headset while in 2D browsing + on the page, which listens for headset activations to request + presentation. 4: DeepLinkedApp, The page was launched in Chrome from the + VR system home (e.g., Daydream Home) and requested presentation. + </summary> + </metric> </event> </ukm-configuration>
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index cdab3686..d5a3825 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -25,7 +25,7 @@ gpu_perftests,"reveman@chromium.org, chrome-gpu-perf-owners@chromium.org",Internals>GPU jetstream,hablich@chromium.org, kraken,hablich@chromium.org, -load_library_perf_tests,, +load_library_perf_tests,"xhwang@chromium.org, crouleau@chromium.org",Internals>Media>Encrypted loading.desktop,"kouhei@chromium.org, ksakamoto@chromium.org", loading.mobile,"kouhei@chromium.org, ksakamoto@chromium.org", media.desktop,"johnchen@chromium.org, crouleau@chromium.org",Internals>Media
diff --git a/tools/perf/core/perf_data_generator.py b/tools/perf/core/perf_data_generator.py index 529f4ad..613b336 100755 --- a/tools/perf/core/perf_data_generator.py +++ b/tools/perf/core/perf_data_generator.py
@@ -913,7 +913,9 @@ 'Internals>GPU', False), 'tracing_perftests': BenchmarkMetadata( 'kkraynov@chromium.org, primiano@chromium.org', None, False), - 'load_library_perf_tests': BenchmarkMetadata(None, None, False), + 'load_library_perf_tests': BenchmarkMetadata( + 'xhwang@chromium.org, crouleau@chromium.org', + 'Internals>Media>Encrypted', False), 'media_perftests': BenchmarkMetadata('crouleau@chromium.org', None, False), 'performance_browser_tests': BenchmarkMetadata( 'miu@chromium.org', None, False), @@ -1079,6 +1081,8 @@ # of the isolate you are running. # shards: shard indices that you want the isolate to run on. If omitted # will run on all shards. +# telemetry: boolean indicating if this is a telemetry test. If omitted +# assumed to be true. NEW_PERF_RECIPE_FYI_TESTERS = { 'testers' : { 'One Buildbot Step Test Builder': { @@ -1086,6 +1090,11 @@ { 'isolate': 'telemetry_perf_tests_experimental', 'extra_args': ['--xvfb'], + }, + { + 'isolate': 'load_library_perf_tests', + 'shards': [0], + 'telemetry': False, } ], 'platform': 'linux', @@ -1106,10 +1115,9 @@ 'isolate': 'performance_test_suite', }, { - 'isolate': 'load_library_perf_tests_v2', - 'test_suite_name': 'load_library_perf_tests', - 'extra_args': ["--non-telemetry=true"], - 'shards': [0] + 'isolate': 'load_library_perf_tests', + 'shards': [0], + 'telemetry': False, } ], 'platform': 'mac', @@ -1184,7 +1192,7 @@ return len(dimensions) -def generate_performance_test(tester_config, test): +def generate_telemetry_args(tester_config): # First determine the browser that you need based on the tester browser_name = '' # For trybot testing we always use the reference build @@ -1203,20 +1211,39 @@ test_args = [ '-v', - '--browser=%s' % browser_name + '--browser=%s' % browser_name, + '--upload-results' ] - test_args += test.get('extra_args', []) + + if browser_name == 'android-webview': + test_args.append( + '--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk') # Appending testing=true if we only want to run a subset of benchmarks # for quicker testing if tester_config.get('testing', False): test_args.append('--testing=true') + return test_args + +def generate_non_telemetry_args(): + # --non-telemetry tells run_performance_tests.py that this test needs + # to be executed differently + # --migrated-test tells run_performance_test_wrapper that this has + # non-telemetry test has been migrated to the new recipe. + return [ + '--non-telemetry=true', + '--migrated-test=true' + ] + +def generate_performance_test(tester_config, test): + if test.get('telemetry', True): + test_args = generate_telemetry_args(tester_config) + else: + test_args = generate_non_telemetry_args() + # Append any additional args specific to an isolate + test_args += test.get('extra_args', []) isolate_name = test['isolate'] - if browser_name == 'android-webview': - test_args.append( - '--webview-embedder-apk=../../out/Release/apks/SystemWebViewShell.apk') - isolate_name = 'telemetry_perf_webview_tests' # Check to see if the name is different than the isolate test_suite = isolate_name
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index ddf03b3b..2433c2b1 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -210,6 +210,8 @@ crbug.com/755556 [ Android ] smoothness.tough_animation_cases/balls_css_keyframe_animations_composited_transform.html [ Skip ] crbug.com/755556 [ Mac ] smoothness.tough_animation_cases/mix_blend_mode_animation_difference.html [ Skip ] crbug.com/755556 [ Mac ] smoothness.tough_animation_cases/mix_blend_mode_animation_hue.html [ Skip ] +crbug.com/829499 [ Android_One ] smoothness.tough_animation_cases/css_animations_many_keyframes.html?N=0316 [ Skip ] +crbug.com/829499 [ Android_One ] smoothness.tough_animation_cases/web_animations_many_keyframes.html?N=0316 [ Skip ] # Benchmark: smoothness.tough_canvas_cases crbug.com/785485 [ Android_Webview ] smoothness.tough_canvas_cases/http://www.kevs3d.co.uk/dev/canvask3d/k3d_test.html [ Skip ] @@ -241,6 +243,7 @@ crbug.com/574485 [ Android_Svelte ] smoothness.tough_webgl_ad_cases/* [ Skip ] # Benchmark: system_health.common_desktop +crbug.com/828917 [ Mac ] system_health.common_desktop/multitab:misc:typical24 [ Skip ] crbug.com/728576 [ Mac ] system_health.common_desktop/browse:news:cnn [ Skip ] crbug.com/64939 [ All ] system_health.common_desktop/play:media:pandora [ Skip ] crbug.com/809146 [ All ] system_health.common_desktop/browse:media:tumblr [ Skip ] @@ -405,6 +408,7 @@ # Benchmark: v8.runtime_stats.top_25 crbug.com/664318 [ Android ] v8.runtime_stats.top_25/* [ Skip ] crbug.com/664318 [ Win ] v8.runtime_stats.top_25/* [ Skip ] +crbug.com/829504 [ Linux ] v8.runtime_stats.top_25/https://www.google.de/search?q=v8 [ Skip ] # Benchmark: wasm [ Android_One ] wasm/WasmSpaceBuggy [ Skip ]
diff --git a/tools/perf/metrics/timeline.py b/tools/perf/metrics/timeline.py index 74deec2d..61042c70 100644 --- a/tools/perf/metrics/timeline.py +++ b/tools/perf/metrics/timeline.py
@@ -16,7 +16,6 @@ TimelineThreadCategories = { "Chrome_InProcGpuThread": "GPU", "CrGpuMain": "GPU", - "AsyncTransferThread": "GPU_transfer", "VizCompositorThread": "display_compositor", "CrBrowserMain": "browser", "Browser Compositor": "browser",
diff --git a/tools/perf/unowned_benchmarks.txt b/tools/perf/unowned_benchmarks.txt index a9d36d73..1dd0cbe5 100644 --- a/tools/perf/unowned_benchmarks.txt +++ b/tools/perf/unowned_benchmarks.txt
@@ -1,4 +1,3 @@ -load_library_perf_tests smoothness.tough_image_decode_cases thread_times.key_hit_test_cases thread_times.key_noop_cases
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc index 67e142a..fc09c0b7 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
@@ -61,6 +61,12 @@ .Append(FILE_PATH_LITERAL("auditor")) .Append(FILE_PATH_LITERAL("safe_list.txt")); +const base::FilePath kClangToolSwitchesPath = + base::FilePath(FILE_PATH_LITERAL("tools")) + .Append(FILE_PATH_LITERAL("traffic_annotation")) + .Append(FILE_PATH_LITERAL("auditor")) + .Append(FILE_PATH_LITERAL("traffic_annotation_extractor_switches.txt")); + // The folder that includes the latest Clang built-in library. Inside this // folder, there should be another folder with version number, like // '.../lib/clang/6.0.0', which would be passed to the clang tool. @@ -77,10 +83,6 @@ .Append(FILE_PATH_LITERAL("scripts")) .Append(FILE_PATH_LITERAL("run_tool.py")); -const std::string kClangToolSwitches[] = { - "-Wno-comment", "-Wno-tautological-unsigned-enum-zero-compare", - "-Wno-tautological-constant-compare", "-Wno-error=unknown-warning-option"}; - // Checks if the list of |path_filters| include the given |file_path|, or there // are path filters which are a folder (don't have a '.' in their name), and // match the file name. @@ -112,6 +114,14 @@ DCHECK(!source_path.empty()); DCHECK(!build_path.empty()); DCHECK(!clang_tool_path.empty()); + + std::string file_content; + if (base::ReadFileToString(kClangToolSwitchesPath, &file_content)) { + clang_tool_switches_ = base::SplitString( + file_content, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); + } else { + LOG(ERROR) << "Could not read " << kClangToolSwitchesPath; + } } TrafficAnnotationAuditor::~TrafficAnnotationAuditor() = default; @@ -168,8 +178,9 @@ base::MakeAbsoluteFilePath(clang_tool_path_).MaybeAsASCII().c_str(), base::MakeAbsoluteFilePath(GetClangLibraryPath()).MaybeAsASCII().c_str()); - for (const std::string& item : kClangToolSwitches) + for (const std::string& item : clang_tool_switches_) fprintf(options_file, "--tool-arg=--extra-arg=%s ", item.c_str()); + if (use_compile_commands) fprintf(options_file, "--all ");
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.h b/tools/traffic_annotation/auditor/traffic_annotation_auditor.h index 62d6932e..7657437 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.h +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.h
@@ -159,6 +159,8 @@ const base::FilePath build_path_; const base::FilePath clang_tool_path_; + std::vector<std::string> clang_tool_switches_; + TrafficAnnotationExporter exporter_; std::string clang_tool_raw_output_;
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_extractor_switches.txt b/tools/traffic_annotation/auditor/traffic_annotation_extractor_switches.txt new file mode 100644 index 0000000..2b5676e --- /dev/null +++ b/tools/traffic_annotation/auditor/traffic_annotation_extractor_switches.txt
@@ -0,0 +1,4 @@ +-Wno-comment +-Wno-tautological-unsigned-enum-zero-compare +-Wno-tautological-constant-compare +-Wno-error=unknown-warning-option
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 5210c33..f95ea35 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -36,7 +36,6 @@ <item id="cast_socket" hash_code="115192205" type="0" content_hash_code="63056899" os_list="linux,windows" file_path="components/cast_channel/cast_socket.cc"/> <item id="cast_udp_socket" hash_code="22573197" type="0" content_hash_code="75328301" os_list="linux,windows" file_path="components/mirroring/service/udp_socket_client.cc"/> <item id="cast_udp_transport" hash_code="5576536" type="0" content_hash_code="107643273" os_list="linux,windows" file_path="media/cast/net/udp_transport_impl.cc"/> - <item id="certificate_reporting_service_test" hash_code="98123372" type="0" content_hash_code="136253658" os_list="linux,windows" file_path="chrome/browser/safe_browsing/certificate_reporting_service.cc"/> <item id="certificate_verifier" hash_code="113553577" type="0" content_hash_code="62346354" os_list="linux,windows" file_path="net/cert_net/cert_net_fetcher_impl.cc"/> <item id="chrome_apps_socket_api" hash_code="8591273" type="0" content_hash_code="70868355" os_list="linux,windows" file_path="extensions/browser/api/socket/socket.cc"/> <item id="chrome_cleaner" hash_code="27071967" type="0" content_hash_code="111240292" os_list="windows" file_path="chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.cc"/>
diff --git a/ui/app_list/test/test_search_result.cc b/ui/app_list/test/test_search_result.cc index 33969e45..1284c9d 100644 --- a/ui/app_list/test/test_search_result.cc +++ b/ui/app_list/test/test_search_result.cc
@@ -16,9 +16,4 @@ set_id(id); } -std::unique_ptr<SearchResult> TestSearchResult::Duplicate() const { - NOTREACHED(); - return nullptr; -} - } // namespace app_list
diff --git a/ui/app_list/test/test_search_result.h b/ui/app_list/test/test_search_result.h index 24d66e5..43d5f71 100644 --- a/ui/app_list/test/test_search_result.h +++ b/ui/app_list/test/test_search_result.h
@@ -21,9 +21,6 @@ void set_result_id(const std::string& id); - // SearchResult: - std::unique_ptr<SearchResult> Duplicate() const override; - private: DISALLOW_COPY_AND_ASSIGN(TestSearchResult); };
diff --git a/ui/aura/window_tree_host_platform.cc b/ui/aura/window_tree_host_platform.cc index 43294f6..49f53a84 100644 --- a/ui/aura/window_tree_host_platform.cc +++ b/ui/aura/window_tree_host_platform.cc
@@ -44,18 +44,7 @@ : WindowTreeHostPlatform() { bounds_ = bounds; CreateCompositor(); -#if defined(USE_OZONE) - platform_window_ = - ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds); -#elif defined(OS_WIN) - platform_window_.reset(new ui::WinWindow(this, bounds)); -#elif defined(OS_ANDROID) - platform_window_.reset(new ui::PlatformWindowAndroid(this)); -#elif defined(USE_X11) - platform_window_.reset(new ui::X11Window(this, bounds)); -#else - NOTIMPLEMENTED(); -#endif + CreateAndSetDefaultPlatformWindow(); } WindowTreeHostPlatform::WindowTreeHostPlatform() @@ -67,6 +56,21 @@ widget_(gfx::kNullAcceleratedWidget), current_cursor_(ui::CursorType::kNull) {} +void WindowTreeHostPlatform::CreateAndSetDefaultPlatformWindow() { +#if defined(USE_OZONE) + platform_window_ = + ui::OzonePlatform::GetInstance()->CreatePlatformWindow(this, bounds_); +#elif defined(OS_WIN) + platform_window_.reset(new ui::WinWindow(this, bounds_)); +#elif defined(OS_ANDROID) + platform_window_.reset(new ui::PlatformWindowAndroid(this)); +#elif defined(USE_X11) + platform_window_.reset(new ui::X11Window(this, bounds_)); +#else + NOTIMPLEMENTED(); +#endif +} + void WindowTreeHostPlatform::SetPlatformWindow( std::unique_ptr<ui::PlatformWindow> window) { platform_window_ = std::move(window); @@ -149,12 +153,10 @@ float new_scale = ui::GetScaleFactorForNativeView(window()); gfx::Rect old_bounds = bounds_; bounds_ = new_bounds; - if (bounds_.origin() != old_bounds.origin()) { + if (bounds_.origin() != old_bounds.origin()) OnHostMovedInPixels(bounds_.origin()); - } - if (bounds_.size() != old_bounds.size() || current_scale != new_scale) { + if (bounds_.size() != old_bounds.size() || current_scale != new_scale) OnHostResizedInPixels(bounds_.size()); - } } void WindowTreeHostPlatform::OnDamageRect(const gfx::Rect& damage_rect) { @@ -190,7 +192,9 @@ gfx::AcceleratedWidget widget, float device_pixel_ratio) { widget_ = widget; - WindowTreeHost::OnAcceleratedWidgetAvailable(); + // This may be called before the Compositor has been created. + if (compositor()) + WindowTreeHost::OnAcceleratedWidgetAvailable(); } void WindowTreeHostPlatform::OnAcceleratedWidgetDestroyed() {
diff --git a/ui/aura/window_tree_host_platform.h b/ui/aura/window_tree_host_platform.h index 5935d163..d07b1f32 100644 --- a/ui/aura/window_tree_host_platform.h +++ b/ui/aura/window_tree_host_platform.h
@@ -48,8 +48,15 @@ WindowTreeHostPlatform(); explicit WindowTreeHostPlatform(std::unique_ptr<WindowPort> window_port); + // Creates a ui::PlatformWindow appropriate for the current platform and + // installs it at as the PlatformWindow for this WindowTreeHostPlatform. + void CreateAndSetDefaultPlatformWindow(); + void SetPlatformWindow(std::unique_ptr<ui::PlatformWindow> window); ui::PlatformWindow* platform_window() { return platform_window_.get(); } + const ui::PlatformWindow* platform_window() const { + return platform_window_.get(); + } // ui::PlatformWindowDelegate: void OnBoundsChanged(const gfx::Rect& new_bounds) override;
diff --git a/ui/base/material_design/material_design_controller.cc b/ui/base/material_design/material_design_controller.cc index d4dd4b1..5abb641 100644 --- a/ui/base/material_design/material_design_controller.cc +++ b/ui/base/material_design/material_design_controller.cc
@@ -120,7 +120,8 @@ // static bool MaterialDesignController::IsSecondaryUiMaterial() { - return base::FeatureList::IsEnabled(features::kSecondaryUiMd); + return base::FeatureList::IsEnabled(features::kSecondaryUiMd) || + GetMode() == MATERIAL_REFRESH; } // static
diff --git a/ui/display/BUILD.gn b/ui/display/BUILD.gn index 8d61a7f..c19111ef 100644 --- a/ui/display/BUILD.gn +++ b/ui/display/BUILD.gn
@@ -113,6 +113,8 @@ "test/display_matchers.cc", "test/display_matchers.h", "test/display_test_util.h", + "test/scoped_screen_override.cc", + "test/scoped_screen_override.h", "test/test_screen.cc", "test/test_screen.h", "win/test/screen_util_win.cc",
diff --git a/ui/display/test/scoped_screen_override.cc b/ui/display/test/scoped_screen_override.cc new file mode 100644 index 0000000..11fadc1 --- /dev/null +++ b/ui/display/test/scoped_screen_override.cc
@@ -0,0 +1,22 @@ +// Copyright 2018 The Chromium Authors. 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/display/test/scoped_screen_override.h" + +#include "ui/display/screen.h" + +namespace display { +namespace test { + +ScopedScreenOverride::ScopedScreenOverride(Screen* screen) + : original_screen_(display::Screen::GetScreen()) { + display::Screen::SetScreenInstance(screen); +} + +ScopedScreenOverride::~ScopedScreenOverride() { + display::Screen::SetScreenInstance(original_screen_); +} + +} // namespace test +} // namespace display
diff --git a/ui/display/test/scoped_screen_override.h b/ui/display/test/scoped_screen_override.h new file mode 100644 index 0000000..6166216 --- /dev/null +++ b/ui/display/test/scoped_screen_override.h
@@ -0,0 +1,33 @@ +// Copyright 2018 The Chromium Authors. 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_DISPLAY_TEST_SCOPED_SCREEN_OVERRIDE_H_ +#define UI_DISPLAY_TEST_SCOPED_SCREEN_OVERRIDE_H_ + +#include "base/macros.h" + +namespace display { + +class Screen; + +namespace test { + +// This class represents a RAII wrapper for global screen overriding. An object +// of this class restores original display::Screen instance when it goes out of +// scope. Prefer to use it instead of directly call of +// display::Screen::SetScreenInstance(). +class ScopedScreenOverride { + public: + explicit ScopedScreenOverride(Screen* screen); + ~ScopedScreenOverride(); + + private: + Screen* original_screen_; + DISALLOW_COPY_AND_ASSIGN(ScopedScreenOverride); +}; + +} // namespace test +} // namespace display + +#endif // UI_DISPLAY_TEST_SCOPED_SCREEN_OVERRIDE_H_
diff --git a/ui/events/blink/input_handler_proxy_unittest.cc b/ui/events/blink/input_handler_proxy_unittest.cc index ff87840d..f1dda975 100644 --- a/ui/events/blink/input_handler_proxy_unittest.cc +++ b/ui/events/blink/input_handler_proxy_unittest.cc
@@ -1907,12 +1907,15 @@ // GSUs and GPUs in one sequence should be coalesced into 1 GSU and 1 GPU. HandleGestureEvent(WebInputEvent::kGestureScrollBegin); + HandleGestureEvent(WebInputEvent::kGesturePinchBegin); HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -20); HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -7); HandleGestureEvent(WebInputEvent::kGesturePinchUpdate, 2.0f, 13, 10); HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -10); HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -6); + HandleGestureEvent(WebInputEvent::kGesturePinchEnd); HandleGestureEvent(WebInputEvent::kGestureScrollEnd); + HandleGestureEvent(WebInputEvent::kGestureScrollBegin); HandleGestureEvent(WebInputEvent::kGesturePinchBegin); HandleGestureEvent(WebInputEvent::kGesturePinchUpdate, 0.2f, 2, 20); HandleGestureEvent(WebInputEvent::kGesturePinchUpdate, 10.0f, 1, 10); @@ -1920,37 +1923,46 @@ HandleGestureEvent(WebInputEvent::kGesturePinchUpdate, 0.25f, 3, 30); HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -10); HandleGestureEvent(WebInputEvent::kGesturePinchEnd); + HandleGestureEvent(WebInputEvent::kGestureScrollEnd); // Only the first GSB was dispatched. - EXPECT_EQ(7ul, event_queue().size()); + EXPECT_EQ(11ul, event_queue().size()); EXPECT_EQ(1ul, event_disposition_recorder_.size()); - EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, + EXPECT_EQ(WebInputEvent::kGesturePinchBegin, event_queue()[0]->event().GetType()); - EXPECT_EQ( - -35, - ToWebGestureEvent(event_queue()[0]->event()).data.scroll_update.delta_y); - EXPECT_EQ(WebInputEvent::kGesturePinchUpdate, + EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, event_queue()[1]->event().GetType()); EXPECT_EQ( - 2.0f, - ToWebGestureEvent(event_queue()[1]->event()).data.pinch_update.scale); - EXPECT_EQ(WebInputEvent::kGestureScrollEnd, + -35, + ToWebGestureEvent(event_queue()[1]->event()).data.scroll_update.delta_y); + EXPECT_EQ(WebInputEvent::kGesturePinchUpdate, event_queue()[2]->event().GetType()); - EXPECT_EQ(WebInputEvent::kGesturePinchBegin, + EXPECT_EQ( + 2.0f, + ToWebGestureEvent(event_queue()[2]->event()).data.pinch_update.scale); + EXPECT_EQ(WebInputEvent::kGesturePinchEnd, event_queue()[3]->event().GetType()); - EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, + EXPECT_EQ(WebInputEvent::kGestureScrollEnd, event_queue()[4]->event().GetType()); + EXPECT_EQ(WebInputEvent::kGestureScrollBegin, + event_queue()[5]->event().GetType()); + EXPECT_EQ(WebInputEvent::kGesturePinchBegin, + event_queue()[6]->event().GetType()); + EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, + event_queue()[7]->event().GetType()); EXPECT_EQ( -85, - ToWebGestureEvent(event_queue()[4]->event()).data.scroll_update.delta_y); + ToWebGestureEvent(event_queue()[7]->event()).data.scroll_update.delta_y); EXPECT_EQ(WebInputEvent::kGesturePinchUpdate, - event_queue()[5]->event().GetType()); + event_queue()[8]->event().GetType()); EXPECT_EQ( 0.5f, - ToWebGestureEvent(event_queue()[5]->event()).data.pinch_update.scale); + ToWebGestureEvent(event_queue()[8]->event()).data.pinch_update.scale); EXPECT_EQ(WebInputEvent::kGesturePinchEnd, - event_queue()[6]->event().GetType()); + event_queue()[9]->event().GetType()); + EXPECT_EQ(WebInputEvent::kGestureScrollEnd, + event_queue()[10]->event().GetType()); testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); } @@ -1970,6 +1982,10 @@ EXPECT_CALL(mock_input_handler_, ScrollEnd(testing::_, true)) .Times(::testing::AtLeast(1)); + EXPECT_CALL(mock_input_handler_, PinchGestureBegin()); + EXPECT_CALL(mock_input_handler_, PinchGestureUpdate(testing::_, testing::_)); + EXPECT_CALL(mock_input_handler_, PinchGestureEnd(testing::_, testing::_)); + trace_analyzer::Start("*"); // Simulate scroll. HandleGestureEvent(WebInputEvent::kGestureScrollBegin); @@ -1980,10 +1996,12 @@ // Simulate scroll and pinch. HandleGestureEvent(WebInputEvent::kGestureScrollBegin); + HandleGestureEvent(WebInputEvent::kGesturePinchBegin); HandleGestureEvent(WebInputEvent::kGesturePinchUpdate, 10.0f, 1, 10); HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -10); HandleGestureEvent(WebInputEvent::kGesturePinchUpdate, 2.0f, 1, 10); HandleGestureEvent(WebInputEvent::kGestureScrollUpdate, -30); + HandleGestureEvent(WebInputEvent::kGesturePinchEnd); HandleGestureEvent(WebInputEvent::kGestureScrollEnd); // Dispatch all events. @@ -2001,8 +2019,8 @@ trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_NESTABLE_ASYNC_END); analyzer->FindEvents(end_query, &end_events); - EXPECT_EQ(5ul, begin_events.size()); - EXPECT_EQ(5ul, end_events.size()); + EXPECT_EQ(7ul, begin_events.size()); + EXPECT_EQ(7ul, end_events.size()); EXPECT_EQ(WebInputEvent::kGestureScrollUpdate, end_events[0]->GetKnownArgAsInt("type")); EXPECT_EQ(3, end_events[0]->GetKnownArgAsInt("coalesced_count")); @@ -2011,15 +2029,19 @@ EXPECT_EQ(WebInputEvent::kGestureScrollBegin, end_events[2]->GetKnownArgAsInt("type")); + EXPECT_EQ(WebInputEvent::kGesturePinchBegin, + end_events[3]->GetKnownArgAsInt("type")); // Original scroll and pinch updates will be stored in the coalesced // PinchUpdate of the <ScrollUpdate, PinchUpdate> pair. // The ScrollUpdate of the pair doesn't carry original events and won't be // traced. EXPECT_EQ(WebInputEvent::kGesturePinchUpdate, - end_events[3]->GetKnownArgAsInt("type")); - EXPECT_EQ(4, end_events[3]->GetKnownArgAsInt("coalesced_count")); - EXPECT_EQ(WebInputEvent::kGestureScrollEnd, end_events[4]->GetKnownArgAsInt("type")); + EXPECT_EQ(4, end_events[4]->GetKnownArgAsInt("coalesced_count")); + EXPECT_EQ(WebInputEvent::kGesturePinchEnd, + end_events[5]->GetKnownArgAsInt("type")); + EXPECT_EQ(WebInputEvent::kGestureScrollEnd, + end_events[6]->GetKnownArgAsInt("type")); testing::Mock::VerifyAndClearExpectations(&mock_input_handler_); }
diff --git a/ui/gfx/color_space.cc b/ui/gfx/color_space.cc index 188cc48..54be4df 100644 --- a/ui/gfx/color_space.cc +++ b/ui/gfx/color_space.cc
@@ -923,6 +923,28 @@ } } +bool ColorSpace::ToSkYUVColorSpace(SkYUVColorSpace* out) { + if (range_ == RangeID::FULL) { + *out = kJPEG_SkYUVColorSpace; + return true; + } + switch (matrix_) { + case MatrixID::BT709: + *out = kRec709_SkYUVColorSpace; + return true; + + case MatrixID::BT470BG: + case MatrixID::SMPTE170M: + case MatrixID::SMPTE240M: + *out = kRec601_SkYUVColorSpace; + return true; + + default: + break; + } + return false; +} + std::ostream& operator<<(std::ostream& out, const ColorSpace& color_space) { return out << color_space.ToString(); }
diff --git a/ui/gfx/color_space.h b/ui/gfx/color_space.h index 561cbc7..aa70e54 100644 --- a/ui/gfx/color_space.h +++ b/ui/gfx/color_space.h
@@ -13,6 +13,7 @@ #include "base/macros.h" #include "build/build_config.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImageInfo.h" #include "ui/gfx/color_space_export.h" namespace IPC { @@ -187,6 +188,10 @@ // range, and unspecified spaces. sk_sp<SkColorSpace> ToSkColorSpace() const; + // For YUV color spaces, return the closest SkYUVColorSpace. + // Returns true if a close match is found. + bool ToSkYUVColorSpace(SkYUVColorSpace* out); + void GetPrimaryMatrix(SkMatrix44* to_XYZD50) const; bool GetTransferFunction(SkColorSpaceTransferFn* fn) const; bool GetInverseTransferFunction(SkColorSpaceTransferFn* fn) const;
diff --git a/ui/latency/windowed_analyzer.h b/ui/latency/windowed_analyzer.h index cf03264..004ffc9 100644 --- a/ui/latency/windowed_analyzer.h +++ b/ui/latency/windowed_analyzer.h
@@ -49,6 +49,18 @@ // Tracks the current window of time that can be stored as the worst // window of time if a metric detects it as such. struct SharedWindowedAnalyzerClient { + SharedWindowedAnalyzerClient() : max_window_size(0) {} + + explicit SharedWindowedAnalyzerClient(size_t max_window_size) + : max_window_size(max_window_size) {} + + SharedWindowedAnalyzerClient(size_t max_window_size, + base::TimeTicks window_begin, + base::TimeTicks window_end) + : max_window_size(max_window_size), + window_begin(window_begin), + window_end(window_end) {} + // Maximum window size in number of samples. size_t max_window_size;
diff --git a/ui/latency/windowed_analyzer_unittest.cc b/ui/latency/windowed_analyzer_unittest.cc index 7ae681d5..96fb6788 100644 --- a/ui/latency/windowed_analyzer_unittest.cc +++ b/ui/latency/windowed_analyzer_unittest.cc
@@ -17,9 +17,9 @@ TEST(FrameMetricsWindowedAnalyzerTest, AllResultsTheSame) { // For this test, we don't care about the timeline, so just keep it constant. TestWindowedAnalyzerClient client; - SharedWindowedAnalyzerClient shared_client{ + SharedWindowedAnalyzerClient shared_client( 60, base::TimeTicks(), - base::TimeTicks() + base::TimeDelta::FromSeconds(1)}; + base::TimeTicks() + base::TimeDelta::FromSeconds(1)); // Try adding a single sample vs. multiple samples. for (size_t samples : {1u, 100u}) { @@ -71,9 +71,9 @@ const uint32_t kSampleWeight = 100; TestWindowedAnalyzerClient client; - SharedWindowedAnalyzerClient shared_client{ + SharedWindowedAnalyzerClient shared_client( kMaxWindowSize, base::TimeTicks(), - base::TimeTicks() + base::TimeDelta::FromSeconds(1)}; + base::TimeTicks() + base::TimeDelta::FromSeconds(1)); WindowedAnalyzer analyzer(&client, &shared_client); // Used to "clear" all the windowed accumulators. @@ -95,15 +95,15 @@ AddPatternHelper(&shared_client, &analyzer, pattern_clear, kSampleWeight); AddPatternHelper(&shared_client, &analyzer, pattern_max_mean, kSampleWeight); - SharedWindowedAnalyzerClient worst_mean_client = shared_client; + SharedWindowedAnalyzerClient worst_mean_client(shared_client); AddPatternHelper(&shared_client, &analyzer, pattern_clear, kSampleWeight); AddPatternHelper(&shared_client, &analyzer, pattern_max_smr, kSampleWeight); - SharedWindowedAnalyzerClient worst_smr_client = shared_client; + SharedWindowedAnalyzerClient worst_smr_client(shared_client); AddPatternHelper(&shared_client, &analyzer, pattern_clear, kSampleWeight); AddPatternHelper(&shared_client, &analyzer, pattern_max_rms, kSampleWeight); - SharedWindowedAnalyzerClient worst_rms_client = shared_client; + SharedWindowedAnalyzerClient worst_rms_client(shared_client); // If there is a tie, the first window detected wins. // This can go wrong if there's any accumulation of error because the @@ -141,16 +141,16 @@ const uint32_t kSampleWeight = 100; TestWindowedAnalyzerClient client; - SharedWindowedAnalyzerClient shared_client{ + SharedWindowedAnalyzerClient shared_client( kMaxWindowSize, base::TimeTicks(), - base::TimeTicks() + base::TimeDelta::FromSeconds(1)}; + base::TimeTicks() + base::TimeDelta::FromSeconds(1)); WindowedAnalyzer analyzer(&client, &shared_client); const std::vector<uint32_t> pattern_short = {2, 2, 2}; double expected_initial_value = 2 * kFixedPointMultiplier * TestWindowedAnalyzerClient::result_scale; AddPatternHelper(&shared_client, &analyzer, pattern_short, kSampleWeight); - SharedWindowedAnalyzerClient short_client = shared_client; + SharedWindowedAnalyzerClient short_client(shared_client); FrameRegionResult worst_mean = analyzer.WorstMean(); EXPECT_DOUBLE_EQ(expected_initial_value, worst_mean.value); @@ -175,9 +175,9 @@ FrameRegionResult worst_mean, worst_smr, worst_rms; TestWindowedAnalyzerClient client; - SharedWindowedAnalyzerClient shared_client{ + SharedWindowedAnalyzerClient shared_client( kMaxWindowSize, base::TimeTicks(), - base::TimeTicks() + base::TimeDelta::FromSeconds(1)}; + base::TimeTicks() + base::TimeDelta::FromSeconds(1)); WindowedAnalyzer analyzer(&client, &shared_client); // The 7's at the start will dominate the result if the implemenationd @@ -187,7 +187,7 @@ double expected_initial_value = 7 * kFixedPointMultiplier * TestWindowedAnalyzerClient::result_scale; AddPatternHelper(&shared_client, &analyzer, pattern_short, kSampleWeight); - SharedWindowedAnalyzerClient short_client = shared_client; + SharedWindowedAnalyzerClient short_client(shared_client); worst_mean = analyzer.WorstMean(); EXPECT_DOUBLE_EQ(expected_initial_value, worst_mean.value); @@ -213,7 +213,7 @@ double expected_final_value = 6 * kFixedPointMultiplier * TestWindowedAnalyzerClient::result_scale; AddPatternHelper(&shared_client, &analyzer, pattern_long, kSampleWeight); - SharedWindowedAnalyzerClient long_client = shared_client; + SharedWindowedAnalyzerClient long_client(shared_client); worst_mean = analyzer.WorstMean(); EXPECT_DOUBLE_EQ(expected_final_value, worst_mean.value); @@ -238,9 +238,9 @@ FrameRegionResult worst_mean, worst_smr, worst_rms; TestWindowedAnalyzerClient client; - SharedWindowedAnalyzerClient shared_client{ + SharedWindowedAnalyzerClient shared_client( kMaxWindowSize, base::TimeTicks(), - base::TimeTicks() + base::TimeDelta::FromSeconds(1)}; + base::TimeTicks() + base::TimeDelta::FromSeconds(1)); WindowedAnalyzer analyzer(&client, &shared_client); // Start off with the worst pattern. @@ -248,7 +248,7 @@ double expected_initial_value = 9 * kFixedPointMultiplier * TestWindowedAnalyzerClient::result_scale; AddPatternHelper(&shared_client, &analyzer, pattern1, kSampleWeight); - SharedWindowedAnalyzerClient initial_client = shared_client; + SharedWindowedAnalyzerClient initial_client(shared_client); worst_mean = analyzer.WorstMean(); EXPECT_DOUBLE_EQ(expected_initial_value, worst_mean.value); @@ -295,7 +295,7 @@ double expected_final_value = 4 * kFixedPointMultiplier * TestWindowedAnalyzerClient::result_scale; AddPatternHelper(&shared_client, &analyzer, pattern3, kSampleWeight); - SharedWindowedAnalyzerClient final_client = shared_client; + SharedWindowedAnalyzerClient final_client(shared_client); // Add a window of 1's here to verify it does not affect the window of 4's. const std::vector<uint32_t> pattern4 = {1, 1, 1, 1, 1, 1}; @@ -393,15 +393,15 @@ // Set up the actual WindowedAnalyzer implementation. TestWindowedAnalyzerClient client_impl; - SharedWindowedAnalyzerClient shared_client_impl{ + SharedWindowedAnalyzerClient shared_client_impl( kMaxWindowSize, base::TimeTicks(), - base::TimeTicks() + base::TimeDelta::FromSeconds(1)}; + base::TimeTicks() + base::TimeDelta::FromSeconds(1)); TestWindowedAnalyzer analyzer_impl(&client_impl, &shared_client_impl); // Set up the naive WindowedAnalyzer implementation. - SharedWindowedAnalyzerClient shared_client_naive{ + SharedWindowedAnalyzerClient shared_client_naive( kMaxWindowSize, base::TimeTicks(), - base::TimeTicks() + base::TimeDelta::FromSeconds(1)}; + base::TimeTicks() + base::TimeDelta::FromSeconds(1)); WindowedAnalyzerNaive analyzer_naive(kMaxWindowSize); // Verify error keeps accumulating each time the bad pattern is applied.
diff --git a/ui/ozone/platform/cast/platform_window_cast.cc b/ui/ozone/platform/cast/platform_window_cast.cc index 08ce52b..a24276ca 100644 --- a/ui/ozone/platform/cast/platform_window_cast.cc +++ b/ui/ozone/platform/cast/platform_window_cast.cc
@@ -39,6 +39,10 @@ void PlatformWindowCast::SetTitle(const base::string16& title) { } +bool PlatformWindowCast::HasCapture() const { + return false; +} + PlatformImeController* PlatformWindowCast::GetPlatformImeController() { return nullptr; }
diff --git a/ui/ozone/platform/cast/platform_window_cast.h b/ui/ozone/platform/cast/platform_window_cast.h index 4a494f2..a7930ee 100644 --- a/ui/ozone/platform/cast/platform_window_cast.h +++ b/ui/ozone/platform/cast/platform_window_cast.h
@@ -31,6 +31,7 @@ void PrepareForShutdown() override {} void SetCapture() override {} void ReleaseCapture() override {} + bool HasCapture() const override; void ToggleFullscreen() override {} void Maximize() override {} void Minimize() override {}
diff --git a/ui/ozone/platform/drm/host/drm_display_host_manager.cc b/ui/ozone/platform/drm/host/drm_display_host_manager.cc index fa48339..7a236a5 100644 --- a/ui/ozone/platform/drm/host/drm_display_host_manager.cc +++ b/ui/ozone/platform/drm/host/drm_display_host_manager.cc
@@ -322,7 +322,7 @@ MapDevPathToSysPath(primary_graphics_card_path_); if (!handle) { - handle.reset(new DrmDeviceHandle()); + handle = std::make_unique<DrmDeviceHandle>(); if (!handle->Initialize(primary_graphics_card_path_, drm_devices_[primary_graphics_card_path_])) LOG(FATAL) << "Failed to open primary graphics card"; @@ -331,8 +331,10 @@ // Send the primary device first since this is used to initialize graphics // state. - proxy_->GpuAddGraphicsDevice(drm_devices_[primary_graphics_card_path_], - handle->PassFD()); + if (!proxy_->GpuAddGraphicsDevice(drm_devices_[primary_graphics_card_path_], + handle->PassFD())) { + LOG(ERROR) << "Failed to add primary graphics device."; + } } void DrmDisplayHostManager::OnGpuThreadReady() {
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc index 44d276df..09632b1 100644 --- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc +++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.cc
@@ -115,7 +115,8 @@ } bool DrmGpuPlatformSupportHost::IsConnected() { - return host_id_ >= 0 && channel_established_; + base::AutoLock auto_lock(host_id_lock_); + return host_id_ >= 0; } void DrmGpuPlatformSupportHost::OnGpuServiceLaunched( @@ -139,27 +140,23 @@ DCHECK(!ui_runner_->BelongsToCurrentThread()); TRACE_EVENT1("drm", "DrmGpuPlatformSupportHost::OnGpuProcessLaunched", "host_id", host_id); - host_id_ = host_id; - send_runner_ = std::move(send_runner); - send_callback_ = send_callback; - - for (GpuThreadObserver& observer : gpu_thread_observers_) - observer.OnGpuProcessLaunched(); ui_runner_->PostTask( FROM_HERE, base::BindOnce(&DrmGpuPlatformSupportHost::OnChannelEstablished, - weak_ptr_)); + weak_ptr_, host_id, std::move(send_runner), + std::move(send_callback))); } void DrmGpuPlatformSupportHost::OnChannelDestroyed(int host_id) { TRACE_EVENT1("drm", "DrmGpuPlatformSupportHost::OnChannelDestroyed", "host_id", host_id); - if (host_id_ == host_id) { + { + base::AutoLock auto_lock(host_id_lock_); + host_id_ = -1; + } cursor_->ResetDrmCursorProxy(); - host_id_ = -1; - channel_established_ = false; send_runner_ = nullptr; send_callback_.Reset(); for (GpuThreadObserver& observer : gpu_thread_observers_) @@ -200,9 +197,22 @@ display_manager_ = nullptr; } -void DrmGpuPlatformSupportHost::OnChannelEstablished() { +void DrmGpuPlatformSupportHost::OnChannelEstablished( + int host_id, + scoped_refptr<base::SingleThreadTaskRunner> send_runner, + const base::Callback<void(IPC::Message*)>& send_callback) { + DCHECK(ui_runner_->BelongsToCurrentThread()); TRACE_EVENT0("drm", "DrmGpuPlatformSupportHost::OnChannelEstablished"); - channel_established_ = true; + + send_runner_ = std::move(send_runner); + send_callback_ = send_callback; + { + base::AutoLock auto_lock(host_id_lock_); + host_id_ = host_id; + } + + for (GpuThreadObserver& observer : gpu_thread_observers_) + observer.OnGpuProcessLaunched(); for (GpuThreadObserver& observer : gpu_thread_observers_) observer.OnGpuThreadReady(); @@ -278,22 +288,8 @@ bool DrmGpuPlatformSupportHost::GpuAddGraphicsDevice(const base::FilePath& path, base::ScopedFD fd) { - IPC::Message* message = new OzoneGpuMsg_AddGraphicsDevice( - path, base::FileDescriptor(std::move(fd))); - - // This function may be called from two places: - // - DrmDisplayHostManager::OnGpuProcessLaunched() invoked synchronously - // by GpuProcessHost::Init() on IO thread, which is the same thread as - // |send_runner_|. In this case we can synchronously send the IPC; - // - DrmDisplayHostManager::OnAddGraphicsDevice() on UI thread. In this - // case we need to post the send task to IO thread. - if (send_runner_ && send_runner_->BelongsToCurrentThread()) { - DCHECK(!send_callback_.is_null()); - send_callback_.Run(message); - return true; - } - - return Send(message); + return Send(new OzoneGpuMsg_AddGraphicsDevice( + path, base::FileDescriptor(std::move(fd)))); } bool DrmGpuPlatformSupportHost::GpuRemoveGraphicsDevice(
diff --git a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h index ebcb9d5e..4f0f918 100644 --- a/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h +++ b/ui/ozone/platform/drm/host/drm_gpu_platform_support_host.h
@@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/observer_list.h" #include "base/single_thread_task_runner.h" +#include "base/synchronization/lock.h" #include "ui/display/types/display_constants.h" #include "ui/gfx/native_widget_types.h" #include "ui/ozone/common/gpu/ozone_gpu_message_params.h" @@ -99,7 +100,10 @@ const gfx::Rect& bounds) override; private: - void OnChannelEstablished(); + void OnChannelEstablished( + int host_id, + scoped_refptr<base::SingleThreadTaskRunner> send_runner, + const base::Callback<void(IPC::Message*)>& send_callback); bool OnMessageReceivedForDrmDisplayHostManager(const IPC::Message& message); void OnUpdateNativeDisplays( const std::vector<DisplaySnapshot_Params>& displays); @@ -117,7 +121,7 @@ const std::vector<OverlayCheckReturn_Params>& returns); int host_id_ = -1; - bool channel_established_ = false; + base::Lock host_id_lock_; scoped_refptr<base::SingleThreadTaskRunner> ui_runner_; scoped_refptr<base::SingleThreadTaskRunner> send_runner_;
diff --git a/ui/ozone/platform/drm/host/drm_window_host.cc b/ui/ozone/platform/drm/host/drm_window_host.cc index cb88e95..c3470c2 100644 --- a/ui/ozone/platform/drm/host/drm_window_host.cc +++ b/ui/ozone/platform/drm/host/drm_window_host.cc
@@ -97,6 +97,10 @@ window_manager_->UngrabEvents(widget_); } +bool DrmWindowHost::HasCapture() const { + return widget_ == window_manager_->event_grabber(); +} + void DrmWindowHost::ToggleFullscreen() { }
diff --git a/ui/ozone/platform/drm/host/drm_window_host.h b/ui/ozone/platform/drm/host/drm_window_host.h index 01f0cce..1b17b20 100644 --- a/ui/ozone/platform/drm/host/drm_window_host.h +++ b/ui/ozone/platform/drm/host/drm_window_host.h
@@ -67,6 +67,7 @@ void SetTitle(const base::string16& title) override; void SetCapture() override; void ReleaseCapture() override; + bool HasCapture() const override; void ToggleFullscreen() override; void Maximize() override; void Minimize() override;
diff --git a/ui/ozone/platform/drm/host/gpu_thread_observer.h b/ui/ozone/platform/drm/host/gpu_thread_observer.h index ed6da90b..24b5b19 100644 --- a/ui/ozone/platform/drm/host/gpu_thread_observer.h +++ b/ui/ozone/platform/drm/host/gpu_thread_observer.h
@@ -7,20 +7,19 @@ namespace ui { -// Observes the channel state. +// Observes the channel state. All calls should happen on the same thread that +// OzonePlatform::InitializeForUI() is called on. This can be the browser UI +// thread or the WS thread for mus/mash. class GpuThreadObserver { public: virtual ~GpuThreadObserver() {} // Called when the GPU process is launched. - // This is called from browser IO thread. virtual void OnGpuProcessLaunched() = 0; // Called when a GPU thread implementation has become available. - // This is called from browser UI thread. virtual void OnGpuThreadReady() = 0; // Called when the GPU thread implementation has ceased to be // available. - // This is called from browser UI thread. virtual void OnGpuThreadRetired() = 0; };
diff --git a/ui/ozone/platform/headless/headless_window.cc b/ui/ozone/platform/headless/headless_window.cc index 2c038ad..5bf6e7c9 100644 --- a/ui/ozone/platform/headless/headless_window.cc +++ b/ui/ozone/platform/headless/headless_window.cc
@@ -56,6 +56,10 @@ void HeadlessWindow::ReleaseCapture() {} +bool HeadlessWindow::HasCapture() const { + return false; +} + void HeadlessWindow::ToggleFullscreen() {} void HeadlessWindow::Maximize() {}
diff --git a/ui/ozone/platform/headless/headless_window.h b/ui/ozone/platform/headless/headless_window.h index 4e909cf..2051d14 100644 --- a/ui/ozone/platform/headless/headless_window.h +++ b/ui/ozone/platform/headless/headless_window.h
@@ -32,6 +32,7 @@ void PrepareForShutdown() override; void SetCapture() override; void ReleaseCapture() override; + bool HasCapture() const override; void ToggleFullscreen() override; void Maximize() override; void Minimize() override;
diff --git a/ui/ozone/platform/wayland/wayland_connection.h b/ui/ozone/platform/wayland/wayland_connection.h index e745efd..6372854 100644 --- a/ui/ozone/platform/wayland/wayland_connection.h +++ b/ui/ozone/platform/wayland/wayland_connection.h
@@ -53,6 +53,9 @@ int GetKeyboardModifiers(); + // Returns the current pointer, which may be null. + WaylandPointer* pointer() { return pointer_.get(); } + private: void Flush(); void DispatchUiEvent(Event* event);
diff --git a/ui/ozone/platform/wayland/wayland_pointer.cc b/ui/ozone/platform/wayland/wayland_pointer.cc index 9d6f4ae..8d74daf 100644 --- a/ui/ozone/platform/wayland/wayland_pointer.cc +++ b/ui/ozone/platform/wayland/wayland_pointer.cc
@@ -23,6 +23,12 @@ return flags == original_flags; } +bool HasAnyButtonFlag(int flags) { + return (flags & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON | + EF_RIGHT_MOUSE_BUTTON | EF_BACK_MOUSE_BUTTON | + EF_FORWARD_MOUSE_BUTTON)) != 0; +} + } // namespace WaylandPointer::WaylandPointer(wl_pointer* pointer, @@ -38,7 +44,12 @@ cursor_.reset(new WaylandCursor); } -WaylandPointer::~WaylandPointer() {} +WaylandPointer::~WaylandPointer() { + if (window_with_pointer_focus_) { + window_with_pointer_focus_->set_pointer_focus(false); + window_with_pointer_focus_->set_has_implicit_grab(false); + } +} // static void WaylandPointer::Enter(void* data, @@ -50,8 +61,11 @@ WaylandPointer* pointer = static_cast<WaylandPointer*>(data); pointer->location_.SetPoint(wl_fixed_to_double(surface_x), wl_fixed_to_double(surface_y)); - if (surface) - WaylandWindow::FromSurface(surface)->set_pointer_focus(true); + if (surface) { + WaylandWindow* window = WaylandWindow::FromSurface(surface); + window->set_pointer_focus(true); + pointer->window_with_pointer_focus_ = window; + } } // static @@ -63,8 +77,11 @@ MouseEvent event(ET_MOUSE_EXITED, gfx::Point(), gfx::Point(), EventTimeForNow(), pointer->flags_, 0); pointer->callback_.Run(&event); - if (surface) - WaylandWindow::FromSurface(surface)->set_pointer_focus(false); + if (surface) { + WaylandWindow* window = WaylandWindow::FromSurface(surface); + window->set_pointer_focus(false); + pointer->window_with_pointer_focus_ = nullptr; + } } // static @@ -92,22 +109,22 @@ uint32_t button, uint32_t state) { WaylandPointer* pointer = static_cast<WaylandPointer*>(data); - int flag; + int changed_button; switch (button) { case BTN_LEFT: - flag = EF_LEFT_MOUSE_BUTTON; + changed_button = EF_LEFT_MOUSE_BUTTON; break; case BTN_MIDDLE: - flag = EF_MIDDLE_MOUSE_BUTTON; + changed_button = EF_MIDDLE_MOUSE_BUTTON; break; case BTN_RIGHT: - flag = EF_RIGHT_MOUSE_BUTTON; + changed_button = EF_RIGHT_MOUSE_BUTTON; break; case BTN_BACK: - flag = EF_BACK_MOUSE_BUTTON; + changed_button = EF_BACK_MOUSE_BUTTON; break; case BTN_FORWARD: - flag = EF_FORWARD_MOUSE_BUTTON; + changed_button = EF_FORWARD_MOUSE_BUTTON; break; default: return; @@ -116,17 +133,24 @@ EventType type; if (state == WL_POINTER_BUTTON_STATE_PRESSED) { type = ET_MOUSE_PRESSED; - pointer->flags_ |= flag; + pointer->flags_ |= changed_button; pointer->connection_->set_serial(serial); } else { type = ET_MOUSE_RELEASED; - pointer->flags_ &= ~flag; + pointer->flags_ &= ~changed_button; } - int flags = pointer->GetFlagsWithKeyboardModifiers() | flag; + if (pointer->window_with_pointer_focus_) { + pointer->window_with_pointer_focus_->set_has_implicit_grab( + HasAnyButtonFlag(pointer->flags_)); + } + + // MouseEvent's flags should contain the button that was released too. + const int flags = pointer->GetFlagsWithKeyboardModifiers() | changed_button; MouseEvent event(type, gfx::Point(), gfx::Point(), base::TimeTicks() + base::TimeDelta::FromMilliseconds(time), - flags, flag); + flags, changed_button); + event.set_location_f(pointer->location_); event.set_root_location_f(pointer->location_); pointer->callback_.Run(&event);
diff --git a/ui/ozone/platform/wayland/wayland_pointer.h b/ui/ozone/platform/wayland/wayland_pointer.h index 9550da69..9515dfc 100644 --- a/ui/ozone/platform/wayland/wayland_pointer.h +++ b/ui/ozone/platform/wayland/wayland_pointer.h
@@ -5,6 +5,7 @@ #ifndef UI_OZONE_PLATFORM_WAYLAND_WAYLAND_POINTER_H_ #define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_POINTER_H_ +#include "base/macros.h" #include "ui/events/ozone/evdev/event_dispatch_callback.h" #include "ui/gfx/geometry/point_f.h" #include "ui/ozone/platform/wayland/wayland_cursor.h" @@ -12,6 +13,8 @@ namespace ui { +class WaylandWindow; + class WaylandPointer { public: WaylandPointer(wl_pointer* pointer, const EventDispatchCallback& callback); @@ -26,6 +29,10 @@ WaylandCursor* cursor() { return cursor_.get(); } + void reset_window_with_pointer_focus() { + window_with_pointer_focus_ = nullptr; + } + private: // wl_pointer_listener static void Enter(void* data, @@ -60,11 +67,18 @@ wl::Object<wl_pointer> obj_; EventDispatchCallback callback_; gfx::PointF location_; + // Flags is a bitmask of EventFlags corresponding to the pointer/keyboard + // state. int flags_ = 0; // Keeps track of current modifiers. These are needed in order to properly // update |flags_| with newest modifiers. int keyboard_modifiers_ = 0; + + // The window the mouse is over. + WaylandWindow* window_with_pointer_focus_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(WaylandPointer); }; } // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_pointer_unittest.cc b/ui/ozone/platform/wayland/wayland_pointer_unittest.cc index 8675f4d..bc86a49 100644 --- a/ui/ozone/platform/wayland/wayland_pointer_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_pointer_unittest.cc
@@ -122,27 +122,42 @@ TEST_P(WaylandPointerTest, ButtonPress) { wl_pointer_send_enter(pointer_->resource(), 1, surface_->resource(), wl_fixed_from_int(200), wl_fixed_from_int(150)); - wl_pointer_send_button(pointer_->resource(), 2, 1002, BTN_RIGHT, - WL_POINTER_BUTTON_STATE_PRESSED); - Sync(); - std::unique_ptr<Event> event; - EXPECT_CALL(delegate_, DispatchEvent(_)).WillOnce(CloneEvent(&event)); + wl_pointer_send_button(pointer_->resource(), 2, 1002, BTN_RIGHT, + WL_POINTER_BUTTON_STATE_PRESSED); + std::unique_ptr<Event> right_press_event; + EXPECT_CALL(delegate_, DispatchEvent(_)) + .WillOnce(CloneEvent(&right_press_event)); + Sync(); + ASSERT_TRUE(right_press_event); + ASSERT_TRUE(right_press_event->IsMouseEvent()); + auto* right_press_mouse_event = right_press_event->AsMouseEvent(); + EXPECT_EQ(ET_MOUSE_PRESSED, right_press_mouse_event->type()); + EXPECT_EQ(EF_RIGHT_MOUSE_BUTTON, right_press_mouse_event->button_flags()); + EXPECT_EQ(EF_RIGHT_MOUSE_BUTTON, + right_press_mouse_event->changed_button_flags()); + + std::unique_ptr<Event> left_press_event; + EXPECT_CALL(delegate_, DispatchEvent(_)) + .WillOnce(CloneEvent(&left_press_event)); wl_pointer_send_button(pointer_->resource(), 3, 1003, BTN_LEFT, WL_POINTER_BUTTON_STATE_PRESSED); Sync(); - ASSERT_TRUE(event); - ASSERT_TRUE(event->IsMouseEvent()); - auto* mouse_event = event->AsMouseEvent(); - EXPECT_EQ(ET_MOUSE_PRESSED, mouse_event->type()); + ASSERT_TRUE(left_press_event); + ASSERT_TRUE(left_press_event->IsMouseEvent()); + auto* left_press_mouse_event = left_press_event->AsMouseEvent(); + EXPECT_EQ(ET_MOUSE_PRESSED, left_press_mouse_event->type()); EXPECT_EQ(EF_LEFT_MOUSE_BUTTON | EF_RIGHT_MOUSE_BUTTON, - mouse_event->button_flags()); - EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, mouse_event->changed_button_flags()); - EXPECT_EQ(gfx::PointF(200, 150), mouse_event->location_f()); - EXPECT_EQ(gfx::PointF(200, 150), mouse_event->root_location_f()); + left_press_mouse_event->button_flags()); + EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, + left_press_mouse_event->changed_button_flags()); + EXPECT_EQ(EF_LEFT_MOUSE_BUTTON, + left_press_mouse_event->changed_button_flags()); + EXPECT_EQ(gfx::PointF(200, 150), left_press_mouse_event->location_f()); + EXPECT_EQ(gfx::PointF(200, 150), left_press_mouse_event->root_location_f()); } TEST_P(WaylandPointerTest, ButtonRelease) {
diff --git a/ui/ozone/platform/wayland/wayland_window.cc b/ui/ozone/platform/wayland/wayland_window.cc index 196ad28..e5b7cd4 100644 --- a/ui/ozone/platform/wayland/wayland_window.cc +++ b/ui/ozone/platform/wayland/wayland_window.cc
@@ -12,6 +12,7 @@ #include "ui/events/event.h" #include "ui/events/ozone/events_ozone.h" #include "ui/ozone/platform/wayland/wayland_connection.h" +#include "ui/ozone/platform/wayland/wayland_pointer.h" #include "ui/ozone/platform/wayland/xdg_surface_wrapper_v5.h" #include "ui/ozone/platform/wayland/xdg_surface_wrapper_v6.h" @@ -55,6 +56,8 @@ PlatformEventSource::GetInstance()->RemovePlatformEventDispatcher(this); connection_->RemoveWindow(surface_.id()); } + if (has_pointer_focus_) + connection_->pointer()->reset_window_with_pointer_focus(); } // static @@ -134,13 +137,21 @@ } void WaylandWindow::SetCapture() { + // Wayland does implicit grabs, and doesn't allow for explicit grabs. The + // exception to that seems to be popups, which can do a grab during show. Need + // to evaluate under what circumstances we need this. NOTIMPLEMENTED(); } void WaylandWindow::ReleaseCapture() { + // See comment in SetCapture() for details on wayland and grabs. NOTIMPLEMENTED(); } +bool WaylandWindow::HasCapture() const { + return has_implicit_grab_; +} + void WaylandWindow::ToggleFullscreen() { DCHECK(xdg_surface_); @@ -267,14 +278,21 @@ else state_ = PlatformWindowState::PLATFORM_WINDOW_STATE_NORMAL; - if (old_state != state_) - delegate_->OnWindowStateChanged(state_); + // Update state before notifying delegate. + const bool did_active_change = is_active_ != is_activated; + is_active_ = is_activated; // Rather than call SetBounds here for every configure event, just save the // most recent bounds, and have WaylandConnection call ApplyPendingBounds // when it has finished processing events. We may get many configure events // in a row during an interactive resize, and only the last one matters. SetPendingBounds(width, height); + + if (old_state != state_) + delegate_->OnWindowStateChanged(state_); + + if (did_active_change) + delegate_->OnActivationChanged(is_active_); } void WaylandWindow::OnCloseRequest() {
diff --git a/ui/ozone/platform/wayland/wayland_window.h b/ui/ozone/platform/wayland/wayland_window.h index 8d205fa4..b534566e 100644 --- a/ui/ozone/platform/wayland/wayland_window.h +++ b/ui/ozone/platform/wayland/wayland_window.h
@@ -43,6 +43,7 @@ // Set whether this window has pointer focus and should dispatch mouse events. void set_pointer_focus(bool focus) { has_pointer_focus_ = focus; } + bool has_pointer_focus() const { return has_pointer_focus_; } // Set whether this window has keyboard focus and should dispatch key events. void set_keyboard_focus(bool focus) { has_keyboard_focus_ = focus; } @@ -50,6 +51,13 @@ // Set whether this window has touch focus and should dispatch touch events. void set_touch_focus(bool focus) { has_touch_focus_ = focus; } + // Set whether this window has an implicit grab (often referred to as capture + // in Chrome code). Implicit grabs happen while a pointer is down. + void set_has_implicit_grab(bool value) { has_implicit_grab_ = value; } + bool has_implicit_grab() const { return has_implicit_grab_; } + + bool is_active() const { return is_active_; } + // PlatformWindow void Show() override; void Hide() override; @@ -60,6 +68,7 @@ void SetTitle(const base::string16& title) override; void SetCapture() override; void ReleaseCapture() override; + bool HasCapture() const override; void ToggleFullscreen() override; void Maximize() override; void Minimize() override; @@ -113,10 +122,13 @@ bool has_pointer_focus_ = false; bool has_keyboard_focus_ = false; bool has_touch_focus_ = false; + bool has_implicit_grab_ = false; // Stores current states of the window. ui::PlatformWindowState state_; + bool is_active_ = false; + DISALLOW_COPY_AND_ASSIGN(WaylandWindow); };
diff --git a/ui/ozone/platform/wayland/wayland_window_unittest.cc b/ui/ozone/platform/wayland/wayland_window_unittest.cc index 5cfa7b5..476272b 100644 --- a/ui/ozone/platform/wayland/wayland_window_unittest.cc +++ b/ui/ozone/platform/wayland/wayland_window_unittest.cc
@@ -323,13 +323,18 @@ } TEST_P(WaylandWindowTest, CanDispatchMouseEventFocus) { + // set_pointer_focus(true) requires a WaylandPointer. + wl_seat_send_capabilities(server_.seat()->resource(), + WL_SEAT_CAPABILITY_POINTER); + Sync(); + ASSERT_TRUE(connection_->pointer()); window_->set_pointer_focus(true); EXPECT_TRUE(window_->CanDispatchEvent(&test_mouse_event_)); } TEST_P(WaylandWindowTest, CanDispatchMouseEventUnfocus) { - window_->set_pointer_focus(true); - EXPECT_TRUE(window_->CanDispatchEvent(&test_mouse_event_)); + EXPECT_FALSE(window_->has_pointer_focus()); + EXPECT_FALSE(window_->CanDispatchEvent(&test_mouse_event_)); } ACTION_P(CloneEvent, ptr) { @@ -352,6 +357,35 @@ test_mouse_event_.changed_button_flags()); } +TEST_P(WaylandWindowTest, HasCaptureUpdatedOnPointerEvents) { + wl_seat_send_capabilities(server_.seat()->resource(), + WL_SEAT_CAPABILITY_POINTER); + + Sync(); + + wl::MockPointer* pointer = server_.seat()->pointer_.get(); + ASSERT_TRUE(pointer); + + wl_pointer_send_enter(pointer->resource(), 1, surface_->resource(), 0, 0); + Sync(); + EXPECT_FALSE(window_->HasCapture()); + + wl_pointer_send_button(pointer->resource(), 2, 1002, BTN_LEFT, + WL_POINTER_BUTTON_STATE_PRESSED); + Sync(); + EXPECT_TRUE(window_->HasCapture()); + + wl_pointer_send_motion(pointer->resource(), 1003, wl_fixed_from_int(400), + wl_fixed_from_int(500)); + Sync(); + EXPECT_TRUE(window_->HasCapture()); + + wl_pointer_send_button(pointer->resource(), 4, 1004, BTN_LEFT, + WL_POINTER_BUTTON_STATE_RELEASED); + Sync(); + EXPECT_FALSE(window_->HasCapture()); +} + TEST_P(WaylandWindowTest, ConfigureEvent) { wl_array states; wl_array_init(&states); @@ -385,6 +419,26 @@ EXPECT_CALL(*xdg_surface_, AckConfigure(14)); } +TEST_P(WaylandWindowTest, OnActivationChanged) { + EXPECT_FALSE(window_->is_active()); + + { + wl_array states; + InitializeWlArrayWithActivatedState(&states); + EXPECT_CALL(delegate_, OnActivationChanged(Eq(true))); + SendConfigureEvent(0, 0, 1, &states); + Sync(); + EXPECT_TRUE(window_->is_active()); + } + + wl_array states; + wl_array_init(&states); + EXPECT_CALL(delegate_, OnActivationChanged(Eq(false))); + SendConfigureEvent(0, 0, 2, &states); + Sync(); + EXPECT_FALSE(window_->is_active()); +} + INSTANTIATE_TEST_CASE_P(XdgVersionV5Test, WaylandWindowTest, ::testing::Values(kXdgShellV5));
diff --git a/ui/ozone/public/ozone_platform.cc b/ui/ozone/public/ozone_platform.cc index 58c114b..2457d0b 100644 --- a/ui/ozone/public/ozone_platform.cc +++ b/ui/ozone/public/ozone_platform.cc
@@ -42,8 +42,11 @@ EnsureInstance(); if (g_platform_initialized_ui) return; - g_platform_initialized_ui = true; instance_->InitializeUI(args); + { + base::AutoLock lock(GetOzoneInstanceLock()); + g_platform_initialized_ui = true; + } // This is deliberately created after initializing so that the platform can // create its own version of DDM. DeviceDataManager::CreateInstance(); @@ -56,8 +59,11 @@ EnsureInstance(); if (g_platform_initialized_gpu) return; - g_platform_initialized_gpu = true; instance_->InitializeGPU(args); + { + base::AutoLock lock(GetOzoneInstanceLock()); + g_platform_initialized_gpu = true; + } if (!args.single_process && !instance_callback.Get().is_null()) std::move(instance_callback.Get()).Run(instance_); }
diff --git a/ui/platform_window/android/platform_window_android.cc b/ui/platform_window/android/platform_window_android.cc index c32b24a3..ed53df5 100644 --- a/ui/platform_window/android/platform_window_android.cc +++ b/ui/platform_window/android/platform_window_android.cc
@@ -196,6 +196,11 @@ NOTIMPLEMENTED(); } +bool PlatformWindowAndroid::HasCapture() const { + NOTIMPLEMENTED(); + return false; +} + void PlatformWindowAndroid::ToggleFullscreen() { NOTIMPLEMENTED(); }
diff --git a/ui/platform_window/android/platform_window_android.h b/ui/platform_window/android/platform_window_android.h index 599ff718..803ab18 100644 --- a/ui/platform_window/android/platform_window_android.h +++ b/ui/platform_window/android/platform_window_android.h
@@ -71,6 +71,7 @@ void SetTitle(const base::string16& title) override; void SetCapture() override; void ReleaseCapture() override; + bool HasCapture() const override; void ToggleFullscreen() override; void Maximize() override; void Minimize() override;
diff --git a/ui/platform_window/platform_window.h b/ui/platform_window/platform_window.h index 87a8b1d..1af46942 100644 --- a/ui/platform_window/platform_window.h +++ b/ui/platform_window/platform_window.h
@@ -45,6 +45,7 @@ virtual void SetCapture() = 0; virtual void ReleaseCapture() = 0; + virtual bool HasCapture() const = 0; virtual void ToggleFullscreen() = 0; virtual void Maximize() = 0;
diff --git a/ui/platform_window/stub/stub_window.cc b/ui/platform_window/stub/stub_window.cc index e646ca4..d5fc54c 100644 --- a/ui/platform_window/stub/stub_window.cc +++ b/ui/platform_window/stub/stub_window.cc
@@ -53,6 +53,10 @@ void StubWindow::ReleaseCapture() { } +bool StubWindow::HasCapture() const { + return false; +} + void StubWindow::ToggleFullscreen() { }
diff --git a/ui/platform_window/stub/stub_window.h b/ui/platform_window/stub/stub_window.h index fa01974c..c94a847 100644 --- a/ui/platform_window/stub/stub_window.h +++ b/ui/platform_window/stub/stub_window.h
@@ -37,6 +37,7 @@ void SetCapture() override; void ReleaseCapture() override; void ToggleFullscreen() override; + bool HasCapture() const override; void Maximize() override; void Minimize() override; void Restore() override;
diff --git a/ui/platform_window/win/win_window.cc b/ui/platform_window/win/win_window.cc index 2f32390a..39fd290b 100644 --- a/ui/platform_window/win/win_window.cc +++ b/ui/platform_window/win/win_window.cc
@@ -101,15 +101,19 @@ } void WinWindow::SetCapture() { - if (::GetCapture() != hwnd()) + if (!HasCapture()) ::SetCapture(hwnd()); } void WinWindow::ReleaseCapture() { - if (::GetCapture() == hwnd()) + if (HasCapture()) ::ReleaseCapture(); } +bool WinWindow::HasCapture() const { + return ::GetCapture() == hwnd(); +} + void WinWindow::ToggleFullscreen() {} void WinWindow::Maximize() {}
diff --git a/ui/platform_window/win/win_window.h b/ui/platform_window/win/win_window.h index c6774fd..c2f7c224 100644 --- a/ui/platform_window/win/win_window.h +++ b/ui/platform_window/win/win_window.h
@@ -36,6 +36,7 @@ void SetTitle(const base::string16& title) override; void SetCapture() override; void ReleaseCapture() override; + bool HasCapture() const override; void ToggleFullscreen() override; void Maximize() override; void Minimize() override;
diff --git a/ui/platform_window/x11/x11_window_base.cc b/ui/platform_window/x11/x11_window_base.cc index 75cc3eef..b6c4214e 100644 --- a/ui/platform_window/x11/x11_window_base.cc +++ b/ui/platform_window/x11/x11_window_base.cc
@@ -224,6 +224,10 @@ void X11WindowBase::ReleaseCapture() {} +bool X11WindowBase::HasCapture() const { + return false; +} + void X11WindowBase::ToggleFullscreen() { ui::SetWMSpecState(xwindow_, !IsFullscreen(), gfx::GetAtom("_NET_WM_STATE_FULLSCREEN"), x11::None);
diff --git a/ui/platform_window/x11/x11_window_base.h b/ui/platform_window/x11/x11_window_base.h index b419dc19..1a062b9 100644 --- a/ui/platform_window/x11/x11_window_base.h +++ b/ui/platform_window/x11/x11_window_base.h
@@ -39,6 +39,7 @@ void SetTitle(const base::string16& title) override; void SetCapture() override; void ReleaseCapture() override; + bool HasCapture() const override; void ToggleFullscreen() override; void Maximize() override; void Minimize() override;
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index 8edb409..2dcfa7fd5 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -1217,6 +1217,6 @@ data_deps = [ "//ui/resources:ui_test_pak_data", - "//testing:run_gtest_perf_test", + "//testing:run_perf_test", ] }
diff --git a/ui/views/controls/scroll_view_unittest.cc b/ui/views/controls/scroll_view_unittest.cc index d57fbb05..16ec528c8 100644 --- a/ui/views/controls/scroll_view_unittest.cc +++ b/ui/views/controls/scroll_view_unittest.cc
@@ -134,12 +134,12 @@ DISALLOW_COPY_AND_ASSIGN(CustomView); }; -void CheckScrollbarVisibility(const ScrollView& scroll_view, +void CheckScrollbarVisibility(const ScrollView* scroll_view, ScrollBarOrientation orientation, bool should_be_visible) { const ScrollBar* scrollbar = orientation == HORIZONTAL - ? scroll_view.horizontal_scroll_bar() - : scroll_view.vertical_scroll_bar(); + ? scroll_view->horizontal_scroll_bar() + : scroll_view->vertical_scroll_bar(); if (should_be_visible) { ASSERT_TRUE(scrollbar); EXPECT_TRUE(scrollbar->visible()); @@ -179,11 +179,16 @@ public: ScrollViewTest() {} + void SetUp() override { + ViewsTestBase::SetUp(); + scroll_view_ = std::make_unique<ScrollView>(); + } + View* InstallContents() { const gfx::Rect default_outer_bounds(0, 0, 100, 100); View* contents = new View; - scroll_view_.SetContents(contents); - scroll_view_.SetBoundsRect(default_outer_bounds); + scroll_view_->SetContents(contents); + scroll_view_->SetBoundsRect(default_outer_bounds); return contents; } @@ -208,14 +213,14 @@ protected: #endif int VerticalScrollBarWidth() { - return scroll_view_.vertical_scroll_bar()->GetThickness(); + return scroll_view_->vertical_scroll_bar()->GetThickness(); } int HorizontalScrollBarHeight() { - return scroll_view_.horizontal_scroll_bar()->GetThickness(); + return scroll_view_->horizontal_scroll_bar()->GetThickness(); } - ScrollView scroll_view_; + std::unique_ptr<ScrollView> scroll_view_; private: DISALLOW_COPY_AND_ASSIGN(ScrollViewTest); @@ -332,7 +337,7 @@ // Verifies the viewport is sized to fit the available space. TEST_F(ScrollViewTest, ViewportSizedToFit) { View* contents = InstallContents(); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ("0,0 100x100", contents->parent()->bounds().ToString()); } @@ -340,9 +345,9 @@ // bounded scroll view. TEST_F(ScrollViewTest, BoundedViewportSizedToFit) { View* contents = InstallContents(); - scroll_view_.ClipHeightTo(100, 200); - scroll_view_.SetBorder(CreateSolidBorder(2, 0)); - scroll_view_.Layout(); + scroll_view_->ClipHeightTo(100, 200); + scroll_view_->SetBorder(CreateSolidBorder(2, 0)); + scroll_view_->Layout(); EXPECT_EQ("2,2 96x96", contents->parent()->bounds().ToString()); // Make sure the width of |contents| is set properly not to overflow the @@ -355,11 +360,11 @@ TEST_F(ScrollViewTest, VerticalScrollbarDoesNotAppearUnnecessarily) { const gfx::Rect default_outer_bounds(0, 0, 100, 100); View* contents = new VerticalResizingView; - scroll_view_.SetContents(contents); - scroll_view_.SetBoundsRect(default_outer_bounds); - scroll_view_.Layout(); - EXPECT_FALSE(scroll_view_.vertical_scroll_bar()->visible()); - EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); + scroll_view_->SetContents(contents); + scroll_view_->SetBoundsRect(default_outer_bounds); + scroll_view_->Layout(); + EXPECT_FALSE(scroll_view_->vertical_scroll_bar()->visible()); + EXPECT_TRUE(scroll_view_->horizontal_scroll_bar()->visible()); } // Verifies the scrollbars are added as necessary. @@ -369,54 +374,54 @@ // Size the contents such that vertical scrollbar is needed. contents->SetBounds(0, 0, 50, 400); - scroll_view_.Layout(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + scroll_view_->Layout(); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, false); - EXPECT_TRUE(!scroll_view_.horizontal_scroll_bar() || - !scroll_view_.horizontal_scroll_bar()->visible()); - ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, false); + EXPECT_TRUE(!scroll_view_->horizontal_scroll_bar() || + !scroll_view_->horizontal_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->vertical_scroll_bar()->visible()); // Size the contents such that horizontal scrollbar is needed. contents->SetBounds(0, 0, 400, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(100, contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), contents->parent()->height()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, false); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, false); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); // Both horizontal and vertical. contents->SetBounds(0, 0, 300, 400); - scroll_view_.Layout(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + scroll_view_->Layout(); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), contents->parent()->height()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); // Add a border, test vertical scrollbar. const int kTopPadding = 1; const int kLeftPadding = 2; const int kBottomPadding = 3; const int kRightPadding = 4; - scroll_view_.SetBorder(CreateEmptyBorder(kTopPadding, kLeftPadding, - kBottomPadding, kRightPadding)); + scroll_view_->SetBorder(CreateEmptyBorder(kTopPadding, kLeftPadding, + kBottomPadding, kRightPadding)); contents->SetBounds(0, 0, 50, 400); - scroll_view_.Layout(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth() - kLeftPadding - + scroll_view_->Layout(); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth() - kLeftPadding - kRightPadding, contents->parent()->width()); EXPECT_EQ(100 - kTopPadding - kBottomPadding, contents->parent()->height()); - EXPECT_TRUE(!scroll_view_.horizontal_scroll_bar() || - !scroll_view_.horizontal_scroll_bar()->visible()); - ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); - gfx::Rect bounds = scroll_view_.vertical_scroll_bar()->bounds(); + EXPECT_TRUE(!scroll_view_->horizontal_scroll_bar() || + !scroll_view_->horizontal_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->vertical_scroll_bar()->visible()); + gfx::Rect bounds = scroll_view_->vertical_scroll_bar()->bounds(); EXPECT_EQ(100 - VerticalScrollBarWidth() - kRightPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding, bounds.right()); EXPECT_EQ(kTopPadding, bounds.y()); @@ -424,16 +429,16 @@ // Horizontal with border. contents->SetBounds(0, 0, 400, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(100 - kLeftPadding - kRightPadding, contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - kTopPadding - + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight() - kTopPadding - kBottomPadding, contents->parent()->height()); - ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); - EXPECT_TRUE(!scroll_view_.vertical_scroll_bar() || - !scroll_view_.vertical_scroll_bar()->visible()); - bounds = scroll_view_.horizontal_scroll_bar()->bounds(); + ASSERT_TRUE(scroll_view_->horizontal_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->horizontal_scroll_bar()->visible()); + EXPECT_TRUE(!scroll_view_->vertical_scroll_bar() || + !scroll_view_->vertical_scroll_bar()->visible()); + bounds = scroll_view_->horizontal_scroll_bar()->bounds(); EXPECT_EQ(kLeftPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding, bounds.right()); EXPECT_EQ(100 - kBottomPadding - HorizontalScrollBarHeight(), bounds.y()); @@ -441,26 +446,26 @@ // Both horizontal and vertical with border. contents->SetBounds(0, 0, 300, 400); - scroll_view_.Layout(); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth() - kLeftPadding - + scroll_view_->Layout(); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth() - kLeftPadding - kRightPadding, contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - kTopPadding - + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight() - kTopPadding - kBottomPadding, contents->parent()->height()); - bounds = scroll_view_.horizontal_scroll_bar()->bounds(); + bounds = scroll_view_->horizontal_scroll_bar()->bounds(); // Check horiz. - ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); - bounds = scroll_view_.horizontal_scroll_bar()->bounds(); + ASSERT_TRUE(scroll_view_->horizontal_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->horizontal_scroll_bar()->visible()); + bounds = scroll_view_->horizontal_scroll_bar()->bounds(); EXPECT_EQ(kLeftPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding - VerticalScrollBarWidth(), bounds.right()); EXPECT_EQ(100 - kBottomPadding - HorizontalScrollBarHeight(), bounds.y()); EXPECT_EQ(100 - kBottomPadding, bounds.bottom()); // Check vert. - ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); - bounds = scroll_view_.vertical_scroll_bar()->bounds(); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->vertical_scroll_bar()->visible()); + bounds = scroll_view_->vertical_scroll_bar()->bounds(); EXPECT_EQ(100 - VerticalScrollBarWidth() - kRightPadding, bounds.x()); EXPECT_EQ(100 - kRightPadding, bounds.right()); EXPECT_EQ(kTopPadding, bounds.y()); @@ -471,11 +476,11 @@ // Assertions around adding a header. TEST_F(ScrollViewTest, Header) { CustomView* header = new CustomView; - scroll_view_.SetHeader(header); + scroll_view_->SetHeader(header); View* header_parent = header->parent(); View* contents = InstallContents(); - scroll_view_.Layout(); + scroll_view_->Layout(); // |header|s preferred size is empty, which should result in all space going // to contents. EXPECT_EQ("0,0 100x0", header->parent()->bounds().ToString()); @@ -502,7 +507,7 @@ EXPECT_EQ("0,0 0x0", contents->bounds().ToString()); // Remove the header. - scroll_view_.SetHeader(NULL); + scroll_view_->SetHeader(NULL); // SetHeader(NULL) deletes header. header = NULL; EXPECT_EQ("0,0 100x0", header_parent->bounds().ToString()); @@ -512,111 +517,111 @@ // Verifies the scrollbars are added as necessary when a header is present. TEST_F(ScrollViewTest, ScrollBarsWithHeader) { CustomView* header = new CustomView; - scroll_view_.SetHeader(header); + scroll_view_->SetHeader(header); View* contents = InstallContents(); header->SetPreferredSize(gfx::Size(10, 20)); // Size the contents such that vertical scrollbar is needed. contents->SetBounds(0, 0, 50, 400); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(0, contents->parent()->x()); EXPECT_EQ(20, contents->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), contents->parent()->width()); EXPECT_EQ(80, contents->parent()->height()); EXPECT_EQ(0, header->parent()->x()); EXPECT_EQ(0, header->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), header->parent()->width()); EXPECT_EQ(20, header->parent()->height()); - EXPECT_TRUE(!scroll_view_.horizontal_scroll_bar() || - !scroll_view_.horizontal_scroll_bar()->visible()); - ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); + EXPECT_TRUE(!scroll_view_->horizontal_scroll_bar() || + !scroll_view_->horizontal_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->vertical_scroll_bar()->visible()); // Make sure the vertical scrollbar overlaps the header for traditional // scrollbars and doesn't overlap the header for overlay scrollbars. const int expected_scrollbar_y = - scroll_view_.vertical_scroll_bar()->OverlapsContent() + scroll_view_->vertical_scroll_bar()->OverlapsContent() ? header->bounds().bottom() : header->y(); - EXPECT_EQ(expected_scrollbar_y, scroll_view_.vertical_scroll_bar()->y()); + EXPECT_EQ(expected_scrollbar_y, scroll_view_->vertical_scroll_bar()->y()); EXPECT_EQ(header->y(), contents->y()); // Size the contents such that horizontal scrollbar is needed. contents->SetBounds(0, 0, 400, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(0, contents->parent()->x()); EXPECT_EQ(20, contents->parent()->y()); EXPECT_EQ(100, contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - 20, + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight() - 20, contents->parent()->height()); EXPECT_EQ(0, header->parent()->x()); EXPECT_EQ(0, header->parent()->y()); EXPECT_EQ(100, header->parent()->width()); EXPECT_EQ(20, header->parent()->height()); - ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); - EXPECT_TRUE(!scroll_view_.vertical_scroll_bar() || - !scroll_view_.vertical_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->horizontal_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->horizontal_scroll_bar()->visible()); + EXPECT_TRUE(!scroll_view_->vertical_scroll_bar() || + !scroll_view_->vertical_scroll_bar()->visible()); // Both horizontal and vertical. contents->SetBounds(0, 0, 300, 400); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(0, contents->parent()->x()); EXPECT_EQ(20, contents->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), contents->parent()->width()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight() - 20, + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight() - 20, contents->parent()->height()); EXPECT_EQ(0, header->parent()->x()); EXPECT_EQ(0, header->parent()->y()); - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutWidth(), + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutWidth(), header->parent()->width()); EXPECT_EQ(20, header->parent()->height()); - ASSERT_TRUE(scroll_view_.horizontal_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.horizontal_scroll_bar()->visible()); - ASSERT_TRUE(scroll_view_.vertical_scroll_bar() != NULL); - EXPECT_TRUE(scroll_view_.vertical_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->horizontal_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->horizontal_scroll_bar()->visible()); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar() != NULL); + EXPECT_TRUE(scroll_view_->vertical_scroll_bar()->visible()); } // Verifies the header scrolls horizontally with the content. TEST_F(ScrollViewTest, HeaderScrollsWithContent) { - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); CustomView* contents = new CustomView; - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); contents->SetPreferredSize(gfx::Size(500, 500)); CustomView* header = new CustomView; - scroll_view_.SetHeader(header); + scroll_view_->SetHeader(header); header->SetPreferredSize(gfx::Size(500, 20)); - scroll_view_.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); + scroll_view_->SetBoundsRect(gfx::Rect(0, 0, 100, 100)); EXPECT_EQ("0,0", test_api.IntegralViewOffset().ToString()); EXPECT_EQ("0,0", header->origin().ToString()); // Scroll the horizontal scrollbar. - ASSERT_TRUE(scroll_view_.horizontal_scroll_bar()); - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), 1); + ASSERT_TRUE(scroll_view_->horizontal_scroll_bar()); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), 1); EXPECT_EQ("-1,0", test_api.IntegralViewOffset().ToString()); EXPECT_EQ("-1,0", header->origin().ToString()); // Scrolling the vertical scrollbar shouldn't effect the header. - ASSERT_TRUE(scroll_view_.vertical_scroll_bar()); - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), 1); + ASSERT_TRUE(scroll_view_->vertical_scroll_bar()); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), 1); EXPECT_EQ("-1,-1", test_api.IntegralViewOffset().ToString()); EXPECT_EQ("-1,0", header->origin().ToString()); } // Verifies ScrollRectToVisible() on the child works. TEST_F(ScrollViewTest, ScrollRectToVisible) { - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); CustomView* contents = new CustomView; - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); contents->SetPreferredSize(gfx::Size(500, 1000)); - scroll_view_.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); - scroll_view_.Layout(); + scroll_view_->SetBoundsRect(gfx::Rect(0, 0, 100, 100)); + scroll_view_->Layout(); EXPECT_EQ("0,0", test_api.IntegralViewOffset().ToString()); // Scroll to y=405 height=10, this should make the y position of the content @@ -625,7 +630,7 @@ const int viewport_height = test_api.contents_viewport()->height(); // Expect there to be a horizontal scrollbar, making the viewport shorter. - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), viewport_height); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), viewport_height); gfx::ScrollOffset offset = test_api.CurrentOffset(); EXPECT_EQ(415 - viewport_height, offset.y()); @@ -637,17 +642,17 @@ // Verifies that child scrolls into view when it's focused. TEST_F(ScrollViewTest, ScrollChildToVisibleOnFocus) { - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); CustomView* contents = new CustomView; - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); contents->SetPreferredSize(gfx::Size(500, 1000)); FixedView* child = new FixedView; child->SetPreferredSize(gfx::Size(10, 10)); child->SetPosition(gfx::Point(0, 405)); contents->AddChildView(child); - scroll_view_.SetBoundsRect(gfx::Rect(0, 0, 100, 100)); - scroll_view_.Layout(); + scroll_view_->SetBoundsRect(gfx::Rect(0, 0, 100, 100)); + scroll_view_->Layout(); EXPECT_EQ(gfx::Point(), test_api.IntegralViewOffset()); // Set focus to the child control. This should cause the control to scroll to @@ -657,7 +662,7 @@ const int viewport_height = test_api.contents_viewport()->height(); // Expect there to be a horizontal scrollbar, making the viewport shorter. - EXPECT_EQ(100 - scroll_view_.GetScrollBarLayoutHeight(), viewport_height); + EXPECT_EQ(100 - scroll_view_->GetScrollBarLayoutHeight(), viewport_height); gfx::ScrollOffset offset = test_api.CurrentOffset(); EXPECT_EQ(415 - viewport_height, offset.y()); @@ -666,138 +671,138 @@ // Verifies ClipHeightTo() uses the height of the content when it is between the // minimum and maximum height values. TEST_F(ScrollViewTest, ClipHeightToNormalContentHeight) { - scroll_view_.ClipHeightTo(kMinHeight, kMaxHeight); + scroll_view_->ClipHeightTo(kMinHeight, kMaxHeight); const int kNormalContentHeight = 75; - scroll_view_.SetContents( + scroll_view_->SetContents( new views::StaticSizedView(gfx::Size(kWidth, kNormalContentHeight))); EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight), - scroll_view_.GetPreferredSize()); + scroll_view_->GetPreferredSize()); - scroll_view_.SizeToPreferredSize(); - scroll_view_.Layout(); + scroll_view_->SizeToPreferredSize(); + scroll_view_->Layout(); EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight), - scroll_view_.contents()->size()); - EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight), scroll_view_.size()); + scroll_view_->contents()->size()); + EXPECT_EQ(gfx::Size(kWidth, kNormalContentHeight), scroll_view_->size()); } // Verifies ClipHeightTo() uses the minimum height when the content is shorter // than the minimum height value. TEST_F(ScrollViewTest, ClipHeightToShortContentHeight) { - scroll_view_.ClipHeightTo(kMinHeight, kMaxHeight); + scroll_view_->ClipHeightTo(kMinHeight, kMaxHeight); const int kShortContentHeight = 10; View* contents = new views::StaticSizedView(gfx::Size(kWidth, kShortContentHeight)); - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); - EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_.GetPreferredSize()); + EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_->GetPreferredSize()); - scroll_view_.SizeToPreferredSize(); - scroll_view_.Layout(); + scroll_view_->SizeToPreferredSize(); + scroll_view_->Layout(); // Layered scrolling requires the contents to fill the viewport. if (contents->layer()) { - EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_.contents()->size()); + EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_->contents()->size()); } else { EXPECT_EQ(gfx::Size(kWidth, kShortContentHeight), - scroll_view_.contents()->size()); + scroll_view_->contents()->size()); } - EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_.size()); + EXPECT_EQ(gfx::Size(kWidth, kMinHeight), scroll_view_->size()); } // Verifies ClipHeightTo() uses the maximum height when the content is longer // thamn the maximum height value. TEST_F(ScrollViewTest, ClipHeightToTallContentHeight) { - scroll_view_.ClipHeightTo(kMinHeight, kMaxHeight); + scroll_view_->ClipHeightTo(kMinHeight, kMaxHeight); const int kTallContentHeight = 1000; - scroll_view_.SetContents( + scroll_view_->SetContents( new views::StaticSizedView(gfx::Size(kWidth, kTallContentHeight))); - EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_.GetPreferredSize()); + EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_->GetPreferredSize()); - scroll_view_.SizeToPreferredSize(); - scroll_view_.Layout(); + scroll_view_->SizeToPreferredSize(); + scroll_view_->Layout(); // The width may be less than kWidth if the scroll bar takes up some width. - EXPECT_GE(kWidth, scroll_view_.contents()->width()); - EXPECT_EQ(kTallContentHeight, scroll_view_.contents()->height()); - EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_.size()); + EXPECT_GE(kWidth, scroll_view_->contents()->width()); + EXPECT_EQ(kTallContentHeight, scroll_view_->contents()->height()); + EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_->size()); } // Verifies that when ClipHeightTo() produces a scrollbar, it reduces the width // of the inner content of the ScrollView. TEST_F(ScrollViewTest, ClipHeightToScrollbarUsesWidth) { - scroll_view_.ClipHeightTo(kMinHeight, kMaxHeight); + scroll_view_->ClipHeightTo(kMinHeight, kMaxHeight); // Create a view that will be much taller than it is wide. - scroll_view_.SetContents(new views::ProportionallySizedView(1000)); + scroll_view_->SetContents(new views::ProportionallySizedView(1000)); // Without any width, it will default to 0,0 but be overridden by min height. - scroll_view_.SizeToPreferredSize(); - EXPECT_EQ(gfx::Size(0, kMinHeight), scroll_view_.GetPreferredSize()); + scroll_view_->SizeToPreferredSize(); + EXPECT_EQ(gfx::Size(0, kMinHeight), scroll_view_->GetPreferredSize()); - gfx::Size new_size(kWidth, scroll_view_.GetHeightForWidth(kWidth)); - scroll_view_.SetSize(new_size); - scroll_view_.Layout(); + gfx::Size new_size(kWidth, scroll_view_->GetHeightForWidth(kWidth)); + scroll_view_->SetSize(new_size); + scroll_view_->Layout(); - int expected_width = kWidth - scroll_view_.GetScrollBarLayoutWidth(); - EXPECT_EQ(scroll_view_.contents()->size().width(), expected_width); - EXPECT_EQ(scroll_view_.contents()->size().height(), 1000 * expected_width); - EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_.size()); + int expected_width = kWidth - scroll_view_->GetScrollBarLayoutWidth(); + EXPECT_EQ(scroll_view_->contents()->size().width(), expected_width); + EXPECT_EQ(scroll_view_->contents()->size().height(), 1000 * expected_width); + EXPECT_EQ(gfx::Size(kWidth, kMaxHeight), scroll_view_->size()); } TEST_F(ScrollViewTest, CornerViewVisibility) { View* contents = InstallContents(); - View* corner_view = ScrollViewTestApi(&scroll_view_).corner_view(); + View* corner_view = ScrollViewTestApi(scroll_view_.get()).corner_view(); contents->SetBounds(0, 0, 200, 200); - scroll_view_.Layout(); + scroll_view_->Layout(); // Corner view should not exist if using overlay scrollbars. - if (scroll_view_.vertical_scroll_bar()->OverlapsContent()) { + if (scroll_view_->vertical_scroll_bar()->OverlapsContent()) { EXPECT_FALSE(corner_view->parent()); return; } // Corner view should be visible when both scrollbars are visible. - EXPECT_EQ(&scroll_view_, corner_view->parent()); + EXPECT_EQ(scroll_view_.get(), corner_view->parent()); EXPECT_TRUE(corner_view->visible()); // Corner view should be aligned to the scrollbars. - EXPECT_EQ(scroll_view_.vertical_scroll_bar()->x(), corner_view->x()); - EXPECT_EQ(scroll_view_.horizontal_scroll_bar()->y(), corner_view->y()); - EXPECT_EQ(scroll_view_.GetScrollBarLayoutWidth(), corner_view->width()); - EXPECT_EQ(scroll_view_.GetScrollBarLayoutHeight(), corner_view->height()); + EXPECT_EQ(scroll_view_->vertical_scroll_bar()->x(), corner_view->x()); + EXPECT_EQ(scroll_view_->horizontal_scroll_bar()->y(), corner_view->y()); + EXPECT_EQ(scroll_view_->GetScrollBarLayoutWidth(), corner_view->width()); + EXPECT_EQ(scroll_view_->GetScrollBarLayoutHeight(), corner_view->height()); // Corner view should be removed when only the vertical scrollbar is visible. contents->SetBounds(0, 0, 50, 200); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_FALSE(corner_view->parent()); // ... or when only the horizontal scrollbar is visible. contents->SetBounds(0, 0, 200, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_FALSE(corner_view->parent()); // ... or when no scrollbar is visible. contents->SetBounds(0, 0, 50, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_FALSE(corner_view->parent()); // Corner view should reappear when both scrollbars reappear. contents->SetBounds(0, 0, 200, 200); - scroll_view_.Layout(); - EXPECT_EQ(&scroll_view_, corner_view->parent()); + scroll_view_->Layout(); + EXPECT_EQ(scroll_view_.get(), corner_view->parent()); EXPECT_TRUE(corner_view->visible()); } TEST_F(ScrollViewTest, ChildWithLayerTest) { View* contents = InstallContents(); - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); if (test_api.contents_viewport()->layer()) return; @@ -812,7 +817,7 @@ EXPECT_TRUE(test_api.contents_viewport()->layer()->fills_bounds_opaquely()); // Setting a transparent color should make fills opaquely false. - scroll_view_.SetBackgroundColor(SK_ColorTRANSPARENT); + scroll_view_->SetBackgroundColor(SK_ColorTRANSPARENT); EXPECT_FALSE(test_api.contents_viewport()->layer()->fills_bounds_opaquely()); child->DestroyLayer(); @@ -829,12 +834,12 @@ // is added to the ScrollView's viewport. TEST_F(ScrollViewTest, DontCreateLayerOnViewportIfLayerOnScrollViewCreated) { View* contents = InstallContents(); - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); if (test_api.contents_viewport()->layer()) return; - scroll_view_.SetPaintToLayer(); + scroll_view_->SetPaintToLayer(); View* child = new View(); contents->AddChildView(child); @@ -853,35 +858,35 @@ // Size the contents such that vertical scrollbar is needed. // Since it is overlaid, the ViewPort size should match the ScrollView. contents->SetBounds(0, 0, 50, 400); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(100, contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutWidth()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, false); + EXPECT_EQ(0, scroll_view_->GetScrollBarLayoutWidth()); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, false); // Size the contents such that horizontal scrollbar is needed. contents->SetBounds(0, 0, 400, 50); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(100, contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutHeight()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, false); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); + EXPECT_EQ(0, scroll_view_->GetScrollBarLayoutHeight()); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, false); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); // Both horizontal and vertical scrollbars. contents->SetBounds(0, 0, 300, 400); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(100, contents->parent()->width()); EXPECT_EQ(100, contents->parent()->height()); - EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutWidth()); - EXPECT_EQ(0, scroll_view_.GetScrollBarLayoutHeight()); - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); + EXPECT_EQ(0, scroll_view_->GetScrollBarLayoutWidth()); + EXPECT_EQ(0, scroll_view_->GetScrollBarLayoutHeight()); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); // Make sure the horizontal and vertical scrollbars don't overlap each other. - gfx::Rect vert_bounds = scroll_view_.vertical_scroll_bar()->bounds(); - gfx::Rect horiz_bounds = scroll_view_.horizontal_scroll_bar()->bounds(); + gfx::Rect vert_bounds = scroll_view_->vertical_scroll_bar()->bounds(); + gfx::Rect horiz_bounds = scroll_view_->horizontal_scroll_bar()->bounds(); EXPECT_EQ(vert_bounds.x(), horiz_bounds.right()); EXPECT_EQ(horiz_bounds.y(), vert_bounds.bottom()); @@ -982,11 +987,11 @@ // 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_F(ScrollViewTest, ConstrainScrollToBounds) { - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); View* contents = InstallContents(); contents->SetBoundsRect(gfx::Rect(0, 0, 300, 300)); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(gfx::ScrollOffset(), test_api.CurrentOffset()); @@ -996,49 +1001,49 @@ 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(); + 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(); + 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()); } // Calling Layout on ScrollView should not reset the scroll location. TEST_F(ScrollViewTest, ContentScrollNotResetOnLayout) { - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); CustomView* contents = new CustomView; contents->SetPreferredSize(gfx::Size(300, 300)); - scroll_view_.SetContents(contents); - scroll_view_.ClipHeightTo(0, 150); - scroll_view_.SizeToPreferredSize(); + scroll_view_->SetContents(contents); + scroll_view_->ClipHeightTo(0, 150); + scroll_view_->SizeToPreferredSize(); // ScrollView preferred width matches that of |contents|, with the height // capped at the value we clipped to. - EXPECT_EQ(gfx::Size(300, 150), scroll_view_.size()); + EXPECT_EQ(gfx::Size(300, 150), scroll_view_->size()); // Scroll down. - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), 25); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), 25); EXPECT_EQ(25, test_api.CurrentOffset().y()); // Call Layout; no change to scroll position. - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(25, test_api.CurrentOffset().y()); // Change contents of |contents|, call Layout; still no change to scroll // position. contents->SetPreferredSize(gfx::Size(300, 500)); contents->InvalidateLayout(); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(25, test_api.CurrentOffset().y()); // Change |contents| to be shorter than the ScrollView's clipped height. // This /will/ change the scroll location due to ConstrainScrollToBounds. contents->SetPreferredSize(gfx::Size(300, 50)); - scroll_view_.Layout(); + scroll_view_->Layout(); EXPECT_EQ(0, test_api.CurrentOffset().y()); } @@ -1046,16 +1051,16 @@ TEST_F(ScrollViewTest, VerticalOverflowIndicators) { const int kWidth = 100; - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); // Set up with vertical scrollbar. FixedView* contents = new FixedView; contents->SetPreferredSize(gfx::Size(kWidth, kMaxHeight * 5)); - scroll_view_.SetContents(contents); - scroll_view_.ClipHeightTo(0, kMaxHeight); + scroll_view_->SetContents(contents); + scroll_view_->ClipHeightTo(0, kMaxHeight); // Make sure the size is set such that no horizontal scrollbar gets shown. - scroll_view_.SetSize( + scroll_view_->SetSize( gfx::Size(kWidth + test_api.GetBaseScrollBar(VERTICAL)->GetThickness(), kMaxHeight)); @@ -1064,8 +1069,8 @@ // The vertical scroll bar should be visible and the horizontal scroll bar // should not. - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, false); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, false); // The overflow indicator on the bottom should be visible. EXPECT_TRUE(test_api.more_content_bottom()->visible()); @@ -1079,7 +1084,7 @@ // Now scroll the view to someplace in the middle of the scrollable region. int offset = kMaxHeight * 2; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset()); // At this point, both overflow indicators on the top and bottom should be @@ -1093,7 +1098,7 @@ // Finally scroll the view to end of the scrollable region. offset = kMaxHeight * 4; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset()); // The overflow indicator on the bottom should not be visible. @@ -1111,15 +1116,15 @@ const int kWidth = 100; const int kHeight = 100; - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); // Set up with horizontal scrollbar. FixedView* contents = new FixedView; contents->SetPreferredSize(gfx::Size(kWidth * 5, kHeight)); - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); // Make sure the size is set such that no vertical scrollbar gets shown. - scroll_view_.SetSize(gfx::Size( + scroll_view_->SetSize(gfx::Size( kWidth, kHeight + test_api.GetBaseScrollBar(HORIZONTAL)->GetThickness())); contents->SetBounds(0, 0, kWidth * 5, kHeight); @@ -1129,8 +1134,8 @@ // The horizontal scroll bar should be visible and the vertical scroll bar // should not. - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); - CheckScrollbarVisibility(scroll_view_, VERTICAL, false); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, false); // The overflow indicator on the right should be visible. EXPECT_TRUE(test_api.more_content_right()->visible()); @@ -1144,7 +1149,7 @@ // Now scroll the view to someplace in the middle of the scrollable region. int offset = kWidth * 2; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), offset); EXPECT_EQ(gfx::ScrollOffset(offset, 0), test_api.CurrentOffset()); // At this point, both overflow indicators on the left and right should be @@ -1158,7 +1163,7 @@ // Finally scroll the view to end of the scrollable region. offset = kWidth * 4; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), offset); EXPECT_EQ(gfx::ScrollOffset(offset, 0), test_api.CurrentOffset()); // The overflow indicator on the right should not be visible. @@ -1176,22 +1181,22 @@ const int kWidth = 100; const int kHeight = 100; - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); // Set up with both horizontal and vertical scrollbars. FixedView* contents = new FixedView; contents->SetPreferredSize(gfx::Size(kWidth * 5, kHeight * 5)); - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); // Make sure the size is set such that both scrollbars are shown. - scroll_view_.SetSize(gfx::Size(kWidth, kHeight)); + scroll_view_->SetSize(gfx::Size(kWidth, kHeight)); // Make sure the initial origin is 0,0 EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset()); // The horizontal and vertical scroll bars should be visible. - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, true); - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, true); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); // The overflow indicators on the right and bottom should not be visible since // they are against the scrollbars. @@ -1205,8 +1210,8 @@ // Now scroll the view to someplace in the middle of the horizontal scrollable // region. int offset_x = kWidth * 2; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), - offset_x); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), + offset_x); EXPECT_EQ(gfx::ScrollOffset(offset_x, 0), test_api.CurrentOffset()); // Since there is a vertical scrollbar only the overflow indicator on the left @@ -1220,8 +1225,8 @@ // Next, scroll the view to end of the scrollable region. offset_x = kWidth * 4; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), - offset_x); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), + offset_x); EXPECT_EQ(gfx::ScrollOffset(offset_x, 0), test_api.CurrentOffset()); // The overflow indicator on the right should still not be visible. @@ -1237,7 +1242,7 @@ EXPECT_FALSE(test_api.more_content_bottom()->visible()); // Return the view back to the horizontal origin. - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), 0); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), 0); EXPECT_EQ(gfx::ScrollOffset(0, 0), test_api.CurrentOffset()); // The overflow indicators on the right and bottom should not be visible since @@ -1253,7 +1258,7 @@ // Now scroll the view to somplace in the middle of the vertical scrollable // region. int offset_y = kHeight * 2; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset_y); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset_y); EXPECT_EQ(gfx::ScrollOffset(0, offset_y), test_api.CurrentOffset()); // Similar to the above, since there is a horizontal scrollbar only the @@ -1268,7 +1273,7 @@ // Finally, for the vertical test scroll the region all the way to the end. offset_y = kHeight * 4; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset_y); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset_y); EXPECT_EQ(gfx::ScrollOffset(0, offset_y), test_api.CurrentOffset()); // The overflow indicator on the bottom should still not be visible. @@ -1286,8 +1291,8 @@ // Back to the horizontal. Scroll all the way to the end in the horizontal // direction. offset_x = kWidth * 4; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), - offset_x); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(HORIZONTAL), + offset_x); EXPECT_EQ(gfx::ScrollOffset(offset_x, offset_y), test_api.CurrentOffset()); // The overflow indicator on the bottom and right should still not be visible. @@ -1302,19 +1307,19 @@ TEST_F(ScrollViewTest, VerticalWithHeaderOverflowIndicators) { const int kWidth = 100; - ScrollViewTestApi test_api(&scroll_view_); + ScrollViewTestApi test_api(scroll_view_.get()); // Set up with vertical scrollbar and a header. FixedView* contents = new FixedView; CustomView* header = new CustomView; contents->SetPreferredSize(gfx::Size(kWidth, kMaxHeight * 5)); - scroll_view_.SetContents(contents); + scroll_view_->SetContents(contents); header->SetPreferredSize(gfx::Size(10, 20)); - scroll_view_.SetHeader(header); - scroll_view_.ClipHeightTo(0, kMaxHeight + header->height()); + scroll_view_->SetHeader(header); + scroll_view_->ClipHeightTo(0, kMaxHeight + header->height()); // Make sure the size is set such that no horizontal scrollbar gets shown. - scroll_view_.SetSize( + scroll_view_->SetSize( gfx::Size(kWidth + test_api.GetBaseScrollBar(VERTICAL)->GetThickness(), kMaxHeight + header->height())); @@ -1323,8 +1328,8 @@ // The vertical scroll bar should be visible and the horizontal scroll bar // should not. - CheckScrollbarVisibility(scroll_view_, VERTICAL, true); - CheckScrollbarVisibility(scroll_view_, HORIZONTAL, false); + CheckScrollbarVisibility(scroll_view_.get(), VERTICAL, true); + CheckScrollbarVisibility(scroll_view_.get(), HORIZONTAL, false); // The overflow indicator on the bottom should be visible. EXPECT_TRUE(test_api.more_content_bottom()->visible()); @@ -1338,7 +1343,7 @@ // Now scroll the view to someplace in the middle of the scrollable region. int offset = kMaxHeight * 2; - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset()); // At this point, only the overflow indicator on the bottom should be visible @@ -1353,7 +1358,7 @@ // Finally scroll the view to end of the scrollable region. offset = test_api.GetBaseScrollBar(VERTICAL)->GetMaxPosition(); - scroll_view_.ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); + scroll_view_->ScrollToPosition(test_api.GetBaseScrollBar(VERTICAL), offset); EXPECT_EQ(gfx::ScrollOffset(0, offset), test_api.CurrentOffset()); // The overflow indicator on the bottom should not be visible now.
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc index 082ea64..f499e20 100644 --- a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc +++ b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
@@ -32,7 +32,10 @@ class TabbedPaneTest : public ViewsTestBase { public: - TabbedPaneTest() { + TabbedPaneTest() = default; + + void SetUp() override { + ViewsTestBase::SetUp(); tabbed_pane_ = std::make_unique<TabbedPane>(); tabbed_pane_->set_owned_by_client(); }
diff --git a/ui/views/mus/remote_view/remote_view_host.cc b/ui/views/mus/remote_view/remote_view_host.cc index 3023825..c5f9e57 100644 --- a/ui/views/mus/remote_view/remote_view_host.cc +++ b/ui/views/mus/remote_view/remote_view_host.cc
@@ -24,9 +24,21 @@ // Only works with mus. DCHECK_EQ(aura::Env::Mode::MUS, aura::Env::GetInstanceDontCreate()->mode()); + embed_token_ = embed_token; + embed_flags_ = embed_flags; + embed_callback_ = std::move(callback); + + if (GetWidget()) + CreateEmbeddingRoot(); +} + +void RemoteViewHost::CreateEmbeddingRoot() { // Should not be attached to anything. DCHECK(!native_view()); + // There is a pending embed request. + DCHECK(!embed_token_.is_empty()); + embedding_root_ = std::make_unique<aura::Window>(nullptr); embedding_root_->set_owned_by_parent(false); @@ -36,33 +48,29 @@ embedding_root_->SetType(aura::client::WINDOW_TYPE_CONTROL); embedding_root_->Init(ui::LAYER_NOT_DRAWN); + // Must happen before EmbedUsingToken call for window server to figure out + // the relevant display. + Attach(embedding_root_.get()); + aura::WindowPortMus::Get(embedding_root_.get()) - ->EmbedUsingToken(embed_token, embed_flags, + ->EmbedUsingToken(embed_token_, embed_flags_, base::BindOnce(&RemoteViewHost::OnEmbedResult, - weak_ptr_factory_.GetWeakPtr(), - embed_token, std::move(callback))); + weak_ptr_factory_.GetWeakPtr())); } -void RemoteViewHost::OnEmbedResult(const base::UnguessableToken& token, - EmbedCallback callback, - bool success) { - LOG_IF(ERROR, !success) << "Failed to embed, token=" << token; - - // Attach to |embedding_root_| if embed succeeds and this view is added to a - // widget but has not yet attached to |embedding_root_|. - if (success && GetWidget() && !native_view()) - Attach(embedding_root_.get()); +void RemoteViewHost::OnEmbedResult(bool success) { + LOG_IF(ERROR, !success) << "Failed to embed, token=" << embed_token_; if (!success && embedding_root_) embedding_root_.reset(); - if (callback) - std::move(callback).Run(success); + if (embed_callback_) + std::move(embed_callback_).Run(success); } void RemoteViewHost::AddedToWidget() { - if (embedding_root_ && !native_view()) - Attach(embedding_root_.get()); + if (!native_view() && !embed_token_.is_empty()) + CreateEmbeddingRoot(); } } // namespace views
diff --git a/ui/views/mus/remote_view/remote_view_host.h b/ui/views/mus/remote_view/remote_view_host.h index d52ddaf..44b1552 100644 --- a/ui/views/mus/remote_view/remote_view_host.h +++ b/ui/views/mus/remote_view/remote_view_host.h
@@ -23,25 +23,32 @@ RemoteViewHost(); ~RemoteViewHost() override; - // Creates an aura::window to embed the remote contents and attach to it when - // the embed succeeds. |embed_token| is the token obtained from the WindowTree - // embed API (ScheduleEmbed/ForExistingClient). |embed_flags| are the - // embedding flags (see window_tree_constants.mojom). |callback| is an - // optional callback invoked with the embed result. + // Embeds the remote contents after this view is added to a widget. + // |embed_token| is the token obtained from the WindowTree embed API + // (ScheduleEmbed/ForExistingClient). |embed_flags| are the embedding flags + // (see window_tree_constants.mojom). |callback| is an optional callback + // invoked with the embed result. + // Note that |callback| should not be used to add the view to a widget because + // the actual embedding only happens after the view is added. using EmbedCallback = base::OnceCallback<void(bool success)>; void EmbedUsingToken(const base::UnguessableToken& embed_token, int embed_flags, EmbedCallback callback); private: + // Creates the embedding aura::Window and attach to it. + void CreateEmbeddingRoot(); + // Invoked after the embed operation. - void OnEmbedResult(const base::UnguessableToken& token, - EmbedCallback callback, - bool success); + void OnEmbedResult(bool success); // views::NativeViewHost: void AddedToWidget() override; + base::UnguessableToken embed_token_; + int embed_flags_ = 0; + EmbedCallback embed_callback_; + std::unique_ptr<aura::Window> embedding_root_; base::WeakPtrFactory<RemoteViewHost> weak_ptr_factory_{this};
diff --git a/ui/views/mus/remote_view/remote_view_host_unittest.cc b/ui/views/mus/remote_view/remote_view_host_unittest.cc index 6497543..611c001 100644 --- a/ui/views/mus/remote_view/remote_view_host_unittest.cc +++ b/ui/views/mus/remote_view/remote_view_host_unittest.cc
@@ -87,13 +87,13 @@ // Ownership will be passed to |widget| later. RemoteViewHost* host = new RemoteViewHost(); + std::unique_ptr<views::Widget> widget = CreateTestWidget(host); + EXPECT_FALSE(host->native_view()); // Embed fails with unknown token. EXPECT_FALSE(Embed(host, unknown_token)); - // |host| is not attached before and after adding to a widget. - EXPECT_FALSE(host->native_view()); - std::unique_ptr<views::Widget> widget = CreateTestWidget(host); + // |host| is not attached after adding to a widget. EXPECT_FALSE(host->native_view()); } @@ -117,29 +117,6 @@ EXPECT_TRUE(host->native_view()); } -// Tests when RemoveViewHost is added to a widget while embedding. -TEST_F(RemoteViewHostTest, AddToWidgetWhileEmbedding) { - const base::UnguessableToken token = base::UnguessableToken::Create(); - window_tree()->AddScheduledEmbedToken(token); - - // Ownership will be passed to |widget| later. - RemoteViewHost* host = new RemoteViewHost(); - - // |host| is not attached because embed operation is not performed. - EXPECT_FALSE(host->native_view()); - - base::RunLoop run_loop; - std::unique_ptr<views::Widget> widget; - host->EmbedUsingToken( - token, 0u /* no flags */, - base::BindOnce(&RemoteViewHostTest::CreateTestWidgetWhileEmbeddingHelper, - base::Unretained(this), &run_loop, host, &widget)); - run_loop.Run(); - - // |host| is attached to the embedding window. - EXPECT_TRUE(host->native_view()); -} - // Tests when RemoveViewHost is added to a widget after embedding. TEST_F(RemoteViewHostTest, AddToWidgetAfterEmbed) { const base::UnguessableToken token = base::UnguessableToken::Create(); @@ -148,12 +125,26 @@ // Ownership will be passed to |widget| later. RemoteViewHost* host = new RemoteViewHost(); - // Embed succeeds. - EXPECT_TRUE(Embed(host, token)); + // Request embedding but it will be deferred until added to a widget. + base::RunLoop run_loop; + bool embed_result = false; + host->EmbedUsingToken( + token, 0u /* no flags */, + base::BindOnce( + [](base::RunLoop* run_loop, bool* result, bool success) { + *result = success; + run_loop->Quit(); + }, + &run_loop, &embed_result)); - // |host| is attached after adding to a widget. + // |host| is not attached before adding to a widget. EXPECT_FALSE(host->native_view()); + + // Add to a widget and wait for embed to finish. std::unique_ptr<views::Widget> widget = CreateTestWidget(host); + run_loop.Run(); + + // |host| is attached after added to a widget. EXPECT_TRUE(host->native_view()); }
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc index 635c932..dbe61e9 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -31,14 +31,22 @@ void DesktopWindowTreeHostPlatform::SetBoundsInDIP( const gfx::Rect& bounds_in_dip) { + DCHECK_NE(0, device_scale_factor()); SetBoundsInPixels( gfx::ConvertRectToPixel(device_scale_factor(), bounds_in_dip)); } void DesktopWindowTreeHostPlatform::Init(const Widget::InitParams& params) { + CreateAndSetDefaultPlatformWindow(); + // TODO(sky): this should be |params.force_software_compositing|, figure out + // why it has to be true now. + const bool use_software_compositing = true; + CreateCompositor(viz::FrameSinkId(), use_software_compositing); + aura::WindowTreeHost::OnAcceleratedWidgetAvailable(); + InitHost(); if (!params.bounds.IsEmpty()) SetBoundsInDIP(params.bounds); - InitHost(); + window()->Show(); } void DesktopWindowTreeHostPlatform::OnNativeWidgetCreated( @@ -59,7 +67,7 @@ DesktopWindowTreeHostPlatform::CreateDragDropClient( DesktopNativeCursorManager* cursor_manager) { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return nullptr; } @@ -94,8 +102,10 @@ void DesktopWindowTreeHostPlatform::ShowWindowWithState( ui::WindowShowState show_state) { - if (compositor()) + if (compositor()) { platform_window()->Show(); + compositor()->SetVisible(true); + } switch (show_state) { case ui::SHOW_STATE_MAXIMIZED: @@ -137,7 +147,7 @@ bool DesktopWindowTreeHostPlatform::IsVisible() const { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return true; } @@ -149,11 +159,11 @@ } void DesktopWindowTreeHostPlatform::StackAbove(aura::Window* window) { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void DesktopWindowTreeHostPlatform::StackAtTop() { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void DesktopWindowTreeHostPlatform::CenterWindow(const gfx::Size& size) { @@ -178,7 +188,7 @@ void DesktopWindowTreeHostPlatform::GetWindowPlacement( gfx::Rect* bounds, ui::WindowShowState* show_state) const { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); *bounds = gfx::Rect(0, 0, 640, 840); *show_state = ui::SHOW_STATE_NORMAL; } @@ -200,7 +210,7 @@ } gfx::Rect DesktopWindowTreeHostPlatform::GetRestoredBounds() const { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return gfx::Rect(0, 0, 640, 840); } @@ -217,22 +227,22 @@ void DesktopWindowTreeHostPlatform::SetShape( std::unique_ptr<Widget::ShapeRects> native_shape) { - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void DesktopWindowTreeHostPlatform::Activate() { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void DesktopWindowTreeHostPlatform::Deactivate() { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } bool DesktopWindowTreeHostPlatform::IsActive() const { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return false; } @@ -250,25 +260,23 @@ bool DesktopWindowTreeHostPlatform::IsMaximized() const { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return false; } bool DesktopWindowTreeHostPlatform::IsMinimized() const { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return false; } bool DesktopWindowTreeHostPlatform::HasCapture() const { - // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); - return false; + return platform_window()->HasCapture(); } void DesktopWindowTreeHostPlatform::SetAlwaysOnTop(bool always_on_top) { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } bool DesktopWindowTreeHostPlatform::IsAlwaysOnTop() const { @@ -279,7 +287,7 @@ void DesktopWindowTreeHostPlatform::SetVisibleOnAllWorkspaces( bool always_visible) { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } bool DesktopWindowTreeHostPlatform::IsVisibleOnAllWorkspaces() const { @@ -290,13 +298,13 @@ bool DesktopWindowTreeHostPlatform::SetWindowTitle( const base::string16& title) { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return false; } void DesktopWindowTreeHostPlatform::ClearNativeFocus() { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } Widget::MoveLoopResult DesktopWindowTreeHostPlatform::RunMoveLoop( @@ -304,19 +312,19 @@ Widget::MoveLoopSource source, Widget::MoveLoopEscapeBehavior escape_behavior) { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return Widget::MOVE_LOOP_CANCELED; } void DesktopWindowTreeHostPlatform::EndMoveLoop() { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void DesktopWindowTreeHostPlatform::SetVisibilityChangedAnimationsEnabled( bool value) { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } NonClientFrameView* DesktopWindowTreeHostPlatform::CreateNonClientFrameView() { @@ -335,54 +343,54 @@ void DesktopWindowTreeHostPlatform::SetFullscreen(bool fullscreen) { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } bool DesktopWindowTreeHostPlatform::IsFullscreen() const { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return false; } void DesktopWindowTreeHostPlatform::SetOpacity(float opacity) { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void DesktopWindowTreeHostPlatform::SetWindowIcons( const gfx::ImageSkia& window_icon, const gfx::ImageSkia& app_icon) { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void DesktopWindowTreeHostPlatform::InitModalType(ui::ModalType modal_type) { // TODO: needs PlatformWindow support (alternatively, remove as // DesktopWindowTreeHostX11 doesn't support at all). - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } void DesktopWindowTreeHostPlatform::FlashFrame(bool flash_frame) { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } bool DesktopWindowTreeHostPlatform::IsAnimatingClosed() const { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return false; } bool DesktopWindowTreeHostPlatform::IsTranslucentWindowOpacitySupported() const { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); return false; } void DesktopWindowTreeHostPlatform::SizeConstraintsChanged() { // TODO: needs PlatformWindow support. - NOTIMPLEMENTED(); + NOTIMPLEMENTED_LOG_ONCE(); } bool DesktopWindowTreeHostPlatform::ShouldUpdateWindowTransparency() const { @@ -415,4 +423,5 @@ Widget* DesktopWindowTreeHostPlatform::GetWidget() { return native_widget_delegate_->AsWidget(); } + } // namespace views