diff --git a/BUILD.gn b/BUILD.gn index 0f2e28a..37cf59b 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -309,7 +309,6 @@ "//tools/android/customtabs_benchmark:customtabs_benchmark_apk", "//tools/android/errorprone_plugin:errorprone_plugin_java", "//tools/android/kerberos/SpnegoAuthenticator:spnego_authenticator_apk", - "//tools/cygprofile:cygprofile_unittests", "//ui/android:ui_junit_tests", ] deps -= [
diff --git a/DEPS b/DEPS index 47520704..9e6ec67 100644 --- a/DEPS +++ b/DEPS
@@ -79,11 +79,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '2388cd1f69e38c2ff2d275532f3afab1348fbbfe', + 'skia_revision': 'bd6525304d448f9c1ce04bf6b10bc9306802823e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': 'f4c401343e75692991a389491f784d1dfe1de9dc', + 'v8_revision': '598a80edc4157838591a393a728a2f4f79a3b66f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -91,7 +91,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'e05ffdd19837dc3782636fba164791091c92210e', + 'angle_revision': 'd2cb7cec4f3e303880ab5d55f6a58165cd23a631', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling build tools # and whatever else without interference from each other. @@ -103,7 +103,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': 'f3be555096b0b64917d27578e51c9e6c7d9c7083', + 'pdfium_revision': '9600a771999de20fb22130cdb97088591508f89f', # 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.
diff --git a/android_webview/browser/net/aw_network_delegate.cc b/android_webview/browser/net/aw_network_delegate.cc index 474a535e..1955b27 100644 --- a/android_webview/browser/net/aw_network_delegate.cc +++ b/android_webview/browser/net/aw_network_delegate.cc
@@ -53,7 +53,7 @@ DCHECK(headers); headers->SetHeaderIfMissing( "X-Requested-With", - base::android::BuildInfo::GetInstance()->package_name()); + base::android::BuildInfo::GetInstance()->host_package_name()); return net::OK; }
diff --git a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java index 4f432fb..02872d65b 100644 --- a/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java +++ b/android_webview/glue/java/src/com/android/webview/chromium/WebViewChromiumFactoryProvider.java
@@ -36,6 +36,7 @@ import org.chromium.android_webview.ResourcesContextWrapperFactory; import org.chromium.android_webview.WebViewChromiumRunQueue; import org.chromium.android_webview.command_line.CommandLineUtil; +import org.chromium.base.BuildInfo; import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.base.PackageUtils; @@ -100,12 +101,6 @@ // Initialization guarded by mAwInit.getLock() private Statics mStaticsAdapter; - // TODO(gsennton) remove this when downstream doesn't depend on it anymore - // Guards accees to adapters. - // This member is not private only because the downstream subclass needs to access it, - // it shouldn't be accessed from anywhere else. - /* package */ final Object mAdapterLock = new Object(); - /** * Thread-safe way to set the one and only WebViewChromiumFactoryProvider. */ @@ -202,11 +197,12 @@ } ThreadUtils.setWillOverrideUiThread(); + final PackageInfo packageInfo = WebViewFactory.getLoadedPackageInfo(); + BuildInfo.setBrowserPackageInfo(packageInfo); + // Load chromium library. AwBrowserProcess.loadLibrary(mWebViewDelegate.getDataDirectorySuffix()); - final PackageInfo packageInfo = WebViewFactory.getLoadedPackageInfo(); - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); try { // Load glue-layer support library.
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc index 4c81cb72..aade6bc96 100644 --- a/android_webview/lib/aw_main_delegate.cc +++ b/android_webview/lib/aw_main_delegate.cc
@@ -241,11 +241,11 @@ static ::crash_reporter::CrashKeyString<64> app_name_key( crash_keys::kAppPackageName); - app_name_key.Set(android_build_info->package_name()); + app_name_key.Set(android_build_info->host_package_name()); static ::crash_reporter::CrashKeyString<64> app_version_key( crash_keys::kAppPackageVersionCode); - app_version_key.Set(android_build_info->package_version_code()); + app_version_key.Set(android_build_info->host_version_code()); static ::crash_reporter::CrashKeyString<8> sdk_int_key( crash_keys::kAndroidSdkInt);
diff --git a/ash/components/shortcut_viewer_strings.grdp b/ash/components/shortcut_viewer_strings.grdp index ad1a6b1b..36cb6417 100644 --- a/ash/components/shortcut_viewer_strings.grdp +++ b/ash/components/shortcut_viewer_strings.grdp
@@ -74,10 +74,10 @@ <ph name="key">$1<ex>Overview Mode Key</ex></ph> </message> <message name="IDS_KSV_SHORTCUT_ONE_MODIFIER_ONE_KEY" desc="Human readable version of the keyboard shortcut. This is for all single modifier shortcuts."> - <ph name="modifier">$1<ex>Ctrl</ex></ph><ph name="separator">$2<ex>+</ex></ph><ph name="key">$3<ex>V</ex></ph> + <ph name="modifier">$1<ex>Ctrl</ex></ph><ph name="separator">$2<ex>+</ex></ph><ph name="key">$3<ex>v</ex></ph> </message> <message name="IDS_KSV_SHORTCUT_TWO_MODIFIERS_ONE_KEY" desc="Human readable version of the keyboard shortcut. This is for all two modifiers shortcuts."> - <ph name="modifier1">$1<ex>Ctrl</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="modifier2">$3<ex>Alt</ex></ph><ph name="separator2">$4<ex>+</ex></ph><ph name="key">$5<ex>V</ex></ph> + <ph name="modifier1">$1<ex>Ctrl</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="modifier2">$3<ex>Alt</ex></ph><ph name="separator2">$4<ex>+</ex></ph><ph name="key">$5<ex>v</ex></ph> </message> <!-- Shortcuts descriptions --> @@ -88,7 +88,7 @@ Change screen resolution </message> <message name="IDS_KSV_SHORTCUT_CHANGE_SCREEN_RESOLUTION" desc="Human readable version of the keyboard shortcut."> - <ph name="ctrl">$1</ph><ph name="separator1">$2</ph><ph name="shift">$3</ph><ph name="separator2">$4</ph><ph name="plus">$5</ph> or <ph name="minus">$6</ph> + <ph name="ctrl">$1<ex>Ctrl</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="shift">$3<ex>Shift</ex></ph><ph name="separator2">$4<ex>+</ex></ph><ph name="plus">$5<ex>v</ex></ph> or <ph name="minus">$6<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_DRAG_LINK_IN_SAME_TAB" desc="Description of the command in keyboard shortcut viewer."> Open the link in the tab @@ -100,7 +100,7 @@ Highlight the next item on your shelf </message> <message name="IDS_KSV_SHORTCUT_HIGHLIGHT_NEXT_ITEM_ON_SHELF" desc="Human readable version of the keyboard shortcut."> - <ph name="shift">$1</ph><ph name="separator1">$2</ph><ph name="alt">$3</ph><ph name="separator2">$4</ph><ph name="l">$5</ph>, then <ph name="tab">$6</ph> or <ph name="right">$7</ph> + <ph name="shift">$1<ex>Shift</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="alt">$3<ex>Alt</ex></ph><ph name="separator2">$4<ex>+</ex></ph><ph name="l">$5<ex>v</ex></ph>, then <ph name="tab">$6<ex>v</ex></ph> or <ph name="right">$7<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_PREVIOUS_IME" desc="Description of the command in keyboard shortcut viewer."> Switch to the previous keyboard language you were using. @@ -109,13 +109,13 @@ Switch quickly between windows </message> <message name="IDS_KSV_SHORTCUT_CYCLE_FORWARD_MRU" desc="Human readable version of the keyboard shortcut."> - Press and hold <ph name="alt">$1</ph>, tap <ph name="tab">$2</ph> until you get to the window you want to open, then release. + Press and hold <ph name="alt">$1<ex>Alt</ex></ph>, tap <ph name="tab">$2<ex>v</ex></ph> until you get to the window you want to open, then release. </message> <message name="IDS_KSV_DESCRIPTION_CYCLE_BACKWARD_MRU" desc="Description of the command in keyboard shortcut viewer."> Open the window you used least recently </message> <message name="IDS_KSV_SHORTCUT_CYCLE_BACKWARD_MRU" desc="Human readable version of the keyboard shortcut."> - Press and hold <ph name="alt">$1</ph><ph name="separator">$2</ph><ph name="shift">$3</ph>, tap <ph name="tab">$4</ph> until you get to the window you want to open, then release. + Press and hold <ph name="alt">$1<ex>Alt</ex></ph><ph name="separator">$2<ex>+</ex></ph><ph name="shift">$3<ex>Shift</ex></ph>, tap <ph name="tab">$4<ex>v</ex></ph> until you get to the window you want to open, then release. </message> <message name="IDS_KSV_DESCRIPTION_TOGGLE_OVERVIEW" desc="Description of the command in keyboard shortcut viewer."> Overview mode @@ -202,19 +202,19 @@ Go to the next match for your search </message> <message name="IDS_KSV_SHORTCUT_IDC_FIND_NEXT" desc="Human readable version of the keyboard shortcut."> - <ph name="ctrl">$1</ph><ph name="separator">$2</ph><ph name="g">$3</ph> or <ph name="enter">$4</ph> + <ph name="ctrl">$1<ex>Ctrl</ex></ph><ph name="separator">$2<ex>+</ex></ph><ph name="g">$3<ex>v</ex></ph> or <ph name="enter">$4<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_IDC_FIND_PREVIOUS" desc="Description of the command in keyboard shortcut viewer."> Go to the previous match for your search </message> <message name="IDS_KSV_SHORTCUT_IDC_FIND_PREVIOUS" desc="Human readable version of the keyboard shortcut."> - <ph name="ctrl">$1</ph><ph name="separator1">$2</ph><ph name="shift1">$3</ph><ph name="separator2">$4</ph><ph name="g">$5</ph> or <ph name="shift2">$6</ph><ph name="separator3">$7</ph><ph name="enter">$8</ph> + <ph name="ctrl">$1<ex>Ctrl</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="shift1">$3<ex>Shift</ex></ph><ph name="separator2">$4<ex>+</ex></ph><ph name="g">$5<ex>v</ex></ph> or <ph name="shift2">$6<ex>Shift</ex></ph><ph name="separator3">$7<ex>+</ex></ph><ph name="enter">$8<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_IDC_FOCUS_LOCATION" desc="Description of the command in keyboard shortcut viewer."> Focus address bar </message> <message name="IDS_KSV_SHORTCUT_IDC_FOCUS_LOCATION" desc="Description of the command in keyboard shortcut viewer."> - <ph name="ctrl">$1</ph><ph name="separator1">$2</ph><ph name="l">$3</ph> or <ph name="alt">$4</ph><ph name="separator2">$5</ph><ph name="d">$6</ph> + <ph name="ctrl">$1<ex>Ctrl</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="l">$3<ex>v</ex></ph> or <ph name="alt">$4<ex>Alt</ex></ph><ph name="separator2">$5<ex>+</ex></ph><ph name="d">$6<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_IDC_OPEN_FILE" desc="Description of the command in keyboard shortcut viewer."> Open a file in the browser @@ -274,7 +274,7 @@ Focus address bar on search </message> <message name="IDS_KSV_SHORTCUT_IDC_FOCUS_SEARCH" desc="Description of the command in keyboard shortcut viewer."> - <ph name="ctrl">$1</ph><ph name="separator">$2</ph><ph name="k">$3</ph> or <ph name="e">$4</ph> + <ph name="ctrl">$1<ex>Ctrl</ex></ph><ph name="separator">$2<ex>+</ex></ph><ph name="k">$3<ex>v</ex></ph> or <ph name="e">$4<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_IDC_FOCUS_TOOLBAR" desc="Description of the command in keyboard shortcut viewer."> Highlight the row with the address bar @@ -298,7 +298,7 @@ Go to numbered tab </message> <message name="IDS_KSV_SHORTCUT_SELECT_NUMBERED_TAB" desc="Human readable version of the keyboard shortcut."> - <ph name="ctrl">$1</ph><ph name="separator">$2</ph> 1 through 8 + <ph name="ctrl">$1<ex>Ctrl</ex></ph><ph name="separator">$2<ex>+</ex></ph> 1 through 8 </message> <message name="IDS_KSV_DESCRIPTION_KEYBOARD_SHORTCUT_HELPER" desc="Description of the command in keyboard shortcut viewer."> See Keyboard Shortcut Helper @@ -307,19 +307,19 @@ Open the link in a new tab in the background </message> <message name="IDS_KSV_SHORTCUT_OPEN_LINK_IN_TAB_BACKGROUND" desc="Human readable version of the keyboard shortcut."> - Press <ph name="ctrl">$1</ph> and click a link + Press <ph name="ctrl">$1<ex>Ctrl</ex></ph> and click a link </message> <message name="IDS_KSV_DESCRIPTION_OPEN_LINK_IN_TAB" desc="Description of the command in keyboard shortcut viewer."> Open the link in a new tab and switch to the new tab </message> <message name="IDS_KSV_SHORTCUT_OPEN_LINK_IN_TAB" desc="Human readable version of the keyboard shortcut."> - Press <ph name="ctrl">$1</ph><ph name="separator">$2</ph><ph name="shift">$3</ph> and click a link + Press <ph name="ctrl">$1<ex>Ctrl</ex></ph><ph name="separator">$2<ex>+</ex></ph><ph name="shift">$3<ex>Shift</ex></ph> and click a link </message> <message name="IDS_KSV_DESCRIPTION_OPEN_LINK_IN_WINDOW" desc="Description of the command in keyboard shortcut viewer."> Open the link in a new window </message> <message name="IDS_KSV_SHORTCUT_OPEN_LINK_IN_WINDOW" desc="Human readable version of the keyboard shortcut."> - Press <ph name="shift">$1</ph> and click a link + Press <ph name="shift">$1<ex>Shift</ex></ph> and click a link </message> <message name="IDS_KSV_DESCRIPTION_DRAG_LINK_IN_NEW_TAB" desc="Description of the command in keyboard shortcut viewer."> Open the link in a new tab @@ -331,25 +331,25 @@ Open the webpage in a new tab </message> <message name="IDS_KSV_SHORTCUT_OPEN_PAGE_IN_NEW_TAB" desc="Human readable version of the keyboard shortcut."> - Type a web address in the address bar, then press <ph name="alt">$1</ph><ph name="separator">$2</ph><ph name="enter">$3</ph> + Type a web address in the address bar, then press <ph name="alt">$1<ex>Alt</ex></ph><ph name="separator">$2<ex>+</ex></ph><ph name="enter">$3<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_STOP_DRAG_TAB" desc="Description of the command in keyboard shortcut viewer."> Return the tab to its original position </message> <message name="IDS_KSV_SHORTCUT_STOP_DRAG_TAB" desc="Human readable version of the keyboard shortcut."> - While dragging the tab, press <ph name="esc">$1</ph> + While dragging the tab, press <ph name="esc">$1<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_PAGE_UP" desc="Description of the command in keyboard shortcut viewer."> Page up </message> <message name="IDS_KSV_SHORTCUT_PAGE_UP" desc="Human readable version of the keyboard shortcut."> - <ph name="alt">$1</ph> or <ph name="search">$2</ph><ph name="separator">$3</ph><ph name="up">$4</ph> + <ph name="alt">$1<ex>Alt</ex></ph> or <ph name="search">$2<ex>Search</ex></ph><ph name="separator">$3<ex>+</ex></ph><ph name="up">$4<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_PAGE_DOWN" desc="Description of the command in keyboard shortcut viewer."> Page down </message> <message name="IDS_KSV_SHORTCUT_PAGE_DOWN" desc="Human readable version of the keyboard shortcut."> - <ph name="alt">$1</ph> or <ph name="search">$2</ph><ph name="separator">$3</ph><ph name="down">$4</ph> + <ph name="alt">$1<ex>Alt</ex></ph> or <ph name="search">$2<ex>Search</ex></ph><ph name="separator">$3<ex>+</ex></ph><ph name="down">$4<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_SCROLL_DOWN_PAGE" desc="Description of the command in keyboard shortcut viewer."> Scroll down the web page @@ -364,7 +364,7 @@ Right-click a link </message> <message name="IDS_KSV_SHORTCUT_RIGHT_CLICK" desc="Human readable version of the keyboard shortcut."> - Press <ph name="alt">$1</ph> and click a link + Press <ph name="alt">$1<ex>Alt</ex></ph> and click a link </message> <message name="IDS_KSV_DESCRIPTION_SAVE_LINK_AS_BOOKMARK" desc="Description of the command in keyboard shortcut viewer."> Save the link as a bookmark @@ -382,7 +382,7 @@ Preview a file in the Files app </message> <message name="IDS_KSV_SHORTCUT_OPEN_FILE" desc="Human readable version of the keyboard shortcut."> - Select the file, then press <ph name="space">$1</ph> + Select the file, then press <ph name="space">$1<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_DISPLAY_HIDDEN_FILES" desc="Description of the command in keyboard shortcut viewer."> Display hidden files in the Files app @@ -391,19 +391,19 @@ Click icons 1-8 on your shelf </message> <message name="IDS_KSV_SHORTCUT_LAUNCH_NUMBERED_APP" desc="Human readable version of the keyboard shortcut."> - <ph name="alt">$1</ph><ph name="separator">$2</ph> 1 through 8 + <ph name="alt">$1<ex>Alt</ex></ph><ph name="separator">$2<ex>+</ex></ph> 1 through 8 </message> <message name="IDS_KSV_DESCRIPTION_USE_F_KEYS" desc="Description of the command in keyboard shortcut viewer."> Use F keys (F1 to F12) </message> <message name="IDS_KSV_SHORTCUT_USE_F_KEYS" desc="Human readable version of the keyboard shortcut."> - <ph name="search">$1</ph><ph name="separator">$2</ph> 1 through = + <ph name="search">$1<ex>Search</ex></ph><ph name="separator">$2<ex>+</ex></ph> 1 through = </message> <message name="IDS_KSV_DESCRIPTION_SELECT_ADDRESS_BAR" desc="Description of the command in keyboard shortcut viewer."> Select the content in the address bar </message> <message name="IDS_KSV_SHORTCUT_SELECT_ADDRESS_BAR" desc="Human readable version of the keyboard shortcut."> - <ph name="ctrl">$1</ph><ph name="separator1">$2</ph><ph name="l">$3</ph> or <ph name="alt">$4</ph><ph name="separator2">$5</ph><ph name="d">$6</ph> + <ph name="ctrl">$1<ex>Ctrl</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="l">$3<ex>v</ex></ph> or <ph name="alt">$4<ex>Alt</ex></ph><ph name="separator2">$5<ex>+</ex></ph><ph name="d">$6<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_SELECT_NEXT_WORD" desc="Description of the command in keyboard shortcut viewer."> Select the next word or letter @@ -451,25 +451,25 @@ Highlight the previous item on your shelf </message> <message name="IDS_KSV_SHORTCUT_HIGHLIGHT_PREVIOUS_ITEM_ON_SHELF" desc="Human readable version of the keyboard shortcut."> - <ph name="shift1">$1</ph><ph name="separator1">$2</ph><ph name="alt">$3</ph><ph name="separator2">$4</ph><ph name="l">$5</ph>, then <ph name="shift2">$6</ph><ph name="separator3">$7</ph><ph name="tab">$8</ph> or <ph name="left">$9</ph> + <ph name="shift1">$1<ex>Shift</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="alt">$3<ex>Alt</ex></ph><ph name="separator2">$4<ex>+</ex></ph><ph name="l">$5<ex>v</ex></ph>, then <ph name="shift2">$6<ex>Shift</ex></ph><ph name="separator3">$7<ex>+</ex></ph><ph name="tab">$8<ex>v</ex></ph> or <ph name="left">$9<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_OPEN_HIGHLIGHTED_ITEM_ON_SHELF" desc="Description of the command in keyboard shortcut viewer."> Open the highlighted button on your shelf </message> <message name="IDS_KSV_SHORTCUT_OPEN_HIGHLIGHTED_ITEM_ON_SHELF" desc="Human readable version of the keyboard shortcut."> - <ph name="shift">$1</ph><ph name="separator1">$2</ph><ph name="alt">$3</ph><ph name="separator2">$4</ph><ph name="l">$5</ph>, then <ph name="space">$6</ph> or <ph name="enter">$7</ph> + <ph name="shift">$1<ex>Shift</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="alt">$3<ex>Alt</ex></ph><ph name="separator2">$4<ex>+</ex></ph><ph name="l">$5<ex>v</ex></ph>, then <ph name="space">$6<ex>v</ex></ph> or <ph name="enter">$7<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_REMOVE_HIGHLIGHT_ON_SHELF" desc="Description of the command in keyboard shortcut viewer."> Remove the highlight from a button on your shelf </message> <message name="IDS_KSV_SHORTCUT_REMOVE_HIGHLIGHT_ON_SHELF" desc="Human readable version of the keyboard shortcut."> - <ph name="shift">$1</ph><ph name="separator1">$2</ph><ph name="alt">$3</ph><ph name="separator2">$4</ph><ph name="l">$5</ph>, then <ph name="esc">$6</ph> + <ph name="shift">$1<ex>Shift</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="alt">$3<ex>Alt</ex></ph><ph name="separator2">$4<ex>+</ex></ph><ph name="l">$5<ex>v</ex></ph>, then <ph name="esc">$6<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_SWITCH_FOCUS" desc="Description of the command in keyboard shortcut viewer."> Switch focus between: Status area (where your account picture appears) Launcher Address bar Bookmarks bar (if visible) The webpage that's open Downloads bar (if visible) </message> <message name="IDS_KSV_SHORTCUT_SWITCH_FOCUS" desc="Human readable version of the keyboard shortcut."> - <ph name="ctrl1">$1</ph><ph name="separator1">$2</ph><ph name="left">$3</ph> or <ph name="ctrl2">$4</ph><ph name="separator2">$5</ph><ph name="right">$6</ph> + <ph name="ctrl1">$1<ex>Ctrl</ex></ph><ph name="separator1">$2<ex>+</ex></ph><ph name="left">$3<ex>v</ex></ph> or <ph name="ctrl2">$4<ex>Ctrl</ex></ph><ph name="separator2">$5<ex>+</ex></ph><ph name="right">$6<ex>v</ex></ph> </message> <message name="IDS_KSV_DESCRIPTION_OPEN_RIGHT_CLICK_MENU_FOR_HIGHLIGHTED_ITEM" desc="Description of the command in keyboard shortcut viewer."> Open right-click menu for highlighted item
diff --git a/ash/message_center/message_center_button_bar.cc b/ash/message_center/message_center_button_bar.cc index 9a33c69..d16480d 100644 --- a/ash/message_center/message_center_button_bar.cc +++ b/ash/message_center/message_center_button_bar.cc
@@ -6,6 +6,7 @@ #include "ash/message_center/message_center_style.h" #include "ash/message_center/message_center_view.h" +#include "ash/public/cpp/ash_features.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/strings/grit/ash_strings.h" #include "ash/system/tray/tray_popup_utils.h" @@ -35,7 +36,6 @@ #include "ui/views/controls/button/menu_button_listener.h" #include "ui/views/controls/label.h" #include "ui/views/controls/menu/menu_runner.h" -#include "ui/views/controls/separator.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/grid_layout.h" #include "ui/views/painter.h" @@ -112,14 +112,15 @@ notification_label_(nullptr), button_container_(nullptr), close_all_button_(nullptr), - settings_button_(nullptr), - quiet_mode_button_(nullptr) { + quiet_mode_button_(nullptr), + settings_button_(nullptr) { SetPaintToLayer(); SetBackground( views::CreateSolidBackground(message_center_style::kBackgroundColor)); SetBorder(views::CreateEmptyBorder(kButtonBarBorder)); - notification_label_ = new views::Label(GetTitle(locked)); + notification_label_ = new views::Label( + GetTitle(!locked || features::IsLockScreenNotificationsEnabled())); notification_label_->SetAutoColorReadabilityEnabled(false); notification_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT); notification_label_->SetEnabledColor(kTextColor); @@ -148,7 +149,8 @@ close_all_button_->SetTooltipText(l10n_util::GetStringUTF16( IDS_ASH_MESSAGE_CENTER_CLEAR_ALL_BUTTON_TOOLTIP)); button_container_->AddChildView(close_all_button_); - button_container_->AddChildView(CreateVerticalSeparator()); + separator_1_ = CreateVerticalSeparator(); + button_container_->AddChildView(separator_1_); quiet_mode_button_ = new MessageCenterButton(this); quiet_mode_button_->SetImage( @@ -166,7 +168,18 @@ IDS_ASH_MESSAGE_CENTER_QUIET_MODE_BUTTON_TOOLTIP)); SetQuietModeState(message_center->IsQuietMode()); button_container_->AddChildView(quiet_mode_button_); - button_container_->AddChildView(CreateVerticalSeparator()); + separator_2_ = CreateVerticalSeparator(); + button_container_->AddChildView(separator_2_); + + settings_button_ = new MessageCenterButton(this); + settings_button_->SetImage( + views::Button::STATE_NORMAL, + gfx::CreateVectorIcon(kNotificationCenterSettingsIcon, + message_center_style::kActionIconSize, + message_center_style::kActiveButtonColor)); + settings_button_->SetTooltipText(l10n_util::GetStringUTF16( + IDS_ASH_MESSAGE_CENTER_SETTINGS_BUTTON_TOOLTIP)); + button_container_->AddChildView(settings_button_); collapse_button_ = new MessageCenterButton(this); collapse_button_->SetVisible(false); @@ -182,16 +195,6 @@ IDS_ASH_MESSAGE_CENTER_COLLAPSE_BUTTON_TOOLTIP)); AddChildView(collapse_button_); - settings_button_ = new MessageCenterButton(this); - settings_button_->SetImage( - views::Button::STATE_NORMAL, - gfx::CreateVectorIcon(kNotificationCenterSettingsIcon, - message_center_style::kActionIconSize, - message_center_style::kActiveButtonColor)); - settings_button_->SetTooltipText(l10n_util::GetStringUTF16( - IDS_ASH_MESSAGE_CENTER_SETTINGS_BUTTON_TOOLTIP)); - button_container_->AddChildView(settings_button_); - AddChildView(button_container_); SetCloseAllButtonEnabled(!settings_initially_visible); @@ -274,32 +277,36 @@ } void MessageCenterButtonBar::SetIsLocked(bool locked) { - SetButtonsVisible(!locked); - UpdateLabel(locked); + SetButtonsVisible(locked); + UpdateLabel(!locked || features::IsLockScreenNotificationsEnabled()); } -base::string16 MessageCenterButtonBar::GetTitle(bool locked) const { - return locked - ? l10n_util::GetStringUTF16( - IDS_ASH_MESSAGE_CENTER_FOOTER_LOCKSCREEN) - : l10n_util::GetStringUTF16(IDS_ASH_MESSAGE_CENTER_FOOTER_TITLE); +base::string16 MessageCenterButtonBar::GetTitle( + bool message_center_visible) const { + return message_center_visible + ? l10n_util::GetStringUTF16(IDS_ASH_MESSAGE_CENTER_FOOTER_TITLE) + : l10n_util::GetStringUTF16( + IDS_ASH_MESSAGE_CENTER_FOOTER_LOCKSCREEN); } -void MessageCenterButtonBar::UpdateLabel(bool locked) { - notification_label_->SetText(GetTitle(locked)); +void MessageCenterButtonBar::UpdateLabel(bool message_center_visible) { + notification_label_->SetText(GetTitle(message_center_visible)); // On lock screen button bar label contains hint for user to unlock device to // view notifications. Making it focusable will invoke ChromeVox spoken // feedback when shown. - notification_label_->SetFocusBehavior(locked ? FocusBehavior::ALWAYS - : FocusBehavior::NEVER); + notification_label_->SetFocusBehavior( + message_center_visible ? FocusBehavior::ALWAYS : FocusBehavior::NEVER); } -void MessageCenterButtonBar::SetButtonsVisible(bool visible) { - settings_button_->SetVisible(visible); - quiet_mode_button_->SetVisible(visible); - +void MessageCenterButtonBar::SetButtonsVisible(bool locked) { + bool message_center_visible = + !locked || features::IsLockScreenNotificationsEnabled(); if (close_all_button_) - close_all_button_->SetVisible(visible); + close_all_button_->SetVisible(message_center_visible); + separator_1_->SetVisible(message_center_visible); + quiet_mode_button_->SetVisible(message_center_visible); + separator_2_->SetVisible(!locked); + settings_button_->SetVisible(!locked); Layout(); }
diff --git a/ash/message_center/message_center_button_bar.h b/ash/message_center/message_center_button_bar.h index 210e0aa..1b7c7e6 100644 --- a/ash/message_center/message_center_button_bar.h +++ b/ash/message_center/message_center_button_bar.h
@@ -10,6 +10,7 @@ #include "ui/compositor/layer_animation_observer.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/separator.h" #include "ui/views/view.h" namespace views { @@ -77,13 +78,13 @@ return message_center_; } - // Returns title for state specified by |locked|. - base::string16 GetTitle(bool locked) const; + // Returns title for state specified by |message_center_visible|. + base::string16 GetTitle(bool message_center_visible) const; - // Updates notification label for state specified by |locked|. - void UpdateLabel(bool locked); + // Updates notification label for state specified by |message_center_visible|. + void UpdateLabel(bool message_center_visible); - void SetButtonsVisible(bool visible); + void SetButtonsVisible(bool locked); MessageCenterView* message_center_view_; message_center::MessageCenter* message_center_; @@ -92,8 +93,12 @@ views::Label* notification_label_; views::View* button_container_; views::ToggleImageButton* close_all_button_; - views::ToggleImageButton* settings_button_; + // A view of a separator between |close_all_button_| and |quiet_mode_button_|. + views::Separator* separator_1_; views::ToggleImageButton* quiet_mode_button_; + // A view of a separator between |quiet_mode_button_| and |settings_button_|. + views::Separator* separator_2_; + views::ToggleImageButton* settings_button_; views::ToggleImageButton* collapse_button_; bool collapse_button_visible_ = false;
diff --git a/ash/message_center/message_center_view.cc b/ash/message_center/message_center_view.cc index 6be9fffc..c8623ebb 100644 --- a/ash/message_center/message_center_view.cc +++ b/ash/message_center/message_center_view.cc
@@ -10,6 +10,7 @@ #include "ash/message_center/message_center_button_bar.h" #include "ash/message_center/message_center_style.h" #include "ash/message_center/notifier_settings_view.h" +#include "ash/public/cpp/ash_features.h" #include "ash/public/cpp/ash_switches.h" #include "ash/resources/vector_icons/vector_icons.h" #include "ash/session/session_controller.h" @@ -191,7 +192,7 @@ ui_controller_(ui_controller), settings_visible_(initially_settings_visible), is_locked_(Shell::Get()->session_controller()->IsScreenLocked()) { - if (is_locked_) + if (is_locked_ && !features::IsLockScreenNotificationsEnabled()) mode_ = Mode::LOCKED; else if (initially_settings_visible) mode_ = Mode::SETTINGS; @@ -580,7 +581,7 @@ void MessageCenterView::Update(bool animate) { bool no_message_views = (message_list_view_->GetNotificationCount() == 0); - if (is_locked_) + if (is_locked_ && !features::IsLockScreenNotificationsEnabled()) SetVisibilityMode(Mode::LOCKED, animate); else if (settings_visible_) SetVisibilityMode(Mode::SETTINGS, animate); @@ -684,8 +685,7 @@ button_bar_->SetBackArrowVisible(mode_ == Mode::SETTINGS); button_bar_->SetIsLocked(is_locked_); - if (!is_locked_) - EnableCloseAllIfAppropriate(); + EnableCloseAllIfAppropriate(); } void MessageCenterView::EnableCloseAllIfAppropriate() {
diff --git a/ash/message_center/message_center_view_unittest.cc b/ash/message_center/message_center_view_unittest.cc index 67c7a27..24cc06b8 100644 --- a/ash/message_center/message_center_view_unittest.cc +++ b/ash/message_center/message_center_view_unittest.cc
@@ -11,11 +11,13 @@ #include "ash/message_center/message_center_button_bar.h" #include "ash/message_center/message_center_style.h" #include "ash/message_center/message_list_view.h" +#include "ash/public/cpp/ash_features.h" #include "ash/test/ash_test_base.h" #include "base/logging.h" #include "base/macros.h" #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/message_center/fake_message_center.h" #include "ui/message_center/notification_list.h" @@ -43,6 +45,12 @@ const char* kNotificationId1 = "notification id 1"; const char* kNotificationId2 = "notification id 2"; +// Plain button bar height (56) +const int kLockedMessageCenterViewHeight = 56; + +// Plain button bar height (56) + Empty view (96) +const int kEmptyMessageCenterViewHeight = 152; + /* Types **********************************************************************/ enum CallType { GET_PREFERRED_SIZE, GET_HEIGHT_FOR_WIDTH, LAYOUT }; @@ -158,6 +166,7 @@ /* Test fixture ***************************************************************/ class MessageCenterViewTest : public AshTestBase, + public testing::WithParamInterface<bool>, public MockNotificationView::Test, views::BoundsAnimatorObserver { public: @@ -204,6 +213,8 @@ void WaitForAnimationToFinish(); private: + void SetLockScreenNotificationsEnabled(); + views::View* MakeParent(views::View* child1, views::View* child2); // The ownership map of notifications; the key is the id. @@ -215,15 +226,23 @@ std::unique_ptr<base::RunLoop> run_loop_; + bool is_lock_screen_notifications_enabled_; + base::test::ScopedFeatureList scoped_feature_list_; + DISALLOW_COPY_AND_ASSIGN(MessageCenterViewTest); }; -MessageCenterViewTest::MessageCenterViewTest() = default; +MessageCenterViewTest::MessageCenterViewTest() + : is_lock_screen_notifications_enabled_(GetParam()) {} MessageCenterViewTest::~MessageCenterViewTest() = default; void MessageCenterViewTest::SetUp() { AshTestBase::SetUp(); + + if (is_lock_screen_notifications_enabled_) + SetLockScreenNotificationsEnabled(); + MessageCenterView::disable_animation_for_testing = true; message_center_.reset(new FakeMessageCenterImpl()); @@ -400,9 +419,13 @@ } } +void MessageCenterViewTest::SetLockScreenNotificationsEnabled() { + scoped_feature_list_.InitAndEnableFeature(features::kLockScreenNotifications); +} + /* Unit tests *****************************************************************/ -TEST_F(MessageCenterViewTest, CallTest) { +TEST_P(MessageCenterViewTest, CallTest) { // Verify that this didn't generate more than 2 Layout() call per descendant // NotificationView or more than a total of 20 GetPreferredSize() and // GetHeightForWidth() calls per descendant NotificationView. 20 is a very @@ -414,7 +437,7 @@ GetNotificationCount() * 20); } -TEST_F(MessageCenterViewTest, Size) { +TEST_P(MessageCenterViewTest, Size) { EXPECT_EQ(2, GetMessageListView()->child_count()); EXPECT_EQ(GetMessageListView()->height(), GetCalculatedMessageListViewHeight()); @@ -432,7 +455,7 @@ // TODO(tetsui): The test is broken because there's no guarantee anymore that // height would change after setting longer message, as NotificationViewMD // implements collapse / expand functionality of long message. -TEST_F(MessageCenterViewTest, DISABLED_SizeAfterUpdate) { +TEST_P(MessageCenterViewTest, DISABLED_SizeAfterUpdate) { EXPECT_EQ(2, GetMessageListView()->child_count()); int width = GetMessageListView()->width() - GetMessageListView()->GetInsets().width(); @@ -473,7 +496,7 @@ GetMessageListView()->GetInsets().height()); } -TEST_F(MessageCenterViewTest, SizeAfterUpdateBelowWithRepositionTarget) { +TEST_P(MessageCenterViewTest, SizeAfterUpdateBelowWithRepositionTarget) { EXPECT_EQ(2, GetMessageListView()->child_count()); // Make sure that notification 2 is placed above notification 1. EXPECT_LT(GetNotificationView(kNotificationId2)->bounds().y(), @@ -503,7 +526,7 @@ GetMessageListView()->GetInsets().height()); } -TEST_F(MessageCenterViewTest, SizeAfterUpdateOfRepositionTarget) { +TEST_P(MessageCenterViewTest, SizeAfterUpdateOfRepositionTarget) { EXPECT_EQ(2, GetMessageListView()->child_count()); // Make sure that notification 2 is placed above notification 1. EXPECT_LT(GetNotificationView(kNotificationId2)->bounds().y(), @@ -533,7 +556,7 @@ GetMessageListView()->GetInsets().height()); } -TEST_F(MessageCenterViewTest, SizeAfterRemove) { +TEST_P(MessageCenterViewTest, SizeAfterRemove) { int original_height = GetMessageListView()->height(); EXPECT_EQ(2, GetMessageListView()->child_count()); RemoveNotification(kNotificationId1, false); @@ -547,7 +570,7 @@ EXPECT_EQ(original_height, GetMessageListView()->height()); } -TEST_F(MessageCenterViewTest, PositionAfterUpdate) { +TEST_P(MessageCenterViewTest, PositionAfterUpdate) { // Make sure that the notification 2 is placed above the notification 1. EXPECT_LT(GetNotificationView(kNotificationId2)->bounds().y(), GetNotificationView(kNotificationId1)->bounds().y()); @@ -577,7 +600,7 @@ current_vertical_pos_from_bottom); } -TEST_F(MessageCenterViewTest, PositionAfterRemove) { +TEST_P(MessageCenterViewTest, PositionAfterRemove) { // Make sure that the notification 2 is placed above the notification 1. EXPECT_LT(GetNotificationView(kNotificationId2)->bounds().y(), GetNotificationView(kNotificationId1)->bounds().y()); @@ -614,7 +637,7 @@ EXPECT_EQ(previous_height, GetMessageListView()->height()); } -TEST_F(MessageCenterViewTest, CloseButton) { +TEST_P(MessageCenterViewTest, CloseButton) { views::Button* close_button = GetButtonBar()->GetCloseAllButtonForTest(); EXPECT_NE(nullptr, close_button); @@ -623,7 +646,7 @@ EXPECT_TRUE(GetMessageCenter()->remove_all_closable_notification_called_); } -TEST_F(MessageCenterViewTest, CloseButtonEnablity) { +TEST_P(MessageCenterViewTest, CloseButtonEnablity) { views::Button* close_button = GetButtonBar()->GetCloseAllButtonForTest(); EXPECT_NE(nullptr, close_button); @@ -720,7 +743,7 @@ EXPECT_FALSE(close_button->enabled()); } -TEST_F(MessageCenterViewTest, CheckModeWithSettingsVisibleAndHidden) { +TEST_P(MessageCenterViewTest, CheckModeWithSettingsVisibleAndHidden) { // Check the initial state. EXPECT_EQ(Mode::NOTIFICATIONS, GetMessageCenterViewInternalMode()); // Show the settings. @@ -731,7 +754,7 @@ EXPECT_EQ(Mode::NOTIFICATIONS, GetMessageCenterViewInternalMode()); } -TEST_F(MessageCenterViewTest, CheckModeWithRemovingAndAddingNotifications) { +TEST_P(MessageCenterViewTest, CheckModeWithRemovingAndAddingNotifications) { // Check the initial state. EXPECT_EQ(Mode::NOTIFICATIONS, GetMessageCenterViewInternalMode()); @@ -750,7 +773,7 @@ EXPECT_EQ(Mode::NOTIFICATIONS, GetMessageCenterViewInternalMode()); } -TEST_F(MessageCenterViewTest, CheckModeWithSettingsVisibleAndHiddenOnEmpty) { +TEST_P(MessageCenterViewTest, CheckModeWithSettingsVisibleAndHiddenOnEmpty) { // Set up by removing all existing notifications. RemoveDefaultNotifications(); @@ -764,7 +787,7 @@ EXPECT_EQ(Mode::NO_NOTIFICATIONS, GetMessageCenterViewInternalMode()); } -TEST_F(MessageCenterViewTest, +TEST_P(MessageCenterViewTest, CheckModeWithRemovingNotificationDuringSettingsVisible) { // Check the initial state. EXPECT_EQ(Mode::NOTIFICATIONS, GetMessageCenterViewInternalMode()); @@ -782,7 +805,7 @@ EXPECT_EQ(Mode::NO_NOTIFICATIONS, GetMessageCenterViewInternalMode()); } -TEST_F(MessageCenterViewTest, +TEST_P(MessageCenterViewTest, CheckModeWithAddingNotificationDuringSettingsVisible) { // Set up by removing all existing notifications. RemoveDefaultNotifications(); @@ -809,13 +832,15 @@ EXPECT_EQ(Mode::NOTIFICATIONS, GetMessageCenterViewInternalMode()); } -TEST_F(MessageCenterViewTest, CheckModeWithLockingAndUnlocking) { +TEST_P(MessageCenterViewTest, CheckModeWithLockingAndUnlocking) { // Check the initial state. EXPECT_EQ(Mode::NOTIFICATIONS, GetMessageCenterViewInternalMode()); // Lock! SetLockedState(true); - EXPECT_EQ(Mode::LOCKED, GetMessageCenterViewInternalMode()); + EXPECT_EQ(features::IsLockScreenNotificationsEnabled() ? Mode::NOTIFICATIONS + : Mode::LOCKED, + GetMessageCenterViewInternalMode()); // Unlock! SetLockedState(false); @@ -827,24 +852,32 @@ // Lock! SetLockedState(true); - EXPECT_EQ(Mode::LOCKED, GetMessageCenterViewInternalMode()); + EXPECT_EQ(features::IsLockScreenNotificationsEnabled() + ? Mode::NO_NOTIFICATIONS + : Mode::LOCKED, + GetMessageCenterViewInternalMode()); // Unlock! SetLockedState(false); EXPECT_EQ(Mode::NO_NOTIFICATIONS, GetMessageCenterViewInternalMode()); } -TEST_F(MessageCenterViewTest, CheckModeWithRemovingNotificationDuringLock) { +TEST_P(MessageCenterViewTest, CheckModeWithRemovingNotificationDuringLock) { // Check the initial state. EXPECT_EQ(Mode::NOTIFICATIONS, GetMessageCenterViewInternalMode()); // Lock! SetLockedState(true); - - EXPECT_EQ(Mode::LOCKED, GetMessageCenterViewInternalMode()); + EXPECT_EQ(features::IsLockScreenNotificationsEnabled() ? Mode::NOTIFICATIONS + : Mode::LOCKED, + GetMessageCenterViewInternalMode()); // Remove all existing notifications. RemoveDefaultNotifications(); + EXPECT_EQ(features::IsLockScreenNotificationsEnabled() + ? Mode::NO_NOTIFICATIONS + : Mode::LOCKED, + GetMessageCenterViewInternalMode()); // Unlock! SetLockedState(false); @@ -852,22 +885,19 @@ EXPECT_EQ(Mode::NO_NOTIFICATIONS, GetMessageCenterViewInternalMode()); } -TEST_F(MessageCenterViewTest, LockScreen) { - // Plain button bar height (56) - const int kLockedMessageCenterViewHeight = 56; - +TEST_P(MessageCenterViewTest, LockScreen) { EXPECT_TRUE(GetNotificationView(kNotificationId1)->IsDrawn()); EXPECT_TRUE(GetNotificationView(kNotificationId2)->IsDrawn()); views::Button* close_button = GetButtonBar()->GetCloseAllButtonForTest(); - ASSERT_NE(nullptr, close_button); + ASSERT_TRUE(close_button); views::Button* quiet_mode_button = GetButtonBar()->GetQuietModeButtonForTest(); - ASSERT_NE(nullptr, quiet_mode_button); + ASSERT_TRUE(quiet_mode_button); views::Button* settings_button = GetButtonBar()->GetSettingsButtonForTest(); - ASSERT_NE(nullptr, settings_button); + ASSERT_TRUE(settings_button); views::Button* collapse_button = GetButtonBar()->GetCollapseButtonForTest(); - ASSERT_NE(nullptr, collapse_button); + ASSERT_TRUE(collapse_button); EXPECT_TRUE(close_button->visible()); EXPECT_TRUE(quiet_mode_button->visible()); @@ -876,21 +906,39 @@ // Lock! SetLockedState(true); - EXPECT_FALSE(GetNotificationView(kNotificationId1)->IsDrawn()); - EXPECT_FALSE(GetNotificationView(kNotificationId2)->IsDrawn()); + if (features::IsLockScreenNotificationsEnabled()) { + EXPECT_TRUE(GetNotificationView(kNotificationId1)->IsDrawn()); + EXPECT_TRUE(GetNotificationView(kNotificationId2)->IsDrawn()); + } else { + EXPECT_FALSE(GetNotificationView(kNotificationId1)->IsDrawn()); + EXPECT_FALSE(GetNotificationView(kNotificationId2)->IsDrawn()); + } GetMessageCenterView()->SizeToPreferredSize(); - EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + if (features::IsLockScreenNotificationsEnabled()) { + EXPECT_NE(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + EXPECT_NE(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height()); + } else { + EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + } RemoveNotification(kNotificationId1, false); GetMessageCenterView()->SizeToPreferredSize(); - EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + if (features::IsLockScreenNotificationsEnabled()) { + EXPECT_NE(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + EXPECT_NE(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height()); + } else { + EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + } RemoveNotification(kNotificationId2, false); GetMessageCenterView()->SizeToPreferredSize(); - EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + if (features::IsLockScreenNotificationsEnabled()) + EXPECT_EQ(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height()); + else + EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); AddNotification(std::make_unique<Notification>( NOTIFICATION_TYPE_SIMPLE, std::string(kNotificationId1), @@ -898,13 +946,26 @@ base::UTF8ToUTF16("display source"), GURL(), NotifierId(NotifierId::APPLICATION, "extension_id"), message_center::RichNotificationData(), nullptr)); - EXPECT_FALSE(GetNotificationView(kNotificationId1)->IsDrawn()); + if (features::IsLockScreenNotificationsEnabled()) + EXPECT_TRUE(GetNotificationView(kNotificationId1)->IsDrawn()); + else + EXPECT_FALSE(GetNotificationView(kNotificationId1)->IsDrawn()); GetMessageCenterView()->SizeToPreferredSize(); - EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + if (features::IsLockScreenNotificationsEnabled()) { + EXPECT_NE(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + EXPECT_NE(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height()); + } else { + EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + } - EXPECT_FALSE(close_button->visible()); - EXPECT_FALSE(quiet_mode_button->visible()); + if (features::IsLockScreenNotificationsEnabled()) { + EXPECT_TRUE(close_button->visible()); + EXPECT_TRUE(quiet_mode_button->visible()); + } else { + EXPECT_FALSE(close_button->visible()); + EXPECT_FALSE(quiet_mode_button->visible()); + } EXPECT_FALSE(settings_button->visible()); EXPECT_FALSE(collapse_button->visible()); @@ -915,6 +976,7 @@ GetMessageCenterView()->SizeToPreferredSize(); EXPECT_NE(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + EXPECT_NE(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height()); EXPECT_TRUE(close_button->visible()); EXPECT_TRUE(quiet_mode_button->visible()); @@ -923,21 +985,31 @@ // Lock! SetLockedState(true); - EXPECT_FALSE(GetNotificationView(kNotificationId1)->IsDrawn()); + if (features::IsLockScreenNotificationsEnabled()) + EXPECT_TRUE(GetNotificationView(kNotificationId1)->IsDrawn()); + else + EXPECT_FALSE(GetNotificationView(kNotificationId1)->IsDrawn()); GetMessageCenterView()->SizeToPreferredSize(); - EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + if (features::IsLockScreenNotificationsEnabled()) { + EXPECT_NE(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + EXPECT_NE(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height()); + } else { + EXPECT_EQ(kLockedMessageCenterViewHeight, GetMessageCenterView()->height()); + } - EXPECT_FALSE(close_button->visible()); - EXPECT_FALSE(quiet_mode_button->visible()); + if (features::IsLockScreenNotificationsEnabled()) { + EXPECT_TRUE(close_button->visible()); + EXPECT_TRUE(quiet_mode_button->visible()); + } else { + EXPECT_FALSE(close_button->visible()); + EXPECT_FALSE(quiet_mode_button->visible()); + } EXPECT_FALSE(settings_button->visible()); EXPECT_FALSE(collapse_button->visible()); } -TEST_F(MessageCenterViewTest, NoNotification) { - // Plain button bar height (56) + Empty view (96) - const int kEmptyMessageCenterViewHeight = 152; - +TEST_P(MessageCenterViewTest, NoNotification) { GetMessageCenterView()->SizeToPreferredSize(); EXPECT_NE(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height()); RemoveNotification(kNotificationId1, false); @@ -958,4 +1030,8 @@ EXPECT_NE(kEmptyMessageCenterViewHeight, GetMessageCenterView()->height()); } +INSTANTIATE_TEST_CASE_P(IsLockScreenNotificationsEnabled, + MessageCenterViewTest, + testing::Bool()); + } // namespace ash
diff --git a/ash/public/cpp/ash_features.cc b/ash/public/cpp/ash_features.cc index cebb067..a335c2e 100644 --- a/ash/public/cpp/ash_features.cc +++ b/ash/public/cpp/ash_features.cc
@@ -19,6 +19,9 @@ const base::Feature kSystemTrayUnified{"SystemTrayUnified", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kLockScreenNotifications{"LockScreenNotifications", + base::FEATURE_DISABLED_BY_DEFAULT}; + bool IsDockedMagnifierEnabled() { return base::FeatureList::IsEnabled(kDockedMagnifier); } @@ -35,5 +38,9 @@ return base::FeatureList::IsEnabled(kSystemTrayUnified); } +bool IsLockScreenNotificationsEnabled() { + return base::FeatureList::IsEnabled(kLockScreenNotifications); +} + } // namespace features } // namespace ash
diff --git a/ash/public/cpp/ash_features.h b/ash/public/cpp/ash_features.h index ccc0974..55a4366 100644 --- a/ash/public/cpp/ash_features.h +++ b/ash/public/cpp/ash_features.h
@@ -29,6 +29,9 @@ // Enables new system menu. ASH_PUBLIC_EXPORT extern const base::Feature kSystemTrayUnified; +// Enables notifications on the lock screen. +ASH_PUBLIC_EXPORT extern const base::Feature kLockScreenNotifications; + ASH_PUBLIC_EXPORT bool IsDockedMagnifierEnabled(); ASH_PUBLIC_EXPORT bool IsKeyboardShortcutViewerEnabled(); @@ -37,6 +40,8 @@ ASH_PUBLIC_EXPORT bool IsSystemTrayUnifiedEnabled(); +ASH_PUBLIC_EXPORT bool IsLockScreenNotificationsEnabled(); + } // namespace features } // namespace ash
diff --git a/ash/system/web_notification/session_state_notification_blocker.cc b/ash/system/web_notification/session_state_notification_blocker.cc index 97919f2..e01c4b3 100644 --- a/ash/system/web_notification/session_state_notification_blocker.cc +++ b/ash/system/web_notification/session_state_notification_blocker.cc
@@ -4,6 +4,7 @@ #include "ash/system/web_notification/session_state_notification_blocker.h" +#include "ash/public/cpp/ash_features.h" #include "ash/session/session_controller.h" #include "ash/shell.h" #include "ui/message_center/message_center.h" @@ -19,7 +20,8 @@ Shell::Get()->session_controller(); return !session_controller->IsRunningInAppMode() && - !session_controller->IsScreenLocked(); + (!session_controller->IsScreenLocked() || + features::IsLockScreenNotificationsEnabled()); } bool CalculateShouldShowPopup() {
diff --git a/ash/wm/window_positioner.cc b/ash/wm/window_positioner.cc index a40a557..880eaa2 100644 --- a/ash/wm/window_positioner.cc +++ b/ash/wm/window_positioner.cc
@@ -34,9 +34,6 @@ // WindowPositioner::SetIgnoreActivations(). static bool disable_auto_positioning = false; -// If set to true, by default the first window in ASH will be maximized. -static bool maximize_first_window = false; - // Check if any management should be performed (with a given |window|). bool UseAutoWindowManager(const aura::Window* window) { if (disable_auto_positioning) @@ -240,7 +237,6 @@ // We want to always open maximized on "small screens" or when policy // tells us to. const bool set_maximized = - maximize_first_window || ((work_area.width() <= GetForceMaximizedWidthLimit() || maximize_first_window_on_first_run) && (!new_window || !wm::GetWindowState(new_window)->IsFullscreen())); @@ -414,11 +410,6 @@ return NormalPopupPosition(popup_size, work_area); } -// static -void WindowPositioner::SetMaximizeFirstWindow(bool maximize) { - maximize_first_window = maximize; -} - gfx::Rect WindowPositioner::NormalPopupPosition(const gfx::Size& popup_size, const gfx::Rect& work_area) { int w = popup_size.width();
diff --git a/ash/wm/window_positioner.h b/ash/wm/window_positioner.h index fe8ce9c..e0aa78e 100644 --- a/ash/wm/window_positioner.h +++ b/ash/wm/window_positioner.h
@@ -66,10 +66,6 @@ // operating systems do (default cascading style). gfx::Rect GetPopupPosition(const gfx::Size& popup_size); - // Accessor to set a flag indicating whether the first window in ASH should - // be maximized. - static void SetMaximizeFirstWindow(bool maximize); - protected: friend class WindowPositionerTest;
diff --git a/base/android/build_info.cc b/base/android/build_info.cc index 1d26a090..80800ea 100644 --- a/base/android/build_info.cc +++ b/base/android/build_info.cc
@@ -61,16 +61,18 @@ model_(StrDupParam(params, 4)), sdk_int_(SdkIntParam(params, 5)), build_type_(StrDupParam(params, 6)), - package_label_(StrDupParam(params, 7)), - package_name_(StrDupParam(params, 8)), - package_version_code_(StrDupParam(params, 9)), - package_version_name_(StrDupParam(params, 10)), - android_build_fp_(StrDupParam(params, 11)), - gms_version_code_(StrDupParam(params, 12)), - installer_package_name_(StrDupParam(params, 13)), - abi_name_(StrDupParam(params, 14)), - firebase_app_id_(StrDupParam(params, 15)), - extracted_file_suffix_(params[16]), + host_package_name_(StrDupParam(params, 7)), + host_version_code_(StrDupParam(params, 8)), + host_package_label_(StrDupParam(params, 9)), + package_name_(StrDupParam(params, 10)), + package_version_code_(StrDupParam(params, 11)), + package_version_name_(StrDupParam(params, 12)), + android_build_fp_(StrDupParam(params, 13)), + gms_version_code_(StrDupParam(params, 14)), + installer_package_name_(StrDupParam(params, 15)), + abi_name_(StrDupParam(params, 16)), + firebase_app_id_(StrDupParam(params, 17)), + extracted_file_suffix_(params[18]), java_exception_info_(NULL) {} // static
diff --git a/base/android/build_info.h b/base/android/build_info.h index e8cf555e..4daca9c4 100644 --- a/base/android/build_info.h +++ b/base/android/build_info.h
@@ -82,6 +82,12 @@ return gms_version_code_; } + const char* host_package_name() const { return host_package_name_; } + + const char* host_version_code() const { return host_version_code_; } + + const char* host_package_label() const { return host_package_label_; } + const char* package_version_code() const { return package_version_code_; } @@ -90,10 +96,6 @@ return package_version_name_; } - const char* package_label() const { - return package_label_; - } - const char* package_name() const { return package_name_; } @@ -139,7 +141,9 @@ const char* const model_; const int sdk_int_; const char* const build_type_; - const char* const package_label_; + const char* const host_package_name_; + const char* const host_version_code_; + const char* const host_package_label_; const char* const package_name_; const char* const package_version_code_; const char* const package_version_name_;
diff --git a/base/android/java/src/org/chromium/base/BuildInfo.java b/base/android/java/src/org/chromium/base/BuildInfo.java index 5c2a062..b32e288 100644 --- a/base/android/java/src/org/chromium/base/BuildInfo.java +++ b/base/android/java/src/org/chromium/base/BuildInfo.java
@@ -4,6 +4,7 @@ package org.chromium.base; +import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; @@ -18,112 +19,116 @@ * primarily of use for accessing package information from native code. */ public class BuildInfo { - /** - * Array index to access field in {@link BuildInfo#getAll()}. - */ - public static final int BRAND_INDEX = 0; - public static final int DEVICE_INDEX = 1; - public static final int ANDROID_BUILD_ID_INDEX = 2; - public static final int MODEL_INDEX = 4; - public static final int ANDROID_BUILD_FP_INDEX = 11; - public static final int GMS_CORE_VERSION_INDEX = 12; - public static final int INSTALLER_PACKAGE_NAME_INDEX = 13; - public static final int ABI_NAME_INDEX = 14; - private static final String TAG = "BuildInfo"; private static final int MAX_FINGERPRINT_LENGTH = 128; - /** - * BuildInfo is a static utility class and therefore shouldn't be instantiated. - */ - private BuildInfo() {} + private static PackageInfo sBrowserPackageInfo; + private static boolean sInitialized; - @SuppressWarnings("deprecation") + /** The application name (e.g. "Chrome"). For WebView, this is name of the embedding app. */ + public final String hostPackageLabel; + /** By default: same as versionCode. For WebView: versionCode of the embedding app. */ + public final int hostVersionCode; + /** The packageName of Chrome/WebView. Use application context for host app packageName. */ + public final String packageName; + /** The versionCode of the apk. */ + public final int versionCode; + /** The versionName of Chrome/WebView. Use application context for host app versionName. */ + public final String versionName; + /** Result of PackageManager.getInstallerPackageName(). Never null, but may be "". */ + public final String installerPackageName; + /** The versionCode of Play Services (for crash reporting). */ + public final String gmsVersionCode; + /** Formatted ABI string (for crash reporting). */ + public final String abiString; + /** Truncated version of Build.FINGERPRINT (for crash reporting). */ + public final String androidBuildFingerprint; + /** A string that is different each time the apk changes. */ + public final String extractedFileSuffix; + + private static class Holder { private static BuildInfo sInstance = new BuildInfo(); } + @CalledByNative - public static String[] getAll() { + private static String[] getAll() { + BuildInfo buildInfo = getInstance(); + String hostPackageName = ContextUtils.getApplicationContext().getPackageName(); + return new String[] { + Build.BRAND, Build.DEVICE, Build.ID, Build.MANUFACTURER, Build.MODEL, + String.valueOf(Build.VERSION.SDK_INT), Build.TYPE, hostPackageName, + String.valueOf(buildInfo.hostVersionCode), buildInfo.hostPackageLabel, + buildInfo.packageName, String.valueOf(buildInfo.versionCode), buildInfo.versionName, + buildInfo.androidBuildFingerprint, buildInfo.gmsVersionCode, + buildInfo.installerPackageName, buildInfo.abiString, BuildConfig.FIREBASE_APP_ID, + buildInfo.extractedFileSuffix, + }; + } + + /** + * @param packageInfo Package for Chrome/WebView (as opposed to host app). + */ + public static void setBrowserPackageInfo(PackageInfo packageInfo) { + assert !sInitialized; + sBrowserPackageInfo = packageInfo; + } + + public static BuildInfo getInstance() { + return Holder.sInstance; + } + + private BuildInfo() { + sInitialized = true; try { - String packageName = ContextUtils.getApplicationContext().getPackageName(); - PackageManager pm = ContextUtils.getApplicationContext().getPackageManager(); - PackageInfo pi = pm.getPackageInfo(packageName, 0); - String versionCode = pi.versionCode <= 0 ? "" : Integer.toString(pi.versionCode); - String versionName = pi.versionName == null ? "" : pi.versionName; - - CharSequence label = pm.getApplicationLabel(pi.applicationInfo); - String packageLabel = label == null ? "" : label.toString(); - - String installerPackageName = pm.getInstallerPackageName(packageName); - if (installerPackageName == null) { - installerPackageName = ""; + Context appContext = ContextUtils.getApplicationContext(); + String hostPackageName = appContext.getPackageName(); + PackageManager pm = appContext.getPackageManager(); + PackageInfo pi = pm.getPackageInfo(hostPackageName, 0); + hostVersionCode = pi.versionCode; + if (sBrowserPackageInfo != null) { + packageName = sBrowserPackageInfo.packageName; + versionCode = sBrowserPackageInfo.versionCode; + versionName = sBrowserPackageInfo.versionName; + sBrowserPackageInfo = null; + } else { + packageName = hostPackageName; + versionCode = hostVersionCode; + versionName = pi.versionName; } - String abiString = null; + CharSequence label = pm.getApplicationLabel(pi.applicationInfo); + hostPackageLabel = label == null ? "" : label.toString(); + + String value = pm.getInstallerPackageName(packageName); + installerPackageName = value == null ? "" : value; + + PackageInfo gmsPackageInfo = null; + try { + gmsPackageInfo = pm.getPackageInfo("com.google.android.gms", 0); + } catch (NameNotFoundException e) { + Log.d(TAG, "GMS package is not found.", e); + } + gmsVersionCode = gmsPackageInfo != null ? String.valueOf(gmsPackageInfo.versionCode) + : "gms versionCode not available."; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { abiString = TextUtils.join(", ", Build.SUPPORTED_ABIS); } else { - abiString = "ABI1: " + Build.CPU_ABI + ", ABI2: " + Build.CPU_ABI2; + abiString = String.format("ABI1: %s, ABI2: %s", Build.CPU_ABI, Build.CPU_ABI2); } // Use lastUpdateTime when developing locally, since versionCode does not normally // change in this case. - long version = pi.versionCode > 10 ? pi.versionCode : pi.lastUpdateTime; - String extractedFileSuffix = String.format("@%s", Long.toHexString(version)); + long version = versionCode > 10 ? versionCode : pi.lastUpdateTime; + extractedFileSuffix = String.format("@%x", version); - // Do not alter this list without updating callers of it. - return new String[] { - Build.BRAND, Build.DEVICE, Build.ID, Build.MANUFACTURER, Build.MODEL, - String.valueOf(Build.VERSION.SDK_INT), Build.TYPE, packageLabel, packageName, - versionCode, versionName, getAndroidBuildFingerprint(), getGMSVersionCode(pm), - installerPackageName, abiString, BuildConfig.FIREBASE_APP_ID, - extractedFileSuffix, - }; + // The value is truncated, as this is used for crash and UMA reporting. + androidBuildFingerprint = Build.FINGERPRINT.substring( + 0, Math.min(Build.FINGERPRINT.length(), MAX_FINGERPRINT_LENGTH)); } catch (NameNotFoundException e) { throw new RuntimeException(e); } } /** - * @return The build fingerprint for the current Android install. The value is truncated to a - * 128 characters as this is used for crash and UMA reporting, which should avoid huge - * strings. - */ - private static String getAndroidBuildFingerprint() { - return Build.FINGERPRINT.substring( - 0, Math.min(Build.FINGERPRINT.length(), MAX_FINGERPRINT_LENGTH)); - } - - private static String getGMSVersionCode(PackageManager packageManager) { - String msg = "gms versionCode not available."; - try { - PackageInfo packageInfo = packageManager.getPackageInfo("com.google.android.gms", 0); - msg = Integer.toString(packageInfo.versionCode); - } catch (NameNotFoundException e) { - Log.d(TAG, "GMS package is not found.", e); - } - return msg; - } - - public static String getPackageVersionCode() { - return getAll()[9]; - } - - public static String getPackageVersionName() { - return getAll()[10]; - } - - /** Returns a string that is different each time the apk changes. */ - public static String getExtractedFileSuffix() { - return getAll()[16]; - } - - public static String getPackageLabel() { - return getAll()[7]; - } - - public static String getPackageName() { - return ContextUtils.getApplicationContext().getPackageName(); - } - - /** * Check if this is a debuggable build of Android. Use this to enable developer-only features. */ public static boolean isDebugAndroid() {
diff --git a/base/android/java/src/org/chromium/base/ResourceExtractor.java b/base/android/java/src/org/chromium/base/ResourceExtractor.java index 6f6a84c..fbb703b 100644 --- a/base/android/java/src/org/chromium/base/ResourceExtractor.java +++ b/base/android/java/src/org/chromium/base/ResourceExtractor.java
@@ -64,7 +64,7 @@ // Use a suffix for extracted files in order to guarantee that the version of the file // on disk matches up with the version of the APK. - String extractSuffix = BuildInfo.getExtractedFileSuffix(); + String extractSuffix = BuildInfo.getInstance().extractedFileSuffix; String[] existingFileNames = outputDir.list(); boolean allFilesExist = existingFileNames != null; if (allFilesExist) {
diff --git a/base/android/library_loader/library_prefetcher.cc b/base/android/library_loader/library_prefetcher.cc index dda25778..fefbb5e 100644 --- a/base/android/library_loader/library_prefetcher.cc +++ b/base/android/library_loader/library_prefetcher.cc
@@ -184,9 +184,9 @@ // static bool NativeLibraryPrefetcher::ForkAndPrefetchNativeLibrary() { - // Avoid forking with cygprofile instrumentation because the latter performs - // memory allocations. #if defined(CYGPROFILE_INSTRUMENTATION) + // Avoid forking with cygprofile instrumentation because the child process + // would create a dump as well. return false; #endif
diff --git a/base/strings/strcat.h b/base/strings/strcat.h index b249d49..44c6211 100644 --- a/base/strings/strcat.h +++ b/base/strings/strcat.h
@@ -11,6 +11,12 @@ #include "base/compiler_specific.h" #include "base/containers/span.h" #include "base/strings/string_piece.h" +#include "build/build_config.h" + +#if defined(OS_WIN) +// To resolve a conflict with Win32 API StrCat macro. +#include "base/win/windows_types.h" +#endif namespace base {
diff --git a/base/strings/string_piece.h b/base/strings/string_piece.h index 0362381..d6236d1 100644 --- a/base/strings/string_piece.h +++ b/base/strings/string_piece.h
@@ -219,31 +219,16 @@ length_ = str ? STRING_TYPE::traits_type::length(str) : 0; } - constexpr value_type operator[](size_type i) const { - CHECK(i < length_); - return ptr_[i]; - } - - value_type front() const { - CHECK_NE(0UL, length_); - return ptr_[0]; - } - - value_type back() const { - CHECK_NE(0UL, length_); - return ptr_[length_ - 1]; - } + constexpr value_type operator[](size_type i) const { return ptr_[i]; } + value_type front() const { return ptr_[0]; } + value_type back() const { return ptr_[length_ - 1]; } constexpr void remove_prefix(size_type n) { - CHECK(n <= length_); ptr_ += n; length_ -= n; } - constexpr void remove_suffix(size_type n) { - CHECK(n <= length_); - length_ -= n; - } + constexpr void remove_suffix(size_type n) { length_ -= n; } int compare(const BasicStringPiece<STRING_TYPE>& x) const { int r = wordmemcmp( @@ -372,7 +357,7 @@ protected: const value_type* ptr_; - size_type length_; + size_type length_; }; template <typename STRING_TYPE>
diff --git a/base/trace_event/auto_open_close_event.cc b/base/trace_event/auto_open_close_event.cc index f2794f4..1879700 100644 --- a/base/trace_event/auto_open_close_event.cc +++ b/base/trace_event/auto_open_close_event.cc
@@ -28,7 +28,7 @@ void AutoOpenCloseEvent::Begin() { DCHECK(thread_checker_.CalledOnValidThread()); - start_time_ = base::TimeTicks::Now(); + start_time_ = TRACE_TIME_TICKS_NOW(); TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0( category_, event_name_, static_cast<void*>(this), start_time_); } @@ -49,4 +49,4 @@ void AutoOpenCloseEvent::OnTraceLogDisabled() {} } // namespace trace_event -} // namespace base \ No newline at end of file +} // namespace base
diff --git a/base/trace_event/common/trace_event_common.h b/base/trace_event/common/trace_event_common.h index 51869ee9..8f0e7ba 100644 --- a/base/trace_event/common/trace_event_common.h +++ b/base/trace_event/common/trace_event_common.h
@@ -1020,6 +1020,14 @@ } \ } while (0) +// Macro for getting the real base::TimeTicks::Now() which can be overridden in +// headless when VirtualTime is enabled. +#define TRACE_TIME_TICKS_NOW() INTERNAL_TRACE_TIME_TICKS_NOW() + +// Macro for getting the real base::Time::Now() which can be overridden in +// headless when VirtualTime is enabled. +#define TRACE_TIME_NOW() INTERNAL_TRACE_TIME_NOW() + // Notes regarding the following definitions: // New values can be added and propagated to third party libraries, but existing // definitions must never be changed, because third party libraries may use old
diff --git a/base/trace_event/trace_event.h b/base/trace_event/trace_event.h index d1f3fc6..38528aa 100644 --- a/base/trace_event/trace_event.h +++ b/base/trace_event/trace_event.h
@@ -18,6 +18,7 @@ #include "base/debug/debugging_buildflags.h" #include "base/macros.h" #include "base/time/time.h" +#include "base/time/time_override.h" #include "base/trace_event/common/trace_event_common.h" #include "base/trace_event/heap_profiler.h" #include "base/trace_event/trace_category.h" @@ -249,6 +250,17 @@ INTERNAL_TRACE_EVENT_UID(atomic), \ INTERNAL_TRACE_EVENT_UID(category_group_enabled)); +// Implementation detail: internal macro to return unoverridden +// base::TimeTicks::Now(). This is important because in headless VirtualTime can +// override base:TimeTicks::Now(). +#define INTERNAL_TRACE_TIME_TICKS_NOW() \ + base::subtle::TimeTicksNowIgnoringOverride() + +// Implementation detail: internal macro to return unoverridden +// base::Time::Now(). This is important because in headless VirtualTime can +// override base:TimeTicks::Now(). +#define INTERNAL_TRACE_TIME_NOW() base::subtle::TimeNowIgnoringOverride() + // Implementation detail: internal macro to create static category and add // event if the category is enabled. #define INTERNAL_TRACE_EVENT_ADD(phase, category_group, name, flags, ...) \ @@ -878,7 +890,7 @@ unsigned int flags, unsigned long long bind_id) { const int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); - const base::TimeTicks now = base::TimeTicks::Now(); + const base::TimeTicks now = TRACE_TIME_TICKS_NOW(); return AddTraceEventWithThreadIdAndTimestamp( phase, category_group_enabled, name, scope, id, thread_id, now, flags, bind_id); @@ -919,7 +931,7 @@ const char* arg1_name, const ARG1_TYPE& arg1_val) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); return AddTraceEventWithThreadIdAndTimestamp( phase, category_group_enabled, name, scope, id, thread_id, now, flags, bind_id, arg1_name, arg1_val); @@ -937,7 +949,7 @@ const char* arg1_name, std::unique_ptr<ARG1_CONVERTABLE_TYPE> arg1_val) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); return AddTraceEventWithThreadIdAndTimestamp( phase, category_group_enabled, name, scope, id, thread_id, now, flags, bind_id, arg1_name, std::move(arg1_val)); @@ -984,7 +996,7 @@ const char* arg2_name, const ARG2_TYPE& arg2_val) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); return AddTraceEventWithThreadIdAndTimestamp( phase, category_group_enabled, name, scope, id, thread_id, now, flags, bind_id, arg1_name, std::move(arg1_val), arg2_name, arg2_val); @@ -1004,7 +1016,7 @@ const char* arg2_name, std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); return AddTraceEventWithThreadIdAndTimestamp( phase, category_group_enabled, name, scope, id, thread_id, now, flags, bind_id, arg1_name, arg1_val, arg2_name, std::move(arg2_val)); @@ -1024,7 +1036,7 @@ const char* arg2_name, std::unique_ptr<ARG2_CONVERTABLE_TYPE> arg2_val) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); return AddTraceEventWithThreadIdAndTimestamp( phase, category_group_enabled, name, scope, id, thread_id, now, flags, bind_id, arg1_name, std::move(arg1_val), arg2_name, std::move(arg2_val)); @@ -1044,7 +1056,7 @@ const char* arg2_name, const ARG2_TYPE& arg2_val) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); return AddTraceEventWithThreadIdAndTimestamp( phase, category_group_enabled, name, scope, id, thread_id, now, flags, bind_id, arg1_name, arg1_val, arg2_name, arg2_val);
diff --git a/base/trace_event/trace_event_android.cc b/base/trace_event/trace_event_android.cc index 0a4e6ea..30d9c74 100644 --- a/base/trace_event/trace_event_android.cc +++ b/base/trace_event/trace_event_android.cc
@@ -205,7 +205,7 @@ // debugfs that takes the written data and pushes it onto the trace // buffer. So, to establish clock sync, we write our monotonic clock into that // trace buffer. - double now_in_seconds = (TimeTicks::Now() - TimeTicks()).InSecondsF(); + double now_in_seconds = (TRACE_TIME_TICKS_NOW() - TimeTicks()).InSecondsF(); std::string marker = StringPrintf( "trace_event_clock_sync: parent_ts=%f\n", now_in_seconds); WriteToATrace(atrace_fd, marker.c_str(), marker.size());
diff --git a/base/trace_event/trace_log.cc b/base/trace_event/trace_log.cc index 718383b0..578bbde0 100644 --- a/base/trace_event/trace_log.cc +++ b/base/trace_event/trace_log.cc
@@ -85,7 +85,9 @@ } ThreadTicks ThreadNow() { - return ThreadTicks::IsSupported() ? ThreadTicks::Now() : ThreadTicks(); + return ThreadTicks::IsSupported() + ? base::subtle::ThreadTicksNowIgnoringOverride() + : ThreadTicks(); } template <typename T> @@ -369,7 +371,7 @@ process_creation_time_ = CurrentProcessInfo::CreationTime(); #else // Use approximate time when creation time is not available. - process_creation_time_ = Time::Now(); + process_creation_time_ = TRACE_TIME_NOW(); #endif logged_events_.reset(CreateTraceBuffer()); @@ -1031,7 +1033,7 @@ std::unique_ptr<ConvertableToTraceFormat>* convertable_values, unsigned int flags) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); return AddTraceEventWithThreadIdAndTimestamp( phase, category_group_enabled, @@ -1063,7 +1065,7 @@ std::unique_ptr<ConvertableToTraceFormat>* convertable_values, unsigned int flags) { int thread_id = static_cast<int>(base::PlatformThread::CurrentId()); - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); return AddTraceEventWithThreadIdAndTimestamp( phase, category_group_enabled, @@ -1094,7 +1096,7 @@ const unsigned long long* arg_values, std::unique_ptr<ConvertableToTraceFormat>* convertable_values, unsigned int flags) { - base::TimeTicks now = base::TimeTicks::Now(); + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); return AddTraceEventWithThreadIdAndTimestamp( phase, category_group_enabled, @@ -1493,7 +1495,7 @@ current_thread_id, "process_name", "name", process_name_); } - TimeDelta process_uptime = Time::Now() - process_creation_time_; + TimeDelta process_uptime = TRACE_TIME_NOW() - process_creation_time_; InitializeMetadataEvent( AddEventToThreadSharedChunkWhileLocked(nullptr, false), current_thread_id, "process_uptime_seconds", "uptime", process_uptime.InSeconds()); @@ -1701,19 +1703,12 @@ if (*category_group_enabled_) { event_handle_ = TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP( - TRACE_EVENT_PHASE_COMPLETE, - category_group_enabled_, - name, - trace_event_internal::kGlobalScope, // scope - trace_event_internal::kNoId, // id + TRACE_EVENT_PHASE_COMPLETE, category_group_enabled_, name, + trace_event_internal::kGlobalScope, // scope + trace_event_internal::kNoId, // id static_cast<int>(base::PlatformThread::CurrentId()), // thread_id - base::TimeTicks::Now(), - trace_event_internal::kZeroNumArgs, - nullptr, - nullptr, - nullptr, - nullptr, - TRACE_EVENT_FLAG_NONE); + TRACE_TIME_TICKS_NOW(), trace_event_internal::kZeroNumArgs, nullptr, + nullptr, nullptr, nullptr, TRACE_EVENT_FLAG_NONE); } }
diff --git a/base/trace_event/trace_log.h b/base/trace_event/trace_log.h index b8041d4d..06c5848 100644 --- a/base/trace_event/trace_log.h +++ b/base/trace_event/trace_log.h
@@ -17,6 +17,7 @@ #include "base/containers/stack.h" #include "base/gtest_prod_util.h" #include "base/macros.h" +#include "base/time/time_override.h" #include "base/trace_event/memory_dump_provider.h" #include "base/trace_event/trace_config.h" #include "base/trace_event/trace_event_impl.h" @@ -431,7 +432,10 @@ } void UseNextTraceBuffer(); - TimeTicks OffsetNow() const { return OffsetTimestamp(TimeTicks::Now()); } + TimeTicks OffsetNow() const { + // This should be TRACE_TIME_TICKS_NOW but include order makes that hard. + return OffsetTimestamp(base::subtle::TimeTicksNowIgnoringOverride()); + } TimeTicks OffsetTimestamp(const TimeTicks& timestamp) const { return timestamp - time_offset_; }
diff --git a/base/win/windows_types.h b/base/win/windows_types.h index 8060f03..2a86195f 100644 --- a/base/win/windows_types.h +++ b/base/win/windows_types.h
@@ -248,5 +248,6 @@ #define SendMessageCallback SendMessageCallbackW #define SetCurrentDirectory SetCurrentDirectoryW #define StartService StartServiceW +#define StrCat StrCatW #endif // BASE_WIN_WINDOWS_TYPES_H
diff --git a/build/android/pylib/base/output_manager.py b/build/android/pylib/base/output_manager.py index 5606e7a..b4dd018f 100644 --- a/build/android/pylib/base/output_manager.py +++ b/build/android/pylib/base/output_manager.py
@@ -14,6 +14,7 @@ HTML = 'html' IMAGE = 'image' TEXT = 'text' + JSON = 'json' class OutputManager(object):
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py index ddc80f7..3b6774057 100644 --- a/build/android/pylib/instrumentation/instrumentation_test_instance.py +++ b/build/android/pylib/instrumentation/instrumentation_test_instance.py
@@ -676,7 +676,6 @@ def _initializeTestControlAttributes(self, args): self._screenshot_dir = args.screenshot_dir self._timeout_scale = args.timeout_scale or 1 - self._ui_screenshot_dir = args.ui_screenshot_dir self._wait_for_java_debugger = args.wait_for_java_debugger def _initializeTestCoverageAttributes(self, args): @@ -809,10 +808,6 @@ return self._total_external_shards @property - def ui_screenshot_dir(self): - return self._ui_screenshot_dir - - @property def wait_for_java_debugger(self): return self._wait_for_java_debugger
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py index 664bb8d..b3517ba 100644 --- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py +++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -321,23 +321,9 @@ valgrind_tools.SetChromeTimeoutScale(dev, None) - if self._test_instance.ui_screenshot_dir: - pull_ui_screen_captures(dev) - if self._replace_package_contextmanager: self._replace_package_contextmanager.__exit__(*sys.exc_info()) - @trace_event.traced - def pull_ui_screen_captures(dev): - file_names = dev.ListDirectory(self._ui_capture_dir[dev]) - target_path = self._test_instance.ui_screenshot_dir - if not os.path.exists(target_path): - os.makedirs(target_path) - - for file_name in file_names: - dev.PullFile(posixpath.join(self._ui_capture_dir[dev], file_name), - target_path) - self._env.parallel_devices.pMap(individual_device_tear_down) def _CreateFlagChangerIfNeeded(self, device): @@ -530,12 +516,41 @@ device.RemovePath(render_tests_device_output_dir, recursive=True, force=True) + def pull_ui_screen_captures(): + screenshots = [] + for filename in device.ListDirectory(self._ui_capture_dir[device]): + if filename.endswith('.json'): + screenshots.append(pull_ui_screenshot(filename)) + if screenshots: + json_archive_name = 'ui_capture_%s_%s.json' % ( + test_name.replace('#', '.'), + time.strftime('%Y%m%dT%H%M%S-UTC', time.gmtime())) + with self._env.output_manager.ArchivedTempfile( + json_archive_name, 'ui_capture', output_manager.Datatype.JSON + ) as json_archive: + json.dump(screenshots, json_archive) + for result in results: + result.SetLink('ui screenshot', json_archive.Link()) + + def pull_ui_screenshot(filename): + source_dir = self._ui_capture_dir[device] + json_path = posixpath.join(source_dir, filename) + json_data = json.loads(device.ReadFile(json_path)) + image_file_path = posixpath.join(source_dir, json_data['location']) + with self._env.output_manager.ArchivedTempfile( + json_data['location'], 'ui_capture', output_manager.Datatype.IMAGE + ) as image_archive: + device.PullFile(image_file_path, image_archive.name) + json_data['image_link'] = image_archive.Link() + return json_data + # While constructing the TestResult objects, we can parallelize several # steps that involve ADB. These steps should NOT depend on any info in # the results! Things such as whether the test CRASHED have not yet been # determined. post_test_steps = [restore_flags, restore_timeout_scale, - handle_coverage_data, handle_render_test_data] + handle_coverage_data, handle_render_test_data, + pull_ui_screen_captures] if self._env.concurrent_adb: post_test_step_thread_group = reraiser_thread.ReraiserThreadGroup( reraiser_thread.ReraiserThread(f) for f in post_test_steps)
diff --git a/build/android/pylib/output/remote_output_manager.py b/build/android/pylib/output/remote_output_manager.py index 425f143..b726cb0 100644 --- a/build/android/pylib/output/remote_output_manager.py +++ b/build/android/pylib/output/remote_output_manager.py
@@ -66,7 +66,8 @@ def _PrepareArchive(self): self._content_addressed = (self._datatype in ( output_manager.Datatype.HTML, - output_manager.Datatype.IMAGE)) + output_manager.Datatype.IMAGE, + output_manager.Datatype.JSON)) if self._content_addressed: sha1 = hashlib.sha1() with open(self.name, 'rb') as f: @@ -87,5 +88,7 @@ content_type = None if self._datatype == output_manager.Datatype.HTML: content_type = 'text/html' + elif self._datatype == output_manager.Datatype.JSON: + content_type = 'application/json' google_storage_helper.upload( self._upload_path, self.name, self._bucket, content_type=content_type)
diff --git a/build/android/test_runner.py b/build/android/test_runner.py index 1789466d..97c31b8 100755 --- a/build/android/test_runner.py +++ b/build/android/test_runner.py
@@ -494,10 +494,6 @@ type=float, help='Factor by which timeouts should be scaled.') parser.add_argument( - '--ui-screenshot-directory', - dest='ui_screenshot_dir', type=os.path.realpath, - help='Destination for screenshots captured by the tests') - parser.add_argument( '-w', '--wait-for-java-debugger', action='store_true', help='Wait for java debugger to attach before running any application ' 'code. Also disables test timeouts and sets retries=0.')
diff --git a/build/config/android/BUILD.gn b/build/config/android/BUILD.gn index 4e73318..fabde6c 100644 --- a/build/config/android/BUILD.gn +++ b/build/config/android/BUILD.gn
@@ -216,11 +216,7 @@ config("cygprofile_instrumentation") { defines = [ "CYGPROFILE_INSTRUMENTATION=1" ] - if (use_lightweight_order_profiling) { - cflags = [ "-finstrument-function-entry-bare" ] - } else { - cflags = [ "-finstrument-functions-after-inlining" ] - } + cflags = [ "-finstrument-function-entry-bare" ] } config("no_cygprofile_instrumentation") {
diff --git a/build/config/android/abi.gni b/build/config/android/abi.gni index 24bef19..877c3f74 100644 --- a/build/config/android/abi.gni +++ b/build/config/android/abi.gni
@@ -12,11 +12,6 @@ # functions are called at startup. use_order_profiling = false - # Use a lightweight variant of order profiling. Does nothing without - # use_order_profiling set above. Will either replace use_order_profiling - # or be removed. - use_lightweight_order_profiling = false - # Builds secondary abi for APKs, supports build 32-bit arch as secondary # abi in 64-bit Monochrome and WebView. build_apk_secondary_abi = true
diff --git a/build/util/lastchange.py b/build/util/lastchange.py index 4467df7..9ade784 100755 --- a/build/util/lastchange.py +++ b/build/util/lastchange.py
@@ -46,7 +46,7 @@ return None -def FetchGitRevision(directory): +def FetchGitRevision(directory, filter): """ Fetch the Git hash (and Cr-Commit-Position if any) for a given directory. @@ -57,6 +57,8 @@ """ hsh = '' git_args = ['log', '-1', '--format=%H'] + if filter is not None: + git_args.append('--grep=' + filter) proc = RunGitCommand(directory, git_args) if proc: output = proc.communicate()[0].strip() @@ -76,12 +78,12 @@ return VersionInfo(hsh, '%s-%s' % (hsh, pos)) -def FetchVersionInfo(directory=None): +def FetchVersionInfo(directory=None, filter=None): """ Returns the last change (as a VersionInfo object) from some appropriate revision control system. """ - version_info = FetchGitRevision(directory) + version_info = FetchGitRevision(directory, filter) if not version_info: version_info = VersionInfo('0', '0') return version_info @@ -165,10 +167,16 @@ "file-output-related options.") parser.add_option("-s", "--source-dir", metavar="DIR", help="Use repository in the given directory.") + parser.add_option("", "--filter", metavar="REGEX", + help="Only use log entries where the commit message " + + "matches the supplied filter regex. Defaults to " + + "'^Change-Id:' to suppress local commits.", + default='^Change-Id:') opts, args = parser.parse_args(argv[1:]) out_file = opts.output header = opts.header + filter=opts.filter while len(args) and out_file is None: if out_file is None: @@ -183,7 +191,7 @@ else: src_dir = os.path.dirname(os.path.abspath(__file__)) - version_info = FetchVersionInfo(directory=src_dir) + version_info = FetchVersionInfo(directory=src_dir, filter=filter) revision_string = version_info.revision if opts.revision_id_only: revision_string = version_info.revision_id
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 5dd1cc2f..bdff8d3 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -40,8 +40,6 @@ [ "manifest_package=org.chromium.chrome.sync_shell" ] app_hooks_impl = "java/src/org/chromium/chrome/browser/AppHooksImpl.java" -class_register_impl = - "java/src/org/chromium/chrome/browser/ClassRegisterImpl.java" if (enable_resource_whitelist_generation) { monochrome_resource_whitelist = @@ -172,13 +170,6 @@ ] } -android_library("class_register_java") { - java_files = [ class_register_impl ] - deps = [ - ":chrome_java", - ] -} - android_aidl("photo_picker_aidl") { import_include = [ "java/src/org/chromium/chrome/browser/photo_picker" ] sources = [ @@ -331,10 +322,7 @@ android_manifest_for_lint = chrome_public_android_manifest # From java_sources.gni. - java_files = chrome_java_sources + [ - app_hooks_impl, - class_register_impl, - ] + java_files = chrome_java_sources + [ app_hooks_impl ] if (enable_vr) { java_files += chrome_vr_java_sources @@ -348,10 +336,7 @@ # Add the actual implementation where necessary so that downstream targets # can provide their own implementations. - jar_excluded_patterns = [ - "*/AppHooksImpl.class", - "*/ClassRegisterImpl.class", - ] + jar_excluded_patterns = [ "*/AppHooksImpl.class" ] } action("chrome_android_java_google_api_keys_srcjar") { @@ -432,7 +417,6 @@ ":app_hooks_java", ":chrome_java", ":chrome_java_resources", - ":class_register_java", ":partner_location_descriptor_proto_java", "$google_play_services_package:google_play_services_base_java", "$google_play_services_package:google_play_services_basement_java", @@ -520,7 +504,6 @@ "//base:base_java_test_support", "//chrome/android:app_hooks_java", "//chrome/android:chrome_java", - "//chrome/android:class_register_java", "//chrome/android/third_party/compositor_animator:compositor_animator_java", "//chrome/android/third_party/widget_bottomsheet_base:widget_bottomsheet_base_java", "//chrome/android/webapk/libs/client:client_java", @@ -672,7 +655,6 @@ "//base:base_java_test_support", "//chrome/android:app_hooks_java", "//chrome/android:chrome_java", - "//chrome/android:class_register_java", "//chrome/test/android:chrome_java_test_support", "//components/policy/android:policy_java", "//content/public/android:content_java", @@ -796,8 +778,8 @@ deps += [ "//tools/cygprofile" ] } - # See crbug.com/705088, crbug.com/717815. - if (target_cpu == "arm" && (is_asan || use_order_profiling)) { + # See crbug.com/705088. + if (target_cpu == "arm" && is_asan) { ldflags = [ "-Wl,--long-plt" ] } @@ -1076,7 +1058,6 @@ ":chrome_public_apk_resources", ":chrome_public_non_pak_assets", ":chrome_public_pak_assets", - ":class_register_java", "//base:base_java", ] } @@ -1143,7 +1124,6 @@ "//base:base_java", "//chrome/android:app_hooks_java", "//chrome/android:chrome_java", - "//chrome/android:class_register_java", ] } @@ -1295,7 +1275,6 @@ "//base:base_java_test_support", "//chrome/android:app_hooks_java", "//chrome/android:chrome_java", - "//chrome/android:class_register_java", "//chrome/test/android:chrome_java_test_support", "//components/bookmarks/common/android:bookmarks_java", "//components/policy/android:policy_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java index 294fa1e..254172a 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeFeatureList.java
@@ -156,6 +156,7 @@ public static final String CAPTIVE_PORTAL_CERTIFICATE_LIST = "CaptivePortalCertificateList"; public static final String CCT_BACKGROUND_TAB = "CCTBackgroundTab"; public static final String CCT_EXTERNAL_LINK_HANDLING = "CCTExternalLinkHandling"; + public static final String CCT_PARALLEL_REQUEST = "CCTParallelRequest"; public static final String CCT_POST_MESSAGE_API = "CCTPostMessageAPI"; public static final String CCT_REDIRECT_PRECONNECT = "CCTRedirectPreconnect"; public static final String CHROME_DUPLEX = "ChromeDuplex";
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ClassRegister.java b/chrome/android/java/src/org/chromium/chrome/browser/ClassRegister.java deleted file mode 100644 index 4dd3709..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ClassRegister.java +++ /dev/null
@@ -1,28 +0,0 @@ -// 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; - -/** - * Base class for defining methods where different behavior is required by downstream targets. - * The difference to AppHooks is we need to upstream changes here later. - */ -public abstract class ClassRegister { - private static ClassRegisterImpl sInstance; - - public static ClassRegister get() { - if (sInstance == null) { - sInstance = new ClassRegisterImpl(); - } - return sInstance; - } - - /** - * Register the {@link ContentClassFactory} so {@link SelectionInsertionHandleObserver} can be - * set properly. - */ - public void registerContentClassFactory() { - /* no-op */ - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ClassRegisterImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/ClassRegisterImpl.java deleted file mode 100644 index 8a68212..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/ClassRegisterImpl.java +++ /dev/null
@@ -1,11 +0,0 @@ -// 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; - -/** - * Implementation of {@link ClassRegister}, don't add anything to this class. - * Downstream targets may provide a different implemenation. - */ -public class ClassRegisterImpl extends ClassRegister {}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java index acc71f7e..41cc1bff 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
@@ -92,8 +92,8 @@ Context context = ContextUtils.getApplicationContext(); ArrayList<String> menuTitles = new ArrayList<String>(2); // Store the package label of current application. - menuTitles.add( - getTitleFromPackageLabel(context, BuildInfo.getPackageLabel())); + menuTitles.add(getTitleFromPackageLabel( + context, BuildInfo.getInstance().hostPackageLabel)); PackageManager pm = context.getPackageManager(); ResolveInfo info = getResolveInfoForViewIntent(pm);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java index bb8c863..57d96de28 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java
@@ -95,7 +95,7 @@ createSnackbarControllerForEditButton(activity, bookmarkId); if (getLastUsedParent(activity) == null) { if (fromCustomTab) { - String packageLabel = BuildInfo.getPackageLabel(); + String packageLabel = BuildInfo.getInstance().hostPackageLabel; snackbar = Snackbar.make( activity.getString(R.string.bookmark_page_saved, packageLabel), snackbarController, Snackbar.TYPE_ACTION, Snackbar.UMA_BOOKMARK_ADDED);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java index 5bfee3d..9a9e8fd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionReporter.java
@@ -7,6 +7,7 @@ import android.app.ActivityManager; import android.app.ActivityManager.RunningAppProcessInfo; import android.content.Context; +import android.os.Build; import android.util.Log; import org.chromium.base.ApiCompatibilityUtils; @@ -116,24 +117,24 @@ processName = "browser"; } - String[] allInfo = BuildInfo.getAll(); + BuildInfo buildInfo = BuildInfo.getInstance(); addPairedString(PRODUCT, "Chrome_Android"); addPairedString(PROCESS_TYPE, processName); - addPairedString(DEVICE, allInfo[BuildInfo.DEVICE_INDEX]); + addPairedString(DEVICE, Build.DEVICE); addPairedString(VERSION, ChromeVersionInfo.getProductVersion()); addPairedString(CHANNEL, getChannel()); - addPairedString(ANDROID_BUILD_ID, allInfo[BuildInfo.ANDROID_BUILD_ID_INDEX]); - addPairedString(MODEL, allInfo[BuildInfo.MODEL_INDEX]); - addPairedString(BRAND, allInfo[BuildInfo.BRAND_INDEX]); - addPairedString(ANDROID_BUILD_FP, allInfo[BuildInfo.ANDROID_BUILD_FP_INDEX]); - addPairedString(GMS_CORE_VERSION, allInfo[BuildInfo.GMS_CORE_VERSION_INDEX]); - addPairedString(INSTALLER_PACKAGE_NAME, allInfo[BuildInfo.INSTALLER_PACKAGE_NAME_INDEX]); - addPairedString(ABI_NAME, allInfo[BuildInfo.ABI_NAME_INDEX]); + addPairedString(ANDROID_BUILD_ID, Build.ID); + addPairedString(MODEL, Build.MODEL); + addPairedString(BRAND, Build.BRAND); + addPairedString(ANDROID_BUILD_FP, buildInfo.androidBuildFingerprint); + addPairedString(GMS_CORE_VERSION, buildInfo.gmsVersionCode); + addPairedString(INSTALLER_PACKAGE_NAME, buildInfo.installerPackageName); + addPairedString(ABI_NAME, buildInfo.abiString); addPairedString(EXCEPTION_INFO, Log.getStackTraceString(javaException)); addPairedString(EARLY_JAVA_EXCEPTION, "true"); addPairedString(PACKAGE, - BuildConfig.FIREBASE_APP_ID + " v" + BuildInfo.getPackageVersionCode() + " (" - + BuildInfo.getPackageVersionName() + ")"); + String.format("%s v%s (%s)", BuildConfig.FIREBASE_APP_ID, buildInfo.versionCode, + buildInfo.versionName)); addString(mBoundary); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java index 7fbb804d..faa96be 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java
@@ -36,6 +36,7 @@ import org.chromium.base.TimeUtils; import org.chromium.base.TraceEvent; import org.chromium.base.VisibleForTesting; +import org.chromium.base.annotations.JNINamespace; import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.base.library_loader.ProcessInitException; import org.chromium.base.metrics.RecordHistogram; @@ -83,6 +84,7 @@ * Note: This class is meant to be package private, and is public to be * accessible from {@link ChromeApplication}. */ +@JNINamespace("customtabs") public class CustomTabsConnection { private static final String TAG = "ChromeConnection"; private static final String LOG_SERVICE_REQUESTS = "custom-tabs-log-service-requests"; @@ -935,6 +937,43 @@ Profile.getLastUsedProfile(), redirectEndpoint.toString()); } + /** @return Whether {@code session} can create a parallel request for a given {@code origin}. */ + @VisibleForTesting + boolean canDoParallelRequest(CustomTabsSessionToken session, String origin) { + ThreadUtils.assertOnUiThread(); + // The restrictions are: + // - Native initialization: Required to get the profile, and the feature state. + // - Feature check + // - The origin is allowed. + // + // TODO(lizeb): Relax the restrictions. + return ChromeBrowserInitializer.getInstance(mContext).hasNativeInitializationCompleted() + && ChromeFeatureList.isEnabled(ChromeFeatureList.CCT_PARALLEL_REQUEST) + && mClientManager.isFirstPartyOriginForSession(session, Uri.parse(origin)); + } + + /** + * Starts a parallel request. + * + * @param session Calling context session. + * @param url URL to send the request to. + * @param origin Origin to use. + * @return Whether the request started. False if the session is not authorized to use the + * provided origin, if Chrome hasn't been initialized, or the feature is disabled. + * Also fails if the URL is neither HTTPS not HTTP. + */ + @VisibleForTesting + boolean startParallelRequest(CustomTabsSessionToken session, String url, String origin) { + ThreadUtils.assertOnUiThread(); + if (TextUtils.isEmpty(url) || !isValid(Uri.parse(url)) + || !canDoParallelRequest(session, origin)) { + return false; + } + + nativeCreateAndStartDetachedResourceRequest(Profile.getLastUsedProfile(), url, origin); + return true; + } + /** See {@link ClientManager#getReferrerForSession(CustomTabsSessionToken)} */ public Referrer getReferrerForSession(CustomTabsSessionToken session) { return mClientManager.getReferrerForSession(session); @@ -1495,4 +1534,7 @@ RecordHistogram.recordEnumeratedHistogram( "CustomTabs.SpeculationStatusOnSwap", status, SPECULATION_STATUS_ON_SWAP_MAX); } + + private static native void nativeCreateAndStartDetachedResourceRequest( + Profile profile, String url, String origin); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java index eaf0625..e99bc42 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadSnackbarController.java
@@ -94,7 +94,7 @@ if (getSnackbarManager() == null) return; Snackbar snackbar; if (getActivity() instanceof CustomTabActivity) { - String packageLabel = BuildInfo.getPackageLabel(); + String packageLabel = BuildInfo.getInstance().hostPackageLabel; snackbar = Snackbar.make(mContext.getString(R.string.download_succeeded_message, downloadInfo.getFileName(), packageLabel), this, Snackbar.TYPE_NOTIFICATION, Snackbar.UMA_DOWNLOAD_SUCCEEDED);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java index 8584da1..534e2b9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
@@ -339,7 +339,7 @@ // pairing code URL, since these match the current tab with a device (Chromecast // or similar) it is supposed to be controlling. Using a different application // that isn't expecting this (in particular YouTube) doesn't work. - if (params.getUrl().matches(".*youtube\\.com.*[?&]pairingCode=.*")) { + if (params.getUrl().matches(".*youtube\\.com(\\/.*)?\\?(.+&)?pairingCode=[^&].+")) { if (DEBUG) Log.i(TAG, "NO_OVERRIDE: YouTube URL with a pairing code"); return OverrideUrlLoadingResult.NO_OVERRIDE; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java index 6eaf21d..16ad618 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/RequestGenerator.java
@@ -180,7 +180,8 @@ * these strings when building their own custom Android ROMs. */ public String getAdditionalParameters() { - String applicationLabel = StringSanitizer.sanitize(BuildInfo.getPackageLabel()); + String applicationLabel = + StringSanitizer.sanitize(BuildInfo.getInstance().hostPackageLabel); String brand = StringSanitizer.sanitize(Build.BRAND); String model = StringSanitizer.sanitize(Build.MODEL); return applicationLabel + ";" + brand + ";" + model;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java index 6f0101c8..f5431d56 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/VersionNumberGetter.java
@@ -60,7 +60,7 @@ * @return The latest version if we retrieved one from the Omaha server, or "" if we haven't. */ public String getCurrentlyUsedVersion(Context context) { - return BuildInfo.getPackageVersionName(); + return BuildInfo.getInstance().versionName; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorTextField.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorTextField.java index 869b875..6da704a7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorTextField.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorTextField.java
@@ -16,6 +16,7 @@ import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.FrameLayout; @@ -66,6 +67,19 @@ mInput.setText(fieldModel.getValue()); mInput.setContentDescription(label); mInput.setOnEditorActionListener(mEditorActionListener); + // AutoCompleteTextView requires and explicit onKeyListener to show the OSK upon receiving + // a KEYCODE_DPAD_CENTER. + mInput.setOnKeyListener((v, keyCode, event) -> { + if (!(keyCode == KeyEvent.KEYCODE_DPAD_CENTER + && event.getAction() == KeyEvent.ACTION_UP)) { + return false; + } + InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService( + Context.INPUT_METHOD_SERVICE); + imm.viewClicked(v); + imm.showSoftInput(v, 0); + return true; + }); mIconsLayer = findViewById(R.id.icons_layer); mIconsLayer.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java index 42c08b2..7b7cb92 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/MainPreferences.java
@@ -12,7 +12,7 @@ import android.preference.PreferenceFragment; import android.provider.Settings; -import org.chromium.base.BuildInfo; +import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeFeatureList; @@ -103,7 +103,8 @@ notifications.setOnPreferenceClickListener(preference -> { Intent intent = new Intent(); intent.setAction(Settings.ACTION_APP_NOTIFICATION_SETTINGS); - intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildInfo.getPackageName()); + intent.putExtra(Settings.EXTRA_APP_PACKAGE, + ContextUtils.getApplicationContext().getPackageName()); startActivity(intent); // We handle the click so the default action (opening NotificationsPreference) // isn't triggered.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreference.java index fb32eba..89f0e6d1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/SyncPreference.java
@@ -101,7 +101,8 @@ if (profileSyncService.getProtocolErrorClientAction() == ProtocolErrorClientAction.UPGRADE_CLIENT) { - return res.getString(R.string.sync_error_upgrade_client, BuildInfo.getPackageLabel()); + return res.getString( + R.string.sync_error_upgrade_client, BuildInfo.getInstance().hostPackageLabel); } if (profileSyncService.hasUnrecoverableError()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java index 9657b20..7791870 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseDialogFragment.java
@@ -30,7 +30,7 @@ import android.widget.TextView.OnEditorActionListener; import org.chromium.base.ApiCompatibilityUtils; -import org.chromium.base.BuildInfo; +import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; @@ -202,7 +202,7 @@ recordPassphraseDialogDismissal(PASSPHRASE_DIALOG_RESET_LINK); Uri syncDashboardUrl = Uri.parse(ChromeStringConstants.SYNC_DASHBOARD_URL); Intent intent = new Intent(Intent.ACTION_VIEW, syncDashboardUrl); - intent.setPackage(BuildInfo.getPackageName()); + intent.setPackage(ContextUtils.getApplicationContext().getPackageName()); IntentUtils.safePutBinderExtra( intent, CustomTabsIntent.EXTRA_SESSION, null); context.startActivity(intent);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java index cc39787..7b6645c4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragment.java
@@ -26,7 +26,7 @@ import android.widget.ListView; import android.widget.TextView; -import org.chromium.base.BuildInfo; +import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeStringConstants; @@ -195,7 +195,7 @@ public void onClick(View view) { Uri syncDashboardUrl = Uri.parse(ChromeStringConstants.SYNC_DASHBOARD_URL); Intent intent = new Intent(Intent.ACTION_VIEW, syncDashboardUrl); - intent.setPackage(BuildInfo.getPackageName()); + intent.setPackage(ContextUtils.getApplicationContext().getPackageName()); IntentUtils.safePutBinderExtra( intent, CustomTabsIntent.EXTRA_SESSION, null); context.startActivity(intent);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java index c618339..28a2968 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/ui/SyncCustomizationFragment.java
@@ -31,6 +31,7 @@ import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.BuildInfo; +import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; @@ -679,7 +680,8 @@ case SYNC_AUTH_ERROR: return res.getString(R.string.hint_sync_auth_error); case SYNC_CLIENT_OUT_OF_DATE: - return res.getString(R.string.hint_client_out_of_date, BuildInfo.getPackageLabel()); + return res.getString( + R.string.hint_client_out_of_date, BuildInfo.getInstance().hostPackageLabel); case SYNC_OTHER_ERRORS: return res.getString(R.string.hint_other_sync_errors); case SYNC_PASSPHRASE_REQUIRED: @@ -716,7 +718,8 @@ if (mCurrentSyncError == SYNC_CLIENT_OUT_OF_DATE) { // Opens the client in play store for update. Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse("market://details?id=" + BuildInfo.getPackageName())); + intent.setData(Uri.parse("market://details?id=" + + ContextUtils.getApplicationContext().getPackageName())); startActivity(intent); return; }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 4bd190c..887b320 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -34,7 +34,6 @@ "java/src/org/chromium/chrome/browser/ChromeTabbedActivity2.java", "java/src/org/chromium/chrome/browser/ChromeVersionInfo.java", "java/src/org/chromium/chrome/browser/ChromeWindow.java", - "java/src/org/chromium/chrome/browser/ClassRegister.java", "java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java", "java/src/org/chromium/chrome/browser/DeferredStartupHandler.java", "java/src/org/chromium/chrome/browser/DevToolsServer.java", @@ -1552,6 +1551,7 @@ "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabsTestUtils.java", "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistenceIntegrationTest.java", "javatests/src/org/chromium/chrome/browser/customtabs/CustomTabTabPersistencePolicyTest.java", + "javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java", "javatests/src/org/chromium/chrome/browser/customtabs/RequestThrottlerTest.java", "javatests/src/org/chromium/chrome/browser/document/LauncherActivityTest.java", "javatests/src/org/chromium/chrome/browser/dom_distiller/DistillabilityServiceTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ProcessIsolationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ProcessIsolationTest.java index 359310e8..886318e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ProcessIsolationTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ProcessIsolationTest.java
@@ -13,7 +13,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -import org.chromium.base.BuildInfo; +import org.chromium.base.ContextUtils; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; @@ -53,7 +53,7 @@ // in the RunningAppProcessInfo for isolated processes is the same as the parent process // (see b/7724486, closed as "Working as intended"). // So we have to resort to parsing the ps output. - String packageName = BuildInfo.getPackageName(); + String packageName = ContextUtils.getApplicationContext().getPackageName(); Assert.assertFalse("Failed to retrieve package name for current version of Chrome.", TextUtils.isEmpty(packageName));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java new file mode 100644 index 0000000..69f4d77 --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/DetachedResourceRequestTest.java
@@ -0,0 +1,137 @@ +// 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.customtabs; + +import android.content.Context; +import android.net.Uri; +import android.support.customtabs.CustomTabsService; +import android.support.customtabs.CustomTabsSessionToken; +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.SmallTest; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; + +import org.chromium.base.PathUtils; +import org.chromium.base.ThreadUtils; +import org.chromium.base.library_loader.LibraryLoader; +import org.chromium.base.library_loader.LibraryProcessType; +import org.chromium.base.test.util.CallbackHelper; +import org.chromium.chrome.browser.ChromeFeatureList; +import org.chromium.chrome.browser.browserservices.OriginVerifier; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.chrome.test.util.browser.Features; +import org.chromium.chrome.test.util.browser.Features.EnableFeatures; +import org.chromium.net.test.EmbeddedTestServer; + +/** Tests for detached resource requests. */ +@RunWith(ChromeJUnit4ClassRunner.class) +public class DetachedResourceRequestTest { + @Rule + public TestRule processor = new Features.InstrumentationProcessor(); + + private CustomTabsConnection mConnection; + private Context mContext; + + private static final String PRIVATE_DATA_DIRECTORY_SUFFIX = "chrome"; + private static final String ORIGIN = "http://cats.google.com"; + + @Before + public void setUp() throws Exception { + PathUtils.setPrivateDataDirectorySuffix(PRIVATE_DATA_DIRECTORY_SUFFIX); + LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER).ensureInitialized(); + mConnection = CustomTabsTestUtils.setUpConnection(); + mContext = InstrumentationRegistry.getInstrumentation() + .getTargetContext() + .getApplicationContext(); + } + + @After + public void tearDown() throws Exception { + CustomTabsTestUtils.cleanupSessions(mConnection); + } + + @Test + @SmallTest + @EnableFeatures(ChromeFeatureList.CCT_PARALLEL_REQUEST) + public void testCanDoParallelRequest() throws Exception { + CustomTabsSessionToken session = CustomTabsSessionToken.createMockSessionTokenForTesting(); + Assert.assertTrue(mConnection.newSession(session)); + ThreadUtils.runOnUiThreadBlocking( + () -> { Assert.assertFalse(mConnection.canDoParallelRequest(session, ORIGIN)); }); + CustomTabsTestUtils.warmUpAndWait(); + ThreadUtils.runOnUiThreadBlocking( + () -> { Assert.assertFalse(mConnection.canDoParallelRequest(session, ORIGIN)); }); + ThreadUtils.runOnUiThreadBlocking(() -> { + String packageName = mContext.getPackageName(); + OriginVerifier.addVerifiedOriginForPackage( + packageName, Uri.parse(ORIGIN), CustomTabsService.RELATION_USE_AS_ORIGIN); + Assert.assertTrue(mConnection.canDoParallelRequest(session, ORIGIN)); + }); + } + + @Test + @SmallTest + @EnableFeatures(ChromeFeatureList.CCT_PARALLEL_REQUEST) + public void testStartParallelRequestValidation() throws Exception { + CustomTabsSessionToken session = prepareSession(); + ThreadUtils.runOnUiThreadBlocking(() -> { + Assert.assertFalse("Should not allow android-app:// scheme", + mConnection.startParallelRequest( + session, "android-app://this.is.an.android.app", ORIGIN)); + Assert.assertFalse("Should not allow an empty URL", + mConnection.startParallelRequest(session, "", ORIGIN)); + Assert.assertFalse("Should not allow an arbitrary origin", + mConnection.startParallelRequest(session, "HTTPS://foo.bar", "wrong://origin")); + Assert.assertTrue(mConnection.startParallelRequest(session, "HTTP://foo.bar", ORIGIN)); + }); + } + + @Test + @SmallTest + @EnableFeatures(ChromeFeatureList.CCT_PARALLEL_REQUEST) + public void testCanStartParallelRequest() throws Exception { + CustomTabsSessionToken session = prepareSession(); + + final CallbackHelper cb = new CallbackHelper(); + EmbeddedTestServer server = new EmbeddedTestServer(); + try { + server.initializeNative(mContext, EmbeddedTestServer.ServerHTTPSSetting.USE_HTTP); + server.setConnectionListener(new EmbeddedTestServer.ConnectionListener() { + @Override + public void readFromSocket(long socketId) { + cb.notifyCalled(); + } + }); + server.start(); + + ThreadUtils.runOnUiThread(() -> { + String url = server.getURL("/echotitle"); + Assert.assertTrue(mConnection.startParallelRequest(session, url, ORIGIN)); + }); + cb.waitForCallback(0, 1); + } finally { + server.stopAndDestroyServer(); + } + } + + private CustomTabsSessionToken prepareSession() throws Exception { + final CustomTabsSessionToken session = + CustomTabsSessionToken.createMockSessionTokenForTesting(); + Assert.assertTrue(mConnection.newSession(session)); + CustomTabsTestUtils.warmUpAndWait(); + ThreadUtils.runOnUiThreadBlocking(() -> { + OriginVerifier.addVerifiedOriginForPackage(mContext.getPackageName(), Uri.parse(ORIGIN), + CustomTabsService.RELATION_USE_AS_ORIGIN); + Assert.assertTrue(mConnection.canDoParallelRequest(session, ORIGIN)); + }); + return session; + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java index 8dc7e2e8..d0e2070 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandlerTest.java
@@ -409,17 +409,39 @@ int transitionTypeIncomingIntent = PageTransition.LINK | PageTransition.FROM_API; - String url = "http://m.youtube.com/watch?v=1234&pairingCode=5678"; + final String[] goodUrls = {"http://m.youtube.com/watch?v=1234&pairingCode=5678", + "youtube.com?pairingCode=xyz", "youtube.com/tv?pairingCode=xyz", + "youtube.com/watch?v=1234&version=3&autohide=1&pairingCode=xyz", + "youtube.com/watch?v=1234&pairingCode=xyz&version=3&autohide=1"}; + final String[] badUrls = {"youtube.com.foo.com/tv?pairingCode=xyz", + "youtube.com.foo.com?pairingCode=xyz", + "youtube.com/watch?v=tEsT&version=3&autohide=1&pairingCode=", + "youtube.com&pairingCode=xyz", + "youtube.com/watch?v=tEsT?version=3&pairingCode=&autohide=1"}; - // http://crbug/386600 - it makes no sense to switch activities for pairing code URLs. - checkUrl(url) - .withIsRedirect(true) - .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE); + // Make sure we don't override when faced with valid pairing code URLs. + for (String url : goodUrls) { + // http://crbug/386600 - it makes no sense to switch activities for pairing code URLs. + checkUrl(url).withIsRedirect(true).expecting( + OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE); - checkUrl(url) - .withPageTransition(transitionTypeIncomingIntent) - .withIsRedirect(true) - .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE); + checkUrl(url) + .withPageTransition(transitionTypeIncomingIntent) + .withIsRedirect(true) + .expecting(OverrideUrlLoadingResult.NO_OVERRIDE, IGNORE); + } + + // The pairing code URL regex shouldn't cause NO_OVERRIDE on invalid URLs. + for (String url : badUrls) { + checkUrl(url).withIsRedirect(true).expecting( + OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, START_OTHER_ACTIVITY); + + checkUrl(url) + .withPageTransition(transitionTypeIncomingIntent) + .withIsRedirect(true) + .expecting(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTENT, + START_OTHER_ACTIVITY); + } } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfilesFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfilesFragmentTest.java index 64614fd2..e6833bc8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfilesFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfilesFragmentTest.java
@@ -7,6 +7,8 @@ import android.preference.PreferenceFragment; import android.support.test.InstrumentationRegistry; import android.support.test.filters.MediumTest; +import android.view.KeyEvent; +import android.widget.EditText; import org.junit.Assert; import org.junit.Before; @@ -22,7 +24,11 @@ import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; import org.chromium.chrome.browser.preferences.Preferences; import org.chromium.chrome.browser.preferences.PreferencesTest; +import org.chromium.content.browser.test.util.Criteria; +import org.chromium.content.browser.test.util.CriteriaHelper; +import org.chromium.ui.UiUtils; +import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -228,4 +234,59 @@ Assert.assertTrue(oldProfile == null); activity.finish(); } + + @Test + @MediumTest + @Feature({"Preferences"}) + public void testKeyboardShownOnDpadCenter() { + Preferences activity = + PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(), + AutofillProfilesFragment.class.getName()); + + PreferenceFragment fragment = (PreferenceFragment) activity.getFragmentForTest(); + AutofillProfileEditorPreference addProfile = + (AutofillProfileEditorPreference) fragment.findPreference( + AutofillProfilesFragment.PREF_NEW_PROFILE); + Assert.assertNotNull(addProfile); + + // Open AutofillProfileEditorPreference. + ThreadUtils.runOnUiThreadBlocking(() -> { + PreferencesTest.clickPreference(fragment, addProfile); + rule.setEditorDialog(addProfile.getEditorDialog()); + }); + // The keyboard is shown as soon as AutofillProfileEditorPreference comes into view. + waitForKeyboardStatus(true, activity); + + // Hide the keyboard. + ThreadUtils.runOnUiThreadBlocking(() -> { + List<EditText> fields = addProfile.getEditorDialog().getEditableTextFieldsForTest(); + UiUtils.hideKeyboard(fields.get(0)); + }); + // Check that the keyboard is hidden. + waitForKeyboardStatus(false, activity); + + // Send a d-pad key event to one of the text fields + ThreadUtils.runOnUiThreadBlocking(() -> { + try { + rule.sendKeycodeToTextFieldInEditorAndWait(KeyEvent.KEYCODE_DPAD_CENTER, 0); + } catch (Exception ex) { + ex.printStackTrace(); + } + }); + // Check that the keyboard was shown. + waitForKeyboardStatus(true, activity); + activity.finish(); + } + + private void waitForKeyboardStatus(final boolean keyboardVisible, final Preferences activity) { + CriteriaHelper.pollUiThread( + new Criteria("Keyboard was not " + (keyboardVisible ? "shown." : "hidden.")) { + @Override + public boolean isSatisfied() { + return keyboardVisible + == UiUtils.isKeyboardShowing( + activity, activity.findViewById(android.R.id.content)); + } + }); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/autofill/AutofillTestRule.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/autofill/AutofillTestRule.java index 695a789..0c71c27 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/autofill/AutofillTestRule.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/autofill/AutofillTestRule.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.preferences.autofill; +import android.view.KeyEvent; import android.widget.EditText; import org.chromium.base.ThreadUtils; @@ -62,6 +63,18 @@ mValidationUpdate.waitForCallback(callCount); } + protected void sendKeycodeToTextFieldInEditorAndWait(final int keycode, + final int textFieldIndex) throws InterruptedException, TimeoutException { + int callCount = mClickUpdate.getCallCount(); + ThreadUtils.runOnUiThreadBlocking(() -> { + List<EditText> fields = mEditorDialog.getEditableTextFieldsForTest(); + fields.get(textFieldIndex) + .dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, keycode)); + fields.get(textFieldIndex).dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, keycode)); + }); + mClickUpdate.waitForCallback(callCount); + } + protected void waitForThePreferenceUpdate() throws InterruptedException, TimeoutException { int callCount = mPreferenceUpdate.getCallCount(); mPreferenceUpdate.waitForCallback(callCount);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java index bd3a4868..9f6e0eb8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/vr_shell/WebVrTransitionTest.java
@@ -129,17 +129,21 @@ CriteriaHelper.pollInstrumentationThread(new Criteria() { @Override public boolean isSatisfied() { - Bitmap bmpCurrentScreen = InstrumentationRegistry.getInstrumentation() - .getUiAutomation() - .takeScreenshot(); + Bitmap screenshot = InstrumentationRegistry.getInstrumentation() + .getUiAutomation() + .takeScreenshot(); - if (bmpCurrentScreen != null) { + if (screenshot != null) { // Calculate center of eye coordinates. - int iheight = uiDevice.getDisplayHeight() / 2; - int iwidth = uiDevice.getDisplayWidth() / 4; + int height = uiDevice.getDisplayHeight() / 2; + int width = uiDevice.getDisplayWidth() / 4; // Verify screen is blue. - return Color.BLUE == bmpCurrentScreen.getPixel(iwidth, iheight); + int pixel = screenshot.getPixel(width, height); + // Workaround for the immersive mode popup sometimes being rendered over the + // screen on K, which causes the pure blue to be darkened to (0, 0, 127). + // TODO(https://crbug.com/819021): Only check pure blue. + return pixel == Color.BLUE || pixel == Color.rgb(0, 0, 127); } return false; }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 3ca1d0f..3b75e50 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -25,7 +25,6 @@ import("//sandbox/features.gni") import("//third_party/protobuf/proto_library.gni") import("//ui/base/ui_features.gni") -import("//build/buildflag_header.gni") # //build/config/android/rules.gni imports //tools/grit/grit_rule.gni, which # produces a conflict for the "grit" template so we have to only include one. @@ -35,10 +34,6 @@ import("//tools/grit/grit_rule.gni") } -if (enable_vr) { - import("//chrome/browser/vr/features.gni") -} - additional_modules_list_file = "$root_gen_dir/chrome/browser/internal/additional_modules_list.txt" @@ -61,13 +56,6 @@ } } -if (enable_vr) { - buildflag_header("vr_build_features") { - header = "vr_features.h" - flags = [ "USE_VR_ASSETS_COMPONENT=$use_vr_assets_component" ] - } -} - # Use a static library here because many test binaries depend on this but don't # require many files from it. This makes linking more efficient. jumbo_split_static_library("browser") { @@ -1755,8 +1743,8 @@ "//content/app/resources", "//content/public/browser", "//content/public/common", + "//content/public/common:buildflags", "//content/public/common:feature_h264_with_openh264_ffmpeg", - "//content/public/common:features", "//content/public/common:service_names", "//courgette:courgette_lib", "//crypto", @@ -1946,6 +1934,7 @@ "android/crash/pure_java_exception_handler.h", "android/customtabs/detached_resource_request.cc", "android/customtabs/detached_resource_request.h", + "android/customtabs/detached_resource_request_android.cc", "android/customtabs/origin_verifier.cc", "android/customtabs/origin_verifier.h", "android/data_usage/data_use_matcher.cc", @@ -4098,12 +4087,8 @@ sources += [ "component_updater/vr_assets_component_installer.cc", "component_updater/vr_assets_component_installer.h", - "vr_features.h", ] - deps += [ - ":vr_build_features", - "//chrome/browser/vr:vr_common", - ] + deps += [ "//chrome/browser/vr:vr_common" ] } if (enable_wayland_server) { @@ -4248,6 +4233,7 @@ "../android/java/src/org/chromium/chrome/browser/cookies/CookiesFetcher.java", "../android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java", "../android/java/src/org/chromium/chrome/browser/crash/PureJavaExceptionHandler.java", + "../android/java/src/org/chromium/chrome/browser/customtabs/CustomTabsConnection.java", "../android/java/src/org/chromium/chrome/browser/customtabs/LoadingPredictor.java", "../android/java/src/org/chromium/chrome/browser/database/SQLiteCursor.java", "../android/java/src/org/chromium/chrome/browser/datausage/DataUseTabUIManager.java",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 706fce99..6794d242 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -90,10 +90,10 @@ #include "components/translate/core/browser/translate_ranker_impl.h" #include "components/version_info/version_info.h" #include "components/viz/common/features.h" +#include "content/public/common/buildflags.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/feature_h264_with_openh264_ffmpeg.h" -#include "content/public/common/features.h" #include "device/base/features.h" #include "device/vr/features/features.h" #include "extensions/features/features.h" @@ -1962,6 +1962,10 @@ {"enable-system-tray-unified", flag_descriptions::kSystemTrayUnifiedName, flag_descriptions::kSystemTrayUnifiedDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kSystemTrayUnified)}, + {"enable-lock-screen-notification", + flag_descriptions::kLockScreenNotificationName, + flag_descriptions::kLockScreenNotificationDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kLockScreenNotifications)}, #endif // OS_CHROMEOS {"enable-message-center-new-style-notification", flag_descriptions::kMessageCenterNewStyleNotificationName,
diff --git a/chrome/browser/android/chrome_feature_list.cc b/chrome/browser/android/chrome_feature_list.cc index 9813ee9..d11f9e5 100644 --- a/chrome/browser/android/chrome_feature_list.cc +++ b/chrome/browser/android/chrome_feature_list.cc
@@ -60,6 +60,7 @@ &kAndroidPaymentApps, &kCCTBackgroundTab, &kCCTExternalLinkHandling, + &kCCTParallelRequest, &kCCTPostMessageAPI, &kCCTRedirectPreconnect, &kChromeDuplexFeature, @@ -181,6 +182,9 @@ const base::Feature kCCTExternalLinkHandling{"CCTExternalLinkHandling", base::FEATURE_ENABLED_BY_DEFAULT}; +const base::Feature kCCTParallelRequest{"CCTParallelRequest", + base::FEATURE_DISABLED_BY_DEFAULT}; + const base::Feature kCCTPostMessageAPI{"CCTPostMessageAPI", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/browser/android/chrome_feature_list.h b/chrome/browser/android/chrome_feature_list.h index a2990b1..168b475b 100644 --- a/chrome/browser/android/chrome_feature_list.h +++ b/chrome/browser/android/chrome_feature_list.h
@@ -19,6 +19,7 @@ extern const base::Feature kAndroidPaymentApps; extern const base::Feature kCCTBackgroundTab; extern const base::Feature kCCTExternalLinkHandling; +extern const base::Feature kCCTParallelRequest; extern const base::Feature kCCTPostMessageAPI; extern const base::Feature kCCTRedirectPreconnect; extern const base::Feature kChromeDuplexFeature;
diff --git a/chrome/browser/android/customtabs/detached_resource_request_android.cc b/chrome/browser/android/customtabs/detached_resource_request_android.cc new file mode 100644 index 0000000..33283554 --- /dev/null +++ b/chrome/browser/android/customtabs/detached_resource_request_android.cc
@@ -0,0 +1,36 @@ +// 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 "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "chrome/browser/android/customtabs/detached_resource_request.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_android.h" +#include "jni/CustomTabsConnection_jni.h" +#include "url/gurl.h" + +namespace customtabs { + +static void JNI_CustomTabsConnection_CreateAndStartDetachedResourceRequest( + JNIEnv* env, + const base::android::JavaParamRef<jclass>& jcaller, + const base::android::JavaParamRef<jobject>& profile, + const base::android::JavaParamRef<jstring>& url, + const base::android::JavaParamRef<jstring>& origin) { + DCHECK(profile && url && origin); + + Profile* native_profile = ProfileAndroid::FromProfileAndroid(profile); + DCHECK(native_profile); + + GURL native_url(base::android::ConvertJavaStringToUTF8(env, url)); + GURL native_origin(base::android::ConvertJavaStringToUTF8(env, origin)); + DCHECK(native_url.is_valid()); + DCHECK(native_origin.is_valid()); + + DetachedResourceRequest::CreateAndStart(native_profile, native_url, + native_origin); +} + +} // namespace customtabs
diff --git a/chrome/browser/android/preferences/pref_service_bridge.cc b/chrome/browser/android/preferences/pref_service_bridge.cc index 74a6c30..0780e56 100644 --- a/chrome/browser/android/preferences/pref_service_bridge.cc +++ b/chrome/browser/android/preferences/pref_service_bridge.cc
@@ -989,7 +989,7 @@ base::android::BuildInfo* android_build_info = base::android::BuildInfo::GetInstance(); - std::string application(android_build_info->package_label()); + std::string application(android_build_info->host_package_label()); application.append(" "); application.append(version_info::GetVersionNumber());
diff --git a/chrome/browser/android/vr/vr_gl_thread.cc b/chrome/browser/android/vr/vr_gl_thread.cc index fd8de652..d2e7bfb 100644 --- a/chrome/browser/android/vr/vr_gl_thread.cc +++ b/chrome/browser/android/vr/vr_gl_thread.cc
@@ -143,6 +143,12 @@ base::Passed(std::move(event)), content_id)); } +void VrGLThread::ClearFocusedElement() { + DCHECK(OnGlThread()); + main_thread_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&VrShell::ClearFocusedElement, weak_vr_shell_)); +} + void VrGLThread::OnWebInputEdited(const TextEdits& edits) { DCHECK(OnGlThread()); DCHECK(weak_input_connection_); @@ -270,12 +276,6 @@ FROM_HERE, base::BindOnce(&VrShell::StopAutocomplete, weak_vr_shell_)); } -void VrGLThread::LoadAssets() { - DCHECK(OnGlThread()); - main_thread_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&VrShell::LoadAssets, weak_vr_shell_)); -} - void VrGLThread::SetFullscreen(bool enabled) { DCHECK(OnMainThread()); task_runner()->PostTask(FROM_HERE, @@ -407,13 +407,6 @@ weak_browser_ui_, base::Passed(std::move(suggestions)))); } -void VrGLThread::OnAssetsComponentReady() { - DCHECK(OnMainThread()); - task_runner()->PostTask( - FROM_HERE, base::BindOnce(&BrowserUiInterface::OnAssetsComponentReady, - weak_browser_ui_)); -} - void VrGLThread::OnAssetsLoaded(AssetsLoadStatus status, std::unique_ptr<Assets> assets, const base::Version& component_version) {
diff --git a/chrome/browser/android/vr/vr_gl_thread.h b/chrome/browser/android/vr/vr_gl_thread.h index 4e95c5c..3c39270a 100644 --- a/chrome/browser/android/vr/vr_gl_thread.h +++ b/chrome/browser/android/vr/vr_gl_thread.h
@@ -69,6 +69,7 @@ void ForwardEvent(std::unique_ptr<blink::WebInputEvent> event, int content_id) override; void ForwardDialogEvent(std::unique_ptr<blink::WebInputEvent> event) override; + void ClearFocusedElement() override; void OnWebInputEdited(const TextEdits& edits) override; void SubmitWebInput() override; void RequestWebInputText(TextStateUpdateCallback callback) override; @@ -87,7 +88,6 @@ void SetVoiceSearchActive(bool active) override; void StartAutocomplete(const AutocompleteRequest& request) override; void StopAutocomplete() override; - void LoadAssets() override; // BrowserUiInterface implementation (Browser calling to UI). void SetWebVrMode(bool enabled, bool show_toast) override; @@ -109,7 +109,6 @@ void OnSpeechRecognitionStateChanged(int new_state) override; void SetOmniboxSuggestions( std::unique_ptr<OmniboxSuggestions> result) override; - void OnAssetsComponentReady() override; void OnAssetsLoaded(AssetsLoadStatus status, std::unique_ptr<Assets> assets, const base::Version& component_version) override;
diff --git a/chrome/browser/android/vr/vr_shell.cc b/chrome/browser/android/vr/vr_shell.cc index 37021782..740f86e5 100644 --- a/chrome/browser/android/vr/vr_shell.cc +++ b/chrome/browser/android/vr/vr_shell.cc
@@ -918,6 +918,13 @@ high_accuracy_location_ = high_accuracy_location; } +void VrShell::ClearFocusedElement() { + if (!web_contents_) + return; + + web_contents_->ClearFocusedElement(); +} + void VrShell::ProcessContentGesture(std::unique_ptr<blink::WebInputEvent> event, int content_id) { // Block the events if they don't belong to the current content @@ -1005,11 +1012,6 @@ base::android::ConvertUTF8ToJavaString(env, url.spec())); } -void VrShell::LoadAssets() { - AssetsLoader::GetInstance()->Load( - base::BindOnce(&VrShell::OnAssetsLoaded, base::Unretained(this))); -} - void VrShell::OnAssetsLoaded(AssetsLoadStatus status, std::unique_ptr<Assets> assets, const base::Version& component_version) { @@ -1025,12 +1027,18 @@ status, component_version); } +void VrShell::LoadAssets() { + AssetsLoader::GetInstance()->Load( + base::BindOnce(&VrShell::OnAssetsLoaded, base::Unretained(this))); +} + void VrShell::OnAssetsComponentReady() { + // We don't apply updates after the timer expires because that would lead to + // replacing the user's environment. New updates will be applied when + // re-entering VR. if (waiting_for_assets_component_timer_.IsRunning()) { waiting_for_assets_component_timer_.Stop(); LoadAssets(); - } else { - ui_->OnAssetsComponentReady(); } } @@ -1075,7 +1083,7 @@ has_or_can_request_audio_permission; ui_initial_state.skips_redraw_when_not_dirty = base::FeatureList::IsEnabled(features::kVrBrowsingExperimentalRendering); - ui_initial_state.assets_available = true; + ui_initial_state.assets_supported = AssetsLoader::AssetsSupported(); return reinterpret_cast<intptr_t>(new VrShell( env, obj, ui_initial_state,
diff --git a/chrome/browser/android/vr/vr_shell.h b/chrome/browser/android/vr/vr_shell.h index ddeaa3ba..520315d5 100644 --- a/chrome/browser/android/vr/vr_shell.h +++ b/chrome/browser/android/vr/vr_shell.h
@@ -187,6 +187,7 @@ void StopAutocomplete(); bool HasAudioPermission(); + void ClearFocusedElement(); void ProcessContentGesture(std::unique_ptr<blink::WebInputEvent> event, int content_id); @@ -223,7 +224,6 @@ void OnVoiceResults(const base::string16& result) override; - void LoadAssets(); void OnAssetsLoaded(AssetsLoadStatus status, std::unique_ptr<Assets> assets, const base::Version& component_version); @@ -247,6 +247,7 @@ content::WebContents* GetNonNativePageWebContents() const; + void LoadAssets(); void OnAssetsComponentReady(); void OnAssetsComponentWaitTimeout();
diff --git a/chrome/browser/android/vr/vr_shell_gl.cc b/chrome/browser/android/vr/vr_shell_gl.cc index 635b402..185d5ae 100644 --- a/chrome/browser/android/vr/vr_shell_gl.cc +++ b/chrome/browser/android/vr/vr_shell_gl.cc
@@ -1571,7 +1571,7 @@ gfx::Transform head_mat; device::mojom::VRPosePtr pose = device::GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), &head_mat, - 0, prediction_nanos); + prediction_nanos); webvr_head_pose_[frame_index % kPoseRingBufferSize] = head_mat; webvr_frame_oustanding_[frame_index % kPoseRingBufferSize] = true;
diff --git a/chrome/browser/component_updater/vr_assets_component_installer.cc b/chrome/browser/component_updater/vr_assets_component_installer.cc index 1d2ad29..caebc2e 100644 --- a/chrome/browser/component_updater/vr_assets_component_installer.cc +++ b/chrome/browser/component_updater/vr_assets_component_installer.cc
@@ -19,7 +19,7 @@ #include "base/version.h" #include "chrome/browser/vr/assets_loader.h" #include "chrome/browser/vr/metrics_helper.h" -#include "chrome/browser/vr_features.h" +#include "chrome/browser/vr/vr_features.h" #include "chrome/common/safe_browsing/file_type_policies.h" #include "components/component_updater/component_updater_paths.h" #include "components/component_updater/component_updater_service.h"
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index 4bbcf8f..ff27b9ff 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -32,6 +32,7 @@ #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/sys_info.h" +#include "base/test/histogram_tester.h" #include "base/test/test_file_util.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" @@ -89,6 +90,7 @@ #include "components/prefs/pref_service.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" #include "components/safe_browsing/proto/csd.pb.h" +#include "components/security_state/core/security_state.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/download_request_utils.h" #include "content/public/browser/notification_source.h" @@ -3447,6 +3449,37 @@ DownloadAndWait(browser(), url); } +// Test that the SecurityLevel of the initiating page is used for the histogram +// rather than the SecurityLevel of the download URL, and that downloads in new +// tabs are not tracked. +IN_PROC_BROWSER_TEST_F(DownloadTest, SecurityLevels) { + base::HistogramTester histogram_tester; + net::EmbeddedTestServer http_server(net::EmbeddedTestServer::TYPE_HTTP); + net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS); + http_server.ServeFilesFromDirectory(GetTestDataDirectory()); + https_server.ServeFilesFromDirectory(GetTestDataDirectory()); + ASSERT_TRUE(http_server.Start()); + ASSERT_TRUE(https_server.Start()); + + ui_test_utils::NavigateToURL(browser(), http_server.GetURL("/simple.html")); + DownloadAndWait(browser(), https_server.GetURL("/downloads/a_zip_file.zip")); + histogram_tester.ExpectBucketCount("Security.SecurityLevel.DownloadStarted", + security_state::NONE, 1); + + ui_test_utils::NavigateToURL(browser(), https_server.GetURL("/simple.html")); + DownloadAndWait(browser(), http_server.GetURL("/downloads/a_zip_file.zip")); + histogram_tester.ExpectBucketCount("Security.SecurityLevel.DownloadStarted", + security_state::SECURE, 1); + + ui_test_utils::NavigateToURL(browser(), http_server.GetURL("/simple.html")); + DownloadAndWaitWithDisposition( + browser(), https_server.GetURL("/downloads/a_zip_file.zip"), + WindowOpenDisposition::NEW_BACKGROUND_TAB, + ui_test_utils::BROWSER_TEST_WAIT_FOR_TAB); + histogram_tester.ExpectTotalCount("Security.SecurityLevel.DownloadStarted", + 2); +} + #if defined(FULL_SAFE_BROWSING) namespace {
diff --git a/chrome/browser/download/download_ui_controller.cc b/chrome/browser/download/download_ui_controller.cc index 3406dcb..15279d7 100644 --- a/chrome/browser/download/download_ui_controller.cc +++ b/chrome/browser/download/download_ui_controller.cc
@@ -7,15 +7,18 @@ #include <utility> #include "base/callback.h" +#include "base/metrics/histogram_macros.h" #include "build/build_config.h" #include "chrome/browser/devtools/devtools_window.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_shelf.h" +#include "chrome/browser/ssl/security_state_tab_helper.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "components/download/public/common/download_item.h" +#include "components/security_state/core/security_state.h" #include "content/public/browser/download_item_utils.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_delegate.h" @@ -133,6 +136,26 @@ void DownloadUIController::OnDownloadCreated(content::DownloadManager* manager, download::DownloadItem* item) { + // Record the security level of the page triggering the download. Only record + // when the download occurs in the WebContents that initiated the download + // (e.g., not downloads in new tabs or windows, which have a different + // WebContents). + content::WebContents* web_contents = + content::DownloadItemUtils::GetWebContents(item); + if (web_contents && (item->IsSavePackageDownload() || + (web_contents->GetURL() != item->GetOriginalUrl() && + web_contents->GetURL() != item->GetURL()))) { + auto* security_state_tab_helper = + SecurityStateTabHelper::FromWebContents(web_contents); + if (security_state_tab_helper) { + security_state::SecurityInfo security_info; + security_state_tab_helper->GetSecurityInfo(&security_info); + UMA_HISTOGRAM_ENUMERATION("Security.SecurityLevel.DownloadStarted", + security_info.security_level, + security_state::SECURITY_LEVEL_COUNT); + } + } + // SavePackage downloads are created in a state where they can be shown in the // browser. Call OnDownloadUpdated() once to notify the UI immediately. OnDownloadUpdated(manager, item);
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc index 7f7fb586..ae67d9c5 100644 --- a/chrome/browser/download/save_page_browsertest.cc +++ b/chrome/browser/download/save_page_browsertest.cc
@@ -20,6 +20,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" +#include "base/test/histogram_tester.h" #include "base/test/test_file_util.h" #include "base/threading/thread_restrictions.h" #include "build/build_config.h" @@ -46,6 +47,7 @@ #include "components/history/core/browser/download_row.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" +#include "components/security_state/core/security_state.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_types.h" @@ -684,6 +686,17 @@ } #endif +// Tests that the SecurityLevel histograms are logged for save page downloads. +IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, SecurityLevelHistogram) { + base::HistogramTester histogram_tester; + GURL url = NavigateToMockURL("a"); + base::FilePath full_file_name, dir; + SaveCurrentTab(url, content::SAVE_PAGE_TYPE_AS_ONLY_HTML, "a", 1, &dir, + &full_file_name); + histogram_tester.ExpectUniqueSample("Security.SecurityLevel.DownloadStarted", + security_state::NONE, 1); +} + class SavePageAsMHTMLBrowserTest : public SavePageBrowserTest { public: SavePageAsMHTMLBrowserTest() {}
diff --git a/chrome/browser/extensions/chrome_extension_web_contents_observer.cc b/chrome/browser/extensions/chrome_extension_web_contents_observer.cc index 0044910..56e34e8 100644 --- a/chrome/browser/extensions/chrome_extension_web_contents_observer.cc +++ b/chrome/browser/extensions/chrome_extension_web_contents_observer.cc
@@ -40,8 +40,19 @@ ChromeExtensionWebContentsObserver::~ChromeExtensionWebContentsObserver() {} +// static +void ChromeExtensionWebContentsObserver::CreateForWebContents( + content::WebContents* web_contents) { + content::WebContentsUserData< + ChromeExtensionWebContentsObserver>::CreateForWebContents(web_contents); + + // Initialize this instance if necessary. + FromWebContents(web_contents)->Initialize(); +} + void ChromeExtensionWebContentsObserver::RenderFrameCreated( content::RenderFrameHost* render_frame_host) { + DCHECK(initialized()); ReloadIfTerminated(render_frame_host); ExtensionWebContentsObserver::RenderFrameCreated(render_frame_host); @@ -82,12 +93,14 @@ void ChromeExtensionWebContentsObserver::DidFinishNavigation( content::NavigationHandle* navigation_handle) { + DCHECK(initialized()); ExtensionWebContentsObserver::DidFinishNavigation(navigation_handle); } bool ChromeExtensionWebContentsObserver::OnMessageReceived( const IPC::Message& message, content::RenderFrameHost* render_frame_host) { + DCHECK(initialized()); if (ExtensionWebContentsObserver::OnMessageReceived(message, render_frame_host)) { return true; @@ -109,6 +122,7 @@ const base::string16& source, const StackTrace& stack_trace, int32_t severity_level) { + DCHECK(initialized()); if (!IsSourceFromAnExtension(source)) return; @@ -127,6 +141,7 @@ void ChromeExtensionWebContentsObserver::InitializeRenderFrame( content::RenderFrameHost* render_frame_host) { + DCHECK(initialized()); ExtensionWebContentsObserver::InitializeRenderFrame(render_frame_host); WindowController* controller = dispatcher()->GetExtensionWindowController(); if (controller) { @@ -137,6 +152,7 @@ void ChromeExtensionWebContentsObserver::ReloadIfTerminated( content::RenderFrameHost* render_frame_host) { + DCHECK(initialized()); std::string extension_id = GetExtensionIdFromFrame(render_frame_host); if (extension_id.empty()) return;
diff --git a/chrome/browser/extensions/chrome_extension_web_contents_observer.h b/chrome/browser/extensions/chrome_extension_web_contents_observer.h index d6d97fb6..1ecf8ae4 100644 --- a/chrome/browser/extensions/chrome_extension_web_contents_observer.h +++ b/chrome/browser/extensions/chrome_extension_web_contents_observer.h
@@ -29,6 +29,10 @@ public: ~ChromeExtensionWebContentsObserver() override; + // Creates and initializes an instance of this class for the given + // |web_contents|, if it doesn't already exist. + static void CreateForWebContents(content::WebContents* web_contents); + private: friend class content::WebContentsUserData<ChromeExtensionWebContentsObserver>;
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index c63b2f1..334daec 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -2683,6 +2683,10 @@ "Enable IME extensions to supply custom views for user input such as " "virtual keyboards."; +const char kLockScreenNotificationName[] = "Lock screen notification"; +const char kLockScreenNotificationDescription[] = + "Enable notifications on the lock screen."; + const char kMemoryPressureThresholdName[] = "Memory discard strategy for advanced pressure handling"; const char kMemoryPressureThresholdDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index cd90f621..a3333853 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1662,6 +1662,9 @@ extern const char kInputViewName[]; extern const char kInputViewDescription[]; +extern const char kLockScreenNotificationName[]; +extern const char kLockScreenNotificationDescription[]; + extern const char kMemoryPressureThresholdName[]; extern const char kMemoryPressureThresholdDescription[]; extern const char kConservativeThresholds[];
diff --git a/chrome/browser/media/webrtc/webrtc_browsertest.cc b/chrome/browser/media/webrtc/webrtc_browsertest.cc index 70b5ba7..94cd801f 100644 --- a/chrome/browser/media/webrtc/webrtc_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_browsertest.cc
@@ -12,9 +12,9 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "content/public/common/buildflags.h" #include "content/public/common/content_switches.h" #include "content/public/common/feature_h264_with_openh264_ffmpeg.h" -#include "content/public/common/features.h" #include "content/public/test/browser_test_utils.h" #include "media/base/media_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h"
diff --git a/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc b/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc index ed531ca..cee51750 100644 --- a/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_desktop_capture_browsertest.cc
@@ -12,9 +12,9 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "content/public/common/buildflags.h" #include "content/public/common/content_switches.h" #include "content/public/common/feature_h264_with_openh264_ffmpeg.h" -#include "content/public/common/features.h" #include "content/public/test/browser_test_utils.h" #include "media/base/media_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h"
diff --git a/chrome/browser/media/webrtc/webrtc_internals_perf_browsertest.cc b/chrome/browser/media/webrtc/webrtc_internals_perf_browsertest.cc index f92760f9..9f8b40a 100644 --- a/chrome/browser/media/webrtc/webrtc_internals_perf_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_internals_perf_browsertest.cc
@@ -22,9 +22,9 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" +#include "content/public/common/buildflags.h" #include "content/public/common/content_switches.h" #include "content/public/common/feature_h264_with_openh264_ffmpeg.h" -#include "content/public/common/features.h" #include "content/public/test/browser_test_utils.h" #include "media/base/media_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h"
diff --git a/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc b/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc index 7cf813df..eda6c34 100644 --- a/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc +++ b/chrome/browser/media/webrtc/webrtc_video_quality_browsertest.cc
@@ -31,8 +31,8 @@ #include "chrome/test/base/in_process_browser_test.h" #include "components/infobars/core/infobar.h" #include "content/public/browser/notification_service.h" +#include "content/public/common/buildflags.h" #include "content/public/common/feature_h264_with_openh264_ffmpeg.h" -#include "content/public/common/features.h" #include "content/public/test/browser_test_utils.h" #include "media/base/media_switches.h" #include "net/test/embedded_test_server/embedded_test_server.h"
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 2739c86..21b388e 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -1791,6 +1791,40 @@ WaitForElementValue("username_id", "temp"); } +// Test that if the same dynamic form is created multiple times then all of them +// are autofilled and no unnecessary PasswordStore requests are fired. +IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, + DuplicateFormsGetFilled) { + // At first let us save a credential to the password store. + scoped_refptr<password_manager::TestPasswordStore> password_store = + static_cast<password_manager::TestPasswordStore*>( + PasswordStoreFactory::GetForProfile( + browser()->profile(), ServiceAccessType::IMPLICIT_ACCESS) + .get()); + autofill::PasswordForm signin_form; + signin_form.signon_realm = embedded_test_server()->base_url().spec(); + signin_form.origin = embedded_test_server()->base_url(); + signin_form.action = embedded_test_server()->base_url(); + signin_form.username_value = base::ASCIIToUTF16("temp"); + signin_form.password_value = base::ASCIIToUTF16("random"); + password_store->AddLogin(signin_form); + + NavigateToFile("/password/recurring_dynamic_form.html"); + ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), "addForm();")); + // Wait until the username is filled, to make sure autofill kicked in. + WaitForJsElementValue("document.body.children[0].children[0]", "temp"); + WaitForJsElementValue("document.body.children[0].children[1]", "random"); + + // It's a trick. There should be no second request to the password store since + // the existing PasswordFormManager will manage the new form. + password_store->Clear(); + // Add one more form. + ASSERT_TRUE(content::ExecuteScript(RenderViewHost(), "addForm();")); + // Wait until the username is filled, to make sure autofill kicked in. + WaitForJsElementValue("document.body.children[1].children[0]", "temp"); + WaitForJsElementValue("document.body.children[1].children[1]", "random"); +} + IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTestBase, PromptForPushStateWhenFormDisappears) { NavigateToFile("/password/password_push_state.html");
diff --git a/chrome/browser/password_manager/password_manager_test_base.cc b/chrome/browser/password_manager/password_manager_test_base.cc index a9fc753f..757d888 100644 --- a/chrome/browser/password_manager/password_manager_test_base.cc +++ b/chrome/browser/password_manager/password_manager_test_base.cc
@@ -583,12 +583,21 @@ const std::string& form_id, size_t elements_index, const std::string& expected_value) { + const std::string element_selector = + base::StringPrintf("document.getElementById('%s').elements['%zu']", + form_id.c_str(), elements_index); + WaitForJsElementValue(element_selector, expected_value); +} + +void PasswordManagerBrowserTestBase::WaitForJsElementValue( + const std::string& element_selector, + const std::string& expected_value) { const std::string value_check_function = base::StringPrintf( "function valueCheck() {" - " var element = document.getElementById('%s').elements['%zu'];" + " var element = %s;" " return element && element.value == '%s';" "}", - form_id.c_str(), elements_index, expected_value.c_str()); + element_selector.c_str(), expected_value.c_str()); const std::string script = value_check_function + base::StringPrintf( @@ -596,7 +605,7 @@ " /* Spin the event loop with setTimeout. */" " setTimeout(window.domAutomationController.send(%d), 0);" "} else {" - " var element = document.getElementById('%s').elements['%zu'];" + " var element = %s;" " if (!element)" " window.domAutomationController.send(%d);" " element.onchange = function() {" @@ -614,13 +623,13 @@ " element.onchange = undefined;" " };" "}", - RETURN_CODE_OK, form_id.c_str(), elements_index, - RETURN_CODE_NO_ELEMENT, RETURN_CODE_OK, RETURN_CODE_WRONG_VALUE); + RETURN_CODE_OK, element_selector.c_str(), RETURN_CODE_NO_ELEMENT, + RETURN_CODE_OK, RETURN_CODE_WRONG_VALUE); int return_value = RETURN_CODE_INVALID; ASSERT_TRUE(content::ExecuteScriptWithoutUserGestureAndExtractInt( RenderFrameHost(), script, &return_value)); EXPECT_EQ(RETURN_CODE_OK, return_value) - << "form_id = " << form_id << "elements_index=" << elements_index + << "element_selector = " << element_selector << ", expected_value = " << expected_value; }
diff --git a/chrome/browser/password_manager/password_manager_test_base.h b/chrome/browser/password_manager/password_manager_test_base.h index cd9af29..3e8d25b 100644 --- a/chrome/browser/password_manager/password_manager_test_base.h +++ b/chrome/browser/password_manager/password_manager_test_base.h
@@ -175,6 +175,11 @@ size_t element_index, const std::string& expected_value); + // Same as above except the element is selected with |element_selector| JS + // expression. + void WaitForJsElementValue(const std::string& element_selector, + const std::string& expected_value); + // Make sure that the password store processed all the previous calls which // are executed on another thread. void WaitForPasswordStore();
diff --git a/chrome/browser/policy/policy_network_browsertest.cc b/chrome/browser/policy/policy_network_browsertest.cc index 57a51ca..56e589c 100644 --- a/chrome/browser/policy/policy_network_browsertest.cc +++ b/chrome/browser/policy/policy_network_browsertest.cc
@@ -18,7 +18,6 @@ #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" -#include "components/grpc_support/test/quic_test_server.h" #include "components/network_session_configurator/common/network_switches.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" @@ -34,6 +33,7 @@ #include "net/cert/test_root_certs.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_transaction_factory.h" +#include "net/test/quic_simple_test_server.h" #include "net/test/test_data_directory.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" @@ -76,10 +76,8 @@ } bool IsQuicEnabled(network::mojom::NetworkContext* network_context) { - GURL url = - GURL(std::string("https://") + grpc_support::kTestServerHost + ":" + - base::NumberToString(grpc_support::GetQuicTestServerPort()) + - grpc_support::kHelloPath); + GURL url = net::QuicSimpleTestServer::GetFileURL( + net::QuicSimpleTestServer::GetHelloPath()); int rv = content::LoadBasicRequest(network_context, url); return rv == net::OK; } @@ -138,7 +136,7 @@ net::TestRootCerts* root_certs = net::TestRootCerts::GetInstance(); root_certs->AddFromFile( net::GetTestCertsDirectory().AppendASCII("quic-root.pem")); - grpc_support::StartQuicTestServer(); + net::QuicSimpleTestServer::Start(); host_resolver()->AddRule("*", "127.0.0.1"); } };
diff --git a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc index 65481d1..6c4ec622 100644 --- a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc +++ b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
@@ -47,60 +47,13 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_context_getter.h" #include "services/network/public/cpp/features.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" #include "testing/gtest/include/gtest/gtest.h" using prerender::test_utils::DestructionWaiter; using prerender::test_utils::RequestCounter; using prerender::test_utils::TestPrerender; -namespace { - -// Helper method that verifies cookies for PrefetchCookies* tests. When the -// cookies expected from loading test/data/prerender/cookie.{js,html}. |loop| is -// notified when the cookies are found; if the cookies are not found this will -// wait forever. -void CheckCookiesForPrefetchCookieTest(base::RunLoop* loop, - GURL url, - net::CookieStore* cookie_store, - const net::CookieList& cookies) { - bool found_chocolate = false; - bool found_oatmeal = false; - for (const auto& c : cookies) { - if (c.Name() == "chocolate-chip") { - EXPECT_EQ("the-best", c.Value()); - found_chocolate = true; - } - if (c.Name() == "oatmeal") { - EXPECT_EQ("sublime", c.Value()); - found_oatmeal = true; - } - } - if (found_oatmeal && found_chocolate) { - loop->Quit(); - } else { - content::BrowserThread::PostDelayedTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(&net::CookieStore::GetAllCookiesForURLAsync, - base::Unretained(cookie_store), url, - base::BindOnce(CheckCookiesForPrefetchCookieTest, loop, - url, cookie_store)), - base::TimeDelta::FromMilliseconds(250)); - } -} - -// Launches the CheckCookiesForPrefetchCookieTest from the IO thread. -void LaunchPrefetchCookieTestFromIO(content::StoragePartition* storage, - base::RunLoop* loop, - GURL url) { - net::CookieStore* cookie_store = - storage->GetURLRequestContext()->GetURLRequestContext()->cookie_store(); - cookie_store->GetAllCookiesForURLAsync( - url, base::BindOnce(CheckCookiesForPrefetchCookieTest, loop, url, - cookie_store)); -} - -} // namespace - namespace prerender { const char k302RedirectPage[] = "/prerender/302_redirect.html"; @@ -276,6 +229,24 @@ WaitForRequestCount(src_server()->GetURL(kPrefetchScript2), 0); } +void GetCookieCallback(base::RepeatingClosure callback, + const net::CookieList& cookie_list) { + bool found_chocolate = false; + bool found_oatmeal = false; + for (const auto& c : cookie_list) { + if (c.Name() == "chocolate-chip") { + EXPECT_EQ("the-best", c.Value()); + found_chocolate = true; + } + if (c.Name() == "oatmeal") { + EXPECT_EQ("sublime", c.Value()); + found_oatmeal = true; + } + } + CHECK(found_chocolate && found_oatmeal); + callback.Run(); +} + // Check cookie loading for prefetched pages. IN_PROC_BROWSER_TEST_P(NoStatePrefetchBrowserTest, PrefetchCookie) { GURL url = src_server()->GetURL(kPrefetchCookiePage); @@ -285,13 +256,11 @@ content::StoragePartition* storage_partition = content::BrowserContext::GetStoragePartitionForSite( current_browser()->profile(), url, false); + net::CookieOptions options; base::RunLoop loop; - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(LaunchPrefetchCookieTestFromIO, storage_partition, &loop, - url)); + storage_partition->GetCookieManagerForBrowserProcess()->GetCookieList( + url, options, base::BindOnce(GetCookieCallback, loop.QuitClosure())); loop.Run(); - // Will timeout if cookies aren't found. } // Check cookie loading for a cross-domain prefetched pages. @@ -307,13 +276,12 @@ content::StoragePartition* storage_partition = content::BrowserContext::GetStoragePartitionForSite( current_browser()->profile(), cross_domain_url, false); + net::CookieOptions options; base::RunLoop loop; - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce(LaunchPrefetchCookieTestFromIO, storage_partition, &loop, - cross_domain_url)); + storage_partition->GetCookieManagerForBrowserProcess()->GetCookieList( + cross_domain_url, options, + base::BindOnce(GetCookieCallback, loop.QuitClosure())); loop.Run(); - // Will timeout if cookies aren't found. } // Check that the LOAD_PREFETCH flag is set.
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js index d79272d..ac05c71 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/automation_predicate.js
@@ -237,6 +237,24 @@ AutomationPredicate.formField(node))) return true; + // Containers who have name from contents should be treated like objects if + // the contents is all static text and not large. + if (node.name && node.nameFrom == 'contents') { + var onlyStaticText = true; + var textLength = 0; + for (var i = 0, child; child = node.children[i]; i++) { + if (child.role != Role.STATIC_TEXT) { + onlyStaticText = false; + break; + } + textLength += child.name ? child.name.length + textLength : textLength; + } + + if (onlyStaticText && textLength > 0 && + textLength < constants.OBJECT_MAX_CHARCOUNT) + return true; + } + // Otherwise, leaf or static text nodes that don't contain only whitespace // should be visited with the exception of non-text only nodes. This covers // cases where an author might make a link with a name of ' '.
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs index bc3b7943..8f0e620 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
@@ -175,6 +175,8 @@ .expectSpeech('foxtraut', 'Heading 2') .expectBraille('foxtraut h2'); mockFeedback.call(doCmd('nextLine')) + .expectSpeech('foxtraut'); + mockFeedback.call(doCmd('nextLine')) .expectSpeech('end', 'of test') .expectBraille('endof test');
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js index 69f23733..d0bbf33 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output.js
@@ -1083,12 +1083,19 @@ options.annotation.push('name'); this.append_(buff, node.name || '', options); } else if (token == 'nameOrDescendants') { + // This token is similar to nameOrTextContent except it gathers rich + // output for descendants. It also lets name from contents override + // the descendants text if |node| has only static text children. options.annotation.push(token); if (node.name && - node.nameFrom != chrome.automation.NameFromType.CONTENTS) + (node.nameFrom != 'contents' || + node.children.every(function(child) { + return child.role == RoleType.STATIC_TEXT; + }))) { this.append_(buff, node.name || '', options); - else + } else { this.format_(node, '$descendants', buff); + } } else if (token == 'description') { if (node.name == node.description || node.value == node.description) return; @@ -1280,7 +1287,7 @@ } } } else if (token == 'nameOrTextContent') { - if (node.name) { + if (node.name && node.nameFrom != 'contents') { this.format_(node, '$name', buff); return; }
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs index 0a80a128..b887ea09 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/output_test.extjs
@@ -190,12 +190,11 @@ var letter = String.fromCharCode('a'.charCodeAt(0) + i -1); assertEqualsJSON({string_: letter + '|Heading ' + i, 'spans_': [ // Attributes. - {value: 'name', start: 0, end: 1} + {value: 'nameOrDescendants', start: 0, end: 1} ]}, o.speechOutputForTest); checkBrailleOutput( letter + ' h' + i, [ - {value: new Output.NodeSpan(el.firstChild), start: 0, end: 1}, {value: new Output.NodeSpan(el), start: 0, end: 4} ], o); @@ -624,7 +623,7 @@ {value: {'relativePitch': toFixed(-0.1 * i)}, start: 0, end: 0}, // Attributes. - {value: 'name', start: 0, end: 1}, + {value: 'nameOrDescendants', start: 0, end: 1}, {value: {'relativePitch': -0.2}, start: 2, end: 2} ]}, o.speechOutputForTest);
diff --git a/chrome/browser/sync/test/integration/sync_test.cc b/chrome/browser/sync/test/integration/sync_test.cc index 78a2a58..49c54db 100644 --- a/chrome/browser/sync/test/integration/sync_test.cc +++ b/chrome/browser/sync/test/integration/sync_test.cc
@@ -1206,16 +1206,6 @@ ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path)); } -void SyncTest::TriggerCreateSyncedBookmarks() { - ASSERT_TRUE(ServerSupportsErrorTriggering()); - std::string path = "chromiumsync/createsyncedbookmarks"; - ui_test_utils::NavigateToURL(browser(), sync_server_.GetURL(path)); - ASSERT_EQ("Synced Bookmarks", - base::UTF16ToASCII( - browser()->tab_strip_model()->GetActiveWebContents()-> - GetTitle())); -} - fake_server::FakeServer* SyncTest::GetFakeServer() const { return fake_server_.get(); }
diff --git a/chrome/browser/sync/test/integration/sync_test.h b/chrome/browser/sync/test/integration/sync_test.h index 6e1fac1..03adc6eef 100644 --- a/chrome/browser/sync/test/integration/sync_test.h +++ b/chrome/browser/sync/test/integration/sync_test.h
@@ -244,9 +244,6 @@ // stay in this state until shut down. void TriggerXmppAuthError(); - // Triggers the creation the Synced Bookmarks folder on the server. - void TriggerCreateSyncedBookmarks(); - // Returns the FakeServer being used for the test or null if FakeServer is // not being used. fake_server::FakeServer* GetFakeServer() const;
diff --git a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc index d5169eb..ff2a813 100644 --- a/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_bookmarks_sync_test.cc
@@ -28,6 +28,7 @@ #include "components/policy/policy_constants.h" #include "components/sync/driver/sync_service.h" #include "components/sync/engine/cycle/sync_cycle_snapshot.h" +#include "components/sync/engine_impl/loopback_server/persistent_permanent_entity.h" #include "testing/gmock/include/gmock/gmock.h" #include "ui/base/layout.h" @@ -94,15 +95,6 @@ DISALLOW_COPY_AND_ASSIGN(TwoClientBookmarksSyncTest); }; -class LegacyTwoClientBookmarksSyncTest : public SyncTest { - public: - LegacyTwoClientBookmarksSyncTest() : SyncTest(TWO_CLIENT_LEGACY) {} - ~LegacyTwoClientBookmarksSyncTest() override {} - - private: - DISALLOW_COPY_AND_ASSIGN(LegacyTwoClientBookmarksSyncTest); -}; - IN_PROC_BROWSER_TEST_F(TwoClientBookmarksSyncTest, Sanity) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; ASSERT_TRUE(AllModelsMatchVerifier()); @@ -1600,8 +1592,7 @@ ASSERT_FALSE(ContainsDuplicateBookmarks(0)); } -// This test fails when run with FakeServer and FakeServerInvalidationService. -IN_PROC_BROWSER_TEST_F(LegacyTwoClientBookmarksSyncTest, MC_DeleteBookmark) { +IN_PROC_BROWSER_TEST_F(TwoClientBookmarksSyncTest, MC_DeleteBookmark) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; ASSERT_TRUE(GetClient(1)->DisableSyncForDatatype(syncer::BOOKMARKS)); @@ -1926,13 +1917,15 @@ // Trigger the server side creation of Synced Bookmarks. Ensure both clients // remain syncing afterwards. Add bookmarks to the synced bookmarks folder -// and ensure both clients receive the boomkmark. -IN_PROC_BROWSER_TEST_F(LegacyTwoClientBookmarksSyncTest, - CreateSyncedBookmarks) { +// and ensure both clients receive the bookmark. +IN_PROC_BROWSER_TEST_F(TwoClientBookmarksSyncTest, CreateSyncedBookmarks) { ASSERT_TRUE(SetupSync()) << "SetupSync() failed."; ASSERT_TRUE(AllModelsMatchVerifier()); - TriggerCreateSyncedBookmarks(); + fake_server_->InjectEntity(syncer::PersistentPermanentEntity::CreateNew( + syncer::BOOKMARKS, "synced_bookmarks", "Synced Bookmarks", + "google_chrome_bookmarks")); + ASSERT_TRUE(BookmarksMatchChecker().Wait()); // Add a bookmark on Client 0 and ensure it syncs over. This will also trigger // both clients downloading the new Synced Bookmarks folder.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 43b689d..3c4217e 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1396,6 +1396,8 @@ "omnibox/clipboard_utils.h", "omnibox/favicon_cache.cc", "omnibox/favicon_cache.h", + "omnibox/omnibox_theme.cc", + "omnibox/omnibox_theme.h", "overlay/overlay_surface_embedder.cc", "overlay/overlay_surface_embedder.h", "overlay/overlay_window.h",
diff --git a/chrome/browser/ui/omnibox/omnibox_theme.cc b/chrome/browser/ui/omnibox/omnibox_theme.cc new file mode 100644 index 0000000..b552b81 --- /dev/null +++ b/chrome/browser/ui/omnibox/omnibox_theme.cc
@@ -0,0 +1,87 @@ +// 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/omnibox/omnibox_theme.h" + +#include "base/logging.h" +#include "ui/base/material_design/material_design_controller.h" +#include "ui/gfx/color_palette.h" +#include "ui/gfx/color_utils.h" +#include "ui/native_theme/native_theme.h" + +#if defined(USE_AURA) +#include "ui/native_theme/native_theme_dark_aura.h" +#endif + +namespace { + +constexpr ui::NativeTheme::ColorId kInvalidColorId = + ui::NativeTheme::kColorId_NumColors; + +template <class T> +constexpr T NormalHoveredSelectedOrBoth(OmniboxState state, + T normal, + T hovered, + T selected, + T hovered_and_selected) { + const T args[] = {normal, hovered, selected, hovered_and_selected}; + return args[static_cast<size_t>(state)]; +} + +template <class T> +constexpr T NormalHoveredSelected(OmniboxState state, + T normal, + T hovered, + T selected) { + // Use selected if state is HOVERED_AND_SELECTED. + const T args[] = {normal, hovered, selected, selected}; + return args[static_cast<size_t>(state)]; +} + +ui::NativeTheme::ColorId GetLegacyColorId(OmniboxPart part, + OmniboxState state) { + using NativeId = ui::NativeTheme::ColorId; + switch (part) { + case OmniboxPart::RESULTS_BACKGROUND: + return NormalHoveredSelected( + state, NativeId::kColorId_ResultsTableNormalBackground, + NativeId::kColorId_ResultsTableHoveredBackground, + NativeId::kColorId_ResultsTableSelectedBackground); + } + return kInvalidColorId; +} + +SkColor GetLegacyColor(OmniboxPart part, OmniboxTint tint, OmniboxState state) { + ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForNativeUi(); +#if defined(USE_AURA) + if (tint == OmniboxTint::DARK) + native_theme = ui::NativeThemeDarkAura::instance(); +#endif + + ui::NativeTheme::ColorId color_id = GetLegacyColorId(part, state); + return color_id == kInvalidColorId ? gfx::kPlaceholderColor + : native_theme->GetSystemColor(color_id); +} + +} // namespace + +SkColor GetOmniboxColor(OmniboxPart part, + OmniboxTint tint, + OmniboxState state) { + if (!ui::MaterialDesignController::IsTouchOptimizedUiEnabled()) + return GetLegacyColor(part, tint, state); + + const bool dark = tint == OmniboxTint::DARK; + + switch (part) { + case OmniboxPart::RESULTS_BACKGROUND: + // The spec calls for transparent black (or white) overlays for hover (6%) + // and select (8%), which can overlap (for 14%). Pre-blend these with the + // background for the best text AA result. + return color_utils::BlendTowardOppositeLuma( + dark ? gfx::kGoogleGrey800 : SK_ColorWHITE, + NormalHoveredSelectedOrBoth<SkAlpha>(state, 0x00, 0x0f, 0x14, 0x24)); + } + return gfx::kPlaceholderColor; +}
diff --git a/chrome/browser/ui/omnibox/omnibox_theme.h b/chrome/browser/ui/omnibox/omnibox_theme.h new file mode 100644 index 0000000..8fb24cd8 --- /dev/null +++ b/chrome/browser/ui/omnibox/omnibox_theme.h
@@ -0,0 +1,27 @@ +// 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_OMNIBOX_OMNIBOX_THEME_H_ +#define CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_THEME_H_ + +#include "third_party/skia/include/core/SkColor.h" + +// A part of the omnibox (location bar, location bar decoration, or dropdown). +enum class OmniboxPart { + RESULTS_BACKGROUND, // Background of the results dropdown. +}; + +// The tint of the omnibox theme. E.g. Incognito may use a DARK tint. +enum class OmniboxTint { DARK, LIGHT }; + +// An optional state for a given |OmniboxPart|. +enum class OmniboxState { NORMAL, HOVERED, SELECTED, HOVERED_AND_SELECTED }; + +// Returns the color for the given |part| and |tint|. An optional |state| can be +// provided for OmniboxParts that support stateful colors. +SkColor GetOmniboxColor(OmniboxPart part, + OmniboxTint tint, + OmniboxState state = OmniboxState::NORMAL); + +#endif // CHROME_BROWSER_UI_OMNIBOX_OMNIBOX_THEME_H_
diff --git a/chrome/browser/ui/overlay/overlay_surface_embedder.cc b/chrome/browser/ui/overlay/overlay_surface_embedder.cc index 888c17c..79d7f07e 100644 --- a/chrome/browser/ui/overlay/overlay_surface_embedder.cc +++ b/chrome/browser/ui/overlay/overlay_surface_embedder.cc
@@ -13,9 +13,14 @@ surface_layer_->SetMasksToBounds(true); // The frame provided by the parent window's layer needs to show through - // the surface layer. + // |surface_layer_|. surface_layer_->SetFillsBoundsOpaquely(false); - surface_layer_->SetBounds(window_->GetBounds()); + // |surface_layer_| bounds are set with the (0, 0) origin point. The + // positioning of |window_| is dictated by itself. + // TODO(apacible): Update |surface_layer_| size when the window is resized. + // http://crbug.com/726621 + surface_layer_->SetBounds( + gfx::Rect(gfx::Point(0, 0), window_->GetBounds().size())); window_->GetLayer()->Add(surface_layer_.get()); }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm index 381e8b5..3562bf8 100644 --- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm +++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_mac.mm
@@ -128,18 +128,6 @@ // BrowserNonClientFrameViewMac, protected: // views::View: -void BrowserNonClientFrameViewMac::OnPaint(gfx::Canvas* canvas) { - if (!browser_view()->IsBrowserTypeNormal()) - return; - - canvas->DrawColor(GetFrameColor()); - - if (!GetThemeProvider()->UsingSystemTheme()) - PaintThemedFrame(canvas); - - if (browser_view()->IsToolbarVisible()) - PaintToolbarBackground(canvas); -} void BrowserNonClientFrameViewMac::Layout() { DCHECK(browser_view()); @@ -166,6 +154,19 @@ BrowserNonClientFrameView::Layout(); } +void BrowserNonClientFrameViewMac::OnPaint(gfx::Canvas* canvas) { + if (!browser_view()->IsBrowserTypeNormal()) + return; + + canvas->DrawColor(GetFrameColor()); + + if (!GetThemeProvider()->UsingSystemTheme()) + PaintThemedFrame(canvas); + + if (browser_view()->IsToolbarVisible()) + PaintToolbarBackground(canvas); +} + // BrowserNonClientFrameView: AvatarButtonStyle BrowserNonClientFrameViewMac::GetAvatarButtonStyle() const { return AvatarButtonStyle::NATIVE;
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index b4c9e443..889cb49 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/themes/theme_service.h" +#include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/translate/translate_service.h" #include "chrome/browser/ui/autofill/save_card_bubble_controller_impl.h" @@ -35,6 +36,7 @@ #include "chrome/browser/ui/find_bar/find_bar_controller.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/omnibox/chrome_omnibox_client.h" +#include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/passwords/manage_passwords_ui_controller.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/views/autofill/save_card_icon_view.h" @@ -123,6 +125,16 @@ ui::MaterialDesignController::MATERIAL_TOUCH_OPTIMIZED; } +OmniboxTint GetTintForProfile(Profile* profile) { + if (ThemeServiceFactory::GetForProfile(profile)->UsingDefaultTheme()) { + return profile->GetProfileType() == Profile::INCOGNITO_PROFILE + ? OmniboxTint::DARK + : OmniboxTint::LIGHT; + } + // TODO(tapted): Infer a tint from theme colors? + return OmniboxTint::LIGHT; +} + } // namespace // LocationBarView ----------------------------------------------------------- @@ -139,7 +151,8 @@ ChromeOmniboxEditController(command_updater), browser_(browser), delegate_(delegate), - is_popup_mode_(is_popup_mode) { + is_popup_mode_(is_popup_mode), + tint_(GetTintForProfile(profile)) { edit_bookmarks_enabled_.Init( bookmarks::prefs::kEditBookmarksEnabled, profile->GetPrefs(), base::Bind(&LocationBarView::UpdateWithoutTabRestore,
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index 22abc9b5..b11b7c55 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -40,6 +40,7 @@ class KeywordHintView; class LocationIconView; class ManagePasswordsIconViews; +enum class OmniboxTint; class Profile; class SelectedKeywordView; class StarView; @@ -129,6 +130,9 @@ SkColor GetSecureTextColor( security_state::SecurityLevel security_level) const; + // Returns the theme color tint for the location bar and results. + OmniboxTint tint() const { return tint_; } + // Returns the delegate. Delegate* delegate() const { return delegate_; } @@ -422,6 +426,9 @@ // bar is read-only. const bool is_popup_mode_; + // The theme tint. Initialized based on the profile and theme settings. + const OmniboxTint tint_; + // True if we should show a focus rect while the location entry field is // focused. Used when the toolbar is in full keyboard accessibility mode. bool show_focus_rect_ = false;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc index 74cc2b3..4ccf59c 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.cc
@@ -15,6 +15,7 @@ #include "build/build_config.h" #include "chrome/browser/search/search.h" #include "chrome/browser/themes/theme_properties.h" +#include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/browser/ui/views/omnibox/omnibox_result_view.h" #include "chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.h" @@ -146,6 +147,8 @@ : public ThemeCopyingWidget, public base::SupportsWeakPtr<AutocompletePopupWidget> { public: + // TODO(tapted): Remove |role_model| when the omnibox is completely decoupled + // from NativeTheme. explicit AutocompletePopupWidget(views::Widget* role_model) : ThemeCopyingWidget(role_model) {} ~AutocompletePopupWidget() override {} @@ -240,6 +243,11 @@ return model_->GetMatchIcon(match, vector_icon_color); } +OmniboxTint OmniboxPopupContentsView::GetTint() const { + // Use LIGHT in tests. + return location_bar_view_ ? location_bar_view_->tint() : OmniboxTint::LIGHT; +} + void OmniboxPopupContentsView::SetSelectedLine(size_t index) { DCHECK(HasMatchAt(index)); @@ -310,8 +318,8 @@ gfx::Rect new_target_bounds = UpdateMarginsAndGetTargetBounds(); if (IsNarrow() && !IsRounded()) { - SkColor background_color = GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_ResultsTableNormalBackground); + SkColor background_color = + GetOmniboxColor(OmniboxPart::RESULTS_BACKGROUND, GetTint()); auto border = std::make_unique<views::BubbleBorder>( views::BubbleBorder::NONE, views::BubbleBorder::SMALL_SHADOW, background_color); @@ -590,8 +598,8 @@ paint_info.paint_recording_scale_y())); { ui::PaintRecorder recorder(paint_info.context(), size()); - SkColor background_color = result_view_at(0)->GetColor( - OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND); + SkColor background_color = + GetOmniboxColor(OmniboxPart::RESULTS_BACKGROUND, GetTint()); recorder.canvas()->DrawColor(background_color); } View::PaintChildren(paint_info);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h index 7ac6c44..37c36333 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h
@@ -20,6 +20,7 @@ class LocationBarView; class OmniboxEditModel; class OmniboxResultView; +enum class OmniboxTint; class OmniboxView; // A view representing the contents of the autocomplete popup. @@ -40,6 +41,9 @@ gfx::Image GetMatchIcon(const AutocompleteMatch& match, SkColor vector_icon_color) const; + // Returns the theme color tint (e.g. dark or light). + OmniboxTint GetTint() const; + // Sets the line specified by |index| as selected. virtual void SetSelectedLine(size_t index);
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc index e4924dd01..a1a6fdd6 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.cc
@@ -22,6 +22,7 @@ #include "base/metrics/field_trial_params.h" #include "base/strings/string_util.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "chrome/browser/ui/views/omnibox/omnibox_popup_contents_view.h" @@ -74,12 +75,6 @@ OmniboxResultView::ResultViewState state; OmniboxResultView::ColorKind kind; } static const kTranslationTable[] = { - { NativeTheme::kColorId_ResultsTableNormalBackground, - OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND }, - { NativeTheme::kColorId_ResultsTableHoveredBackground, - OmniboxResultView::HOVERED, OmniboxResultView::BACKGROUND }, - { NativeTheme::kColorId_ResultsTableSelectedBackground, - OmniboxResultView::SELECTED, OmniboxResultView::BACKGROUND }, { NativeTheme::kColorId_ResultsTableNormalText, OmniboxResultView::NORMAL, OmniboxResultView::TEXT }, { NativeTheme::kColorId_ResultsTableHoveredText, @@ -231,7 +226,9 @@ if (state == NORMAL) { SetBackground(nullptr); } else { - SetBackground(CreateBackgroundWithColor(GetColor(state, BACKGROUND))); + SkColor color = GetOmniboxColor(OmniboxPart::RESULTS_BACKGROUND, GetTint(), + GetThemeState()); + SetBackground(CreateBackgroundWithColor(color)); } if (match_.answer) { @@ -278,6 +275,18 @@ return is_hovered_ ? HOVERED : NORMAL; } +OmniboxState OmniboxResultView::GetThemeState() const { + if (model_->IsSelectedIndex(model_index_)) { + return is_hovered_ ? OmniboxState::HOVERED_AND_SELECTED + : OmniboxState::SELECTED; + } + return is_hovered_ ? OmniboxState::HOVERED : OmniboxState::NORMAL; +} + +OmniboxTint OmniboxResultView::GetTint() const { + return model_->GetTint(); +} + void OmniboxResultView::OnMatchIconUpdated() { // The new icon will be fetched during repaint. SchedulePaint();
diff --git a/chrome/browser/ui/views/omnibox/omnibox_result_view.h b/chrome/browser/ui/views/omnibox/omnibox_result_view.h index 1d41078..6acf300 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_result_view.h +++ b/chrome/browser/ui/views/omnibox/omnibox_result_view.h
@@ -22,6 +22,8 @@ #include "ui/views/view.h" class OmniboxPopupContentsView; +enum class OmniboxState; +enum class OmniboxTint; namespace gfx { class Canvas; @@ -36,6 +38,7 @@ public: // Keep these ordered from least dominant (normal) to most dominant // (selected). + // TODO(tapted): Remove these: replace with OmniboxState. enum ResultViewState { NORMAL = 0, HOVERED, @@ -44,7 +47,6 @@ }; enum ColorKind { - BACKGROUND = 0, TEXT, DIMMED_TEXT, URL, @@ -72,6 +74,8 @@ void OnSelected(); ResultViewState GetState() const; + OmniboxState GetThemeState() const; + OmniboxTint GetTint() const; // Notification that the match icon has changed and schedules a repaint. void OnMatchIconUpdated();
diff --git a/chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.cc b/chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.cc index 99d8da7..463d97a 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.cc
@@ -4,23 +4,37 @@ #include "chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/omnibox/omnibox_theme.h" +#include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" +#include "chrome/browser/ui/views/omnibox/omnibox_result_view.h" +#include "components/omnibox/browser/vector_icons.h" #include "ui/gfx/color_utils.h" +#include "ui/gfx/paint_vector_icon.h" +#include "ui/views/controls/button/label_button_border.h" + +OmniboxTabSwitchButton::OmniboxTabSwitchButton(OmniboxResultView* result_view) + : LabelButton(this, base::ASCIIToUTF16("Switch to open tab")), + result_view_(result_view) { + // TODO: SetTooltipText(text); + // SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE); + SetBackground(std::make_unique<BackgroundWith1PxBorder>(GetBackgroundColor(), + SK_ColorBLACK)); + SetImage(STATE_NORMAL, + gfx::CreateVectorIcon(omnibox::kSwitchIcon, 16, SK_ColorBLACK)); +} void OmniboxTabSwitchButton::SetPressed() { - const SkColor bg_color = result_view_->GetColor( - OmniboxResultView::SELECTED, OmniboxResultView::BACKGROUND); // Using transparent does nothing, since the result view is also selected. - const SkColor pressed_color = - color_utils::AlphaBlend(bg_color, SK_ColorBLACK, 0.8 * 255); - SetBackground( - std::make_unique<BackgroundWith1PxBorder>(pressed_color, SK_ColorBLACK)); + background()->SetNativeControlColor(color_utils::AlphaBlend( + GetOmniboxColor(OmniboxPart::RESULTS_BACKGROUND, result_view_->GetTint()), + SK_ColorBLACK, 0.8 * 255)); SchedulePaint(); } void OmniboxTabSwitchButton::ClearState() { - // TODO: Consider giving this a non-transparent background. - SetBackground(nullptr); + background()->SetNativeControlColor(GetBackgroundColor()); SchedulePaint(); } @@ -62,11 +76,12 @@ } void OmniboxTabSwitchButton::StateChanged(ButtonState old_state) { - const SkColor bg_color = result_view_->GetColor( - state() == STATE_HOVERED ? OmniboxResultView::HOVERED - : OmniboxResultView::NORMAL, - OmniboxResultView::BACKGROUND); - SetBackground( - std::make_unique<BackgroundWith1PxBorder>(bg_color, SK_ColorBLACK)); + background()->SetNativeControlColor(GetBackgroundColor()); LabelButton::StateChanged(old_state); } + +SkColor OmniboxTabSwitchButton::GetBackgroundColor() const { + return GetOmniboxColor( + OmniboxPart::RESULTS_BACKGROUND, result_view_->GetTint(), + state() == STATE_HOVERED ? OmniboxState::HOVERED : OmniboxState::NORMAL); +}
diff --git a/chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.h b/chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.h index 16ef7ff..d2e9a72 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.h +++ b/chrome/browser/ui/views/omnibox/omnibox_tab_switch_button.h
@@ -5,29 +5,14 @@ #ifndef CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_TAB_SWITCH_BUTTON_H_ #define CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_TAB_SWITCH_BUTTON_H_ -#include "base/strings/utf_string_conversions.h" -#include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" -#include "chrome/browser/ui/views/omnibox/omnibox_result_view.h" -#include "components/omnibox/browser/vector_icons.h" -#include "ui/gfx/paint_vector_icon.h" #include "ui/views/controls/button/label_button.h" -#include "ui/views/controls/button/label_button_border.h" + +class OmniboxResultView; class OmniboxTabSwitchButton : public views::LabelButton, - views::ButtonListener { + public views::ButtonListener { public: - explicit OmniboxTabSwitchButton(OmniboxResultView* result_view) - : LabelButton(this, base::ASCIIToUTF16("Switch to open tab")), - result_view_(result_view) { - // TODO: SetTooltipText(text); - // SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE); - const SkColor bg_color = result_view_->GetColor( - OmniboxResultView::NORMAL, OmniboxResultView::BACKGROUND); - SetBackground( - std::make_unique<BackgroundWith1PxBorder>(bg_color, SK_ColorBLACK)); - SetImage(STATE_NORMAL, - gfx::CreateVectorIcon(omnibox::kSwitchIcon, 16, SK_ColorBLACK)); - } + explicit OmniboxTabSwitchButton(OmniboxResultView* result_view); void SetPressed(); void ClearState(); @@ -45,6 +30,8 @@ void StateChanged(ButtonState old_state) override; private: + SkColor GetBackgroundColor() const; + OmniboxResultView* result_view_; DISALLOW_COPY_AND_ASSIGN(OmniboxTabSwitchButton);
diff --git a/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc b/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc index 7850680..370a14a 100644 --- a/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc +++ b/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc
@@ -6,6 +6,7 @@ #include "build/build_config.h" #include "chrome/browser/ui/layout_constants.h" +#include "chrome/browser/ui/omnibox/omnibox_theme.h" #include "chrome/browser/ui/views/location_bar/background_with_1_px_border.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" #include "ui/compositor/layer.h" @@ -57,8 +58,8 @@ contents_host_->layer()->SetFillsBoundsOpaquely(false); // Use a solid background. Note this is clipped to get rounded corners. - SkColor background_color = GetNativeTheme()->GetSystemColor( - ui::NativeTheme::kColorId_ResultsTableNormalBackground); + SkColor background_color = + GetOmniboxColor(OmniboxPart::RESULTS_BACKGROUND, location_bar->tint()); contents_host_->SetBackground(views::CreateSolidBackground(background_color)); // Use a textured mask to clip contents. This doesn't work on Windows
diff --git a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc index 7b6120c..f017f274 100644 --- a/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc +++ b/chrome/browser/ui/views/passwords/account_chooser_dialog_view.cc
@@ -109,8 +109,10 @@ } void AccountChooserDialogView::ControllerGone() { - controller_ = nullptr; + // During Widget::Close() phase some accessibility event may occur. Thus, + // |controller_| should be kept around. GetWidget()->Close(); + controller_ = nullptr; } ui::ModalType AccountChooserDialogView::GetModalType() const { @@ -170,15 +172,22 @@ void AccountChooserDialogView::StyledLabelLinkClicked(views::StyledLabel* label, const gfx::Range& range, int event_flags) { - controller_->OnSmartLockLinkClicked(); + // On Mac the button click event may be dispatched after the dialog was + // hidden. Thus, the controller can be NULL. + if (controller_) + controller_->OnSmartLockLinkClicked(); } void AccountChooserDialogView::ButtonPressed(views::Button* sender, const ui::Event& event) { CredentialsItemView* view = static_cast<CredentialsItemView*>(sender); - controller_->OnChooseCredentials( - *view->form(), - password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD); + // On Mac the button click event may be dispatched after the dialog was + // hidden. Thus, the controller can be NULL. + if (controller_) { + controller_->OnChooseCredentials( + *view->form(), + password_manager::CredentialType::CREDENTIAL_TYPE_PASSWORD); + } } void AccountChooserDialogView::InitWindow() {
diff --git a/chrome/browser/ui/views/profiles/avatar_button.cc b/chrome/browser/ui/views/profiles/avatar_button.cc index 8f7525d..55318383 100644 --- a/chrome/browser/ui/views/profiles/avatar_button.cc +++ b/chrome/browser/ui/views/profiles/avatar_button.cc
@@ -46,7 +46,9 @@ namespace { +#if !defined(OS_MACOSX) constexpr int kGenericAvatarIconSize = 16; +#endif // TODO(emx): Calculate width based on caption button [http://crbug.com/716365] constexpr int kCondensibleButtonMinWidth = 46; @@ -76,10 +78,6 @@ } #endif -#if defined(OS_MACOSX) -constexpr int kHoverCornerRadius = 2; -#endif - // This class draws the border (and background) of the avatar button for // "themed" browser windows, i.e. OpaqueBrowserFrameView. Currently it's only // used on Linux as the shape specifically matches the Linux caption buttons. @@ -276,7 +274,7 @@ AvatarButton::~AvatarButton() {} void AvatarButton::SetupThemeColorButton() { -#if defined(OS_WIN) || defined(OS_MACOSX) +#if defined(OS_WIN) if (IsCondensible()) { // TODO(bsep): This needs to also be called when the Windows accent color // updates, but there is currently no signal for that. @@ -290,7 +288,13 @@ generic_avatar_ = gfx::CreateVectorIcon(kAccountCircleIcon, kGenericAvatarIconSize, icon_color); } -#endif // defined(OS_WIN) || defined(OS_MACOSX) +#elif defined(OS_MACOSX) + const SkColor text_color = color_utils::IsDark(GetThemeProvider()->GetColor( + ThemeProperties::COLOR_FRAME)) + ? SK_ColorWHITE + : SK_ColorBLACK; + SetEnabledTextColors(text_color); +#endif } void AvatarButton::OnAvatarButtonPressed(const ui::Event* event) { @@ -352,13 +356,17 @@ std::unique_ptr<views::InkDropMask> AvatarButton::CreateInkDropMask() const { #if defined(OS_MACOSX) + // On Mac, this looks and behaves like a regular MD button, so we need a hover + // background. // TODO (lgrey): Determine and set the correct insets. + constexpr int kHoverCornerRadius = 2; return std::make_unique<views::RoundRectInkDropMask>(size(), gfx::Insets(), kHoverCornerRadius); -#endif +#else if (button_style_ == AvatarButtonStyle::THEMED) return AvatarButtonThemedBorder::CreateInkDropMask(size()); return MenuButton::CreateInkDropMask(); +#endif } std::unique_ptr<views::InkDropHighlight> AvatarButton::CreateInkDropHighlight() @@ -374,12 +382,14 @@ return ink_drop_highlight; } -#if defined(OS_MACOSX) SkColor AvatarButton::GetInkDropBaseColor() const { +#if defined(OS_MACOSX) return GetThemeProvider()->GetColor( ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON); -} +#else + return MenuButton::GetInkDropBaseColor(); #endif +} bool AvatarButton::ShouldEnterPushedState(const ui::Event& event) { if (ProfileChooserView::IsShowing()) @@ -515,8 +525,9 @@ return true; #elif defined(OS_MACOSX) return true; -#endif +#else if (render_native_nav_buttons_) return false; return IsCondensible(); +#endif }
diff --git a/chrome/browser/ui/views/profiles/avatar_button.h b/chrome/browser/ui/views/profiles/avatar_button.h index 48c3197..e1b127198 100644 --- a/chrome/browser/ui/views/profiles/avatar_button.h +++ b/chrome/browser/ui/views/profiles/avatar_button.h
@@ -45,10 +45,8 @@ gfx::Size CalculatePreferredSize() const override; std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight() const override; - std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; -#if defined(OS_MACOSX) SkColor GetInkDropBaseColor() const override; -#endif + std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override; protected: // views::LabelButton:
diff --git a/chrome/browser/ui/views/session_crashed_bubble_view.cc b/chrome/browser/ui/views/session_crashed_bubble_view.cc index 81f303b..18989e5c3 100644 --- a/chrome/browser/ui/views/session_crashed_bubble_view.cc +++ b/chrome/browser/ui/views/session_crashed_bubble_view.cc
@@ -222,13 +222,6 @@ views::View* SessionCrashedBubbleView::CreateUmaOptInView() { RecordBubbleHistogramValue(SESSION_CRASHED_BUBBLE_OPTIN_BAR_SHOWN); - // Checkbox for metric reporting setting. - // Since the text to the right of the checkbox can't be a simple string (needs - // a hyperlink in it), this checkbox contains an empty string as its label, - // and the real text will be added as a separate view. - uma_option_ = new views::Checkbox(base::string16()); - uma_option_->SetChecked(false); - // The text to the right of the checkbox. size_t offset; base::string16 link_text = @@ -251,6 +244,11 @@ // Shift the text down by 1px to align with the checkbox. uma_label->SetBorder(views::CreateEmptyBorder(1, 0, 0, 0)); + // Checkbox for metric reporting setting. + uma_option_ = new views::Checkbox(base::string16()); + uma_option_->SetChecked(false); + uma_option_->SetAssociatedLabel(uma_label); + // Create a view to hold the checkbox and the text. views::View* uma_view = new views::View(); GridLayout* uma_layout =
diff --git a/chrome/browser/ui/views_mode_controller.cc b/chrome/browser/ui/views_mode_controller.cc index 6452151..9a673df 100644 --- a/chrome/browser/ui/views_mode_controller.cc +++ b/chrome/browser/ui/views_mode_controller.cc
@@ -5,13 +5,14 @@ #include "chrome/browser/ui/views_mode_controller.h" #include "chrome/common/chrome_features.h" +#include "ui/base/ui_base_features.h" #if defined(OS_MACOSX) && BUILDFLAG(MAC_VIEWS_BROWSER) namespace views_mode_controller { bool IsViewsBrowserCocoa() { - return !base::FeatureList::IsEnabled(features::kViewsBrowserWindows); + return features::IsViewsBrowserCocoa(); } } // namespace views_mode_controller
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc index bfcdab0..b664c08 100644 --- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc +++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.cc
@@ -5,11 +5,13 @@ #include "chrome/browser/ui/webui/signin/dice_turn_sync_on_helper.h" #include "base/bind.h" +#include "base/location.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" #include "base/metrics/user_metrics_action.h" #include "base/strings/utf_string_conversions.h" +#include "base/threading/sequenced_task_runner_handle.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/policy/cloud/user_policy_signin_service.h" #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h" @@ -71,7 +73,10 @@ DCHECK(!signin_util::IsForceSigninEnabled()); if (HasCanOfferSigninError()) { - AbortAndDelete(); + // Do not self-destruct synchronously in the constructor. + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&DiceTurnSyncOnHelper::AbortAndDelete, + base::Unretained(this))); return; }
diff --git a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc index 5e964de..d3925d2 100644 --- a/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc +++ b/chrome/browser/ui/webui/signin/dice_turn_sync_on_helper_unittest.cc
@@ -428,6 +428,7 @@ // Signin flow. CreateDiceTurnOnSyncHelper( DiceTurnSyncOnHelper::SigninAbortedMode::KEEP_ACCOUNT); + base::RunLoop().RunUntilIdle(); // Check expectations. EXPECT_FALSE(signin_manager()->IsAuthenticated()); EXPECT_TRUE(token_service()->RefreshTokenIsAvailable(account_id())); @@ -443,6 +444,7 @@ // Signin flow. CreateDiceTurnOnSyncHelper( DiceTurnSyncOnHelper::SigninAbortedMode::REMOVE_ACCOUNT); + base::RunLoop().RunUntilIdle(); // Check expectations. EXPECT_FALSE(signin_manager()->IsAuthenticated()); EXPECT_FALSE(token_service()->RefreshTokenIsAvailable(account_id()));
diff --git a/chrome/browser/ui/window_sizer/window_sizer.cc b/chrome/browser/ui/window_sizer/window_sizer.cc index 3adf2a6..a653307 100644 --- a/chrome/browser/ui/window_sizer/window_sizer.cc +++ b/chrome/browser/ui/window_sizer/window_sizer.cc
@@ -172,10 +172,10 @@ std::unique_ptr<StateProvider> state_provider, std::unique_ptr<TargetDisplayProvider> target_display_provider, const Browser* browser) - : state_provider_(std::move(state_provider)), - target_display_provider_(std::move(target_display_provider)), - screen_(display::Screen::GetScreen()), - browser_(browser) {} + : WindowSizer(std::move(state_provider), + std::move(target_display_provider), + display::Screen::GetScreen(), + browser) {} WindowSizer::WindowSizer( std::unique_ptr<StateProvider> state_provider, @@ -189,8 +189,7 @@ DCHECK(screen_); } -WindowSizer::~WindowSizer() { -} +WindowSizer::~WindowSizer() {} // static void WindowSizer::GetBrowserWindowBoundsAndShowState( @@ -404,25 +403,18 @@ if (!browser_) return ui::SHOW_STATE_DEFAULT; - // Only tabbed browsers use the command line or preference state, with the - // exception of devtools. - bool show_state = !browser_->is_type_tabbed() && !browser_->is_devtools(); + // Only tabbed browsers and dev tools use the command line. + bool use_command_line = browser_->is_type_tabbed() || browser_->is_devtools(); #if defined(USE_AURA) - // We use the apps save state on aura. - show_state &= !browser_->is_app(); + // We use the apps save state as well on aura. + use_command_line = use_command_line || browser_->is_app(); #endif - if (show_state) - return browser_->initial_show_state(); - - if (base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kStartMaximized)) + if (use_command_line && base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kStartMaximized)) { return ui::SHOW_STATE_MAXIMIZED; + } - if (browser_->initial_show_state() != ui::SHOW_STATE_DEFAULT) - return browser_->initial_show_state(); - - // Otherwise we use the default which can be overridden later on. - return ui::SHOW_STATE_DEFAULT; + return browser_->initial_show_state(); }
diff --git a/chrome/browser/ui/window_sizer/window_sizer.h b/chrome/browser/ui/window_sizer/window_sizer.h index ab64ec02..fc2d96a 100644 --- a/chrome/browser/ui/window_sizer/window_sizer.h +++ b/chrome/browser/ui/window_sizer/window_sizer.h
@@ -34,21 +34,6 @@ class StateProvider; class TargetDisplayProvider; - // WindowSizer owns |state_provider| and |target_display_provider|, - // and will use the platforms's display::Screen. - WindowSizer(std::unique_ptr<StateProvider> state_provider, - std::unique_ptr<TargetDisplayProvider> target_display_provider, - const Browser* browser); - - // WindowSizer owns |state_provider| and |target_display_provider|, - // and will use the supplied |screen|. Used only for testing. - WindowSizer(std::unique_ptr<StateProvider> state_provider, - std::unique_ptr<TargetDisplayProvider> target_display_provider, - display::Screen* screen, - const Browser* browser); - - virtual ~WindowSizer(); - // An interface implemented by an object that can retrieve state from either a // persistent store or an existing window. class StateProvider { @@ -129,6 +114,21 @@ #endif private: + friend class WindowSizerTestUtil; + + // WindowSizer will use the platforms's display::Screen. + WindowSizer(std::unique_ptr<StateProvider> state_provider, + std::unique_ptr<TargetDisplayProvider> target_display_provider, + const Browser* browser); + + // As above, but uses the supplied |screen|. Used only for testing. + WindowSizer(std::unique_ptr<StateProvider> state_provider, + std::unique_ptr<TargetDisplayProvider> target_display_provider, + display::Screen* screen, + const Browser* browser); + + virtual ~WindowSizer(); + // The edge of the screen to check for out-of-bounds. enum Edge { TOP, LEFT, BOTTOM, RIGHT };
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash.cc b/chrome/browser/ui/window_sizer/window_sizer_ash.cc index 05e2f64..09dd86a8 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_ash.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_ash.cc
@@ -32,15 +32,12 @@ if (!GetSavedWindowBounds(bounds, show_state)) *bounds = GetDefaultWindowBoundsAsh(GetTargetDisplay(gfx::Rect())); determined = true; - } else { + } else if (state_provider_) { // In Ash, prioritize the last saved |show_state|. If you have questions // or comments about this behavior please contact oshima@chromium.org. - if (state_provider_) { - gfx::Rect ignored_bounds, ignored_work_area; - state_provider_->GetPersistentState(&ignored_bounds, - &ignored_work_area, - show_state); - } + gfx::Rect ignored_bounds, ignored_work_area; + state_provider_->GetPersistentState(&ignored_bounds, &ignored_work_area, + show_state); } } else if (browser_->is_type_popup() && bounds->origin().IsOrigin()) { // In case of a popup with an 'unspecified' location in ash, we are
diff --git a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc index 3102492b..7e6d73d 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_ash_unittest.cc
@@ -30,6 +30,8 @@ namespace { +using util = WindowSizerTestUtil; + // Shorten identifiers to improve line wrapping. const int kDesktopBorderSize = WindowSizer::kDesktopBorderSize; const int kMaximumWindowWidth = WindowSizer::kMaximumWindowWidth; @@ -56,8 +58,9 @@ TEST_F(WindowSizerAshTest, DefaultSizeCase) { { // 4:3 monitor case, 1024x768, no taskbar gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ( gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 1024 - kDesktopBorderSize * 2, 768 - kDesktopBorderSize), @@ -66,9 +69,9 @@ { // 4:3 monitor case, 1024x768, taskbar on bottom gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 1024 - kDesktopBorderSize * 2, taskbar_bottom_work_area.height() - kDesktopBorderSize), @@ -77,9 +80,9 @@ { // 4:3 monitor case, 1024x768, taskbar on right gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ( gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, taskbar_right_work_area.width() - kDesktopBorderSize * 2, @@ -89,9 +92,9 @@ { // 4:3 monitor case, 1024x768, taskbar on left gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() + kDesktopBorderSize, kDesktopBorderSize, taskbar_left_work_area.width() - kDesktopBorderSize * 2, @@ -101,9 +104,9 @@ { // 4:3 monitor case, 1024x768, taskbar on top gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(kDesktopBorderSize, taskbar_top_work_area.y() + kDesktopBorderSize, 1024 - kDesktopBorderSize * 2, @@ -113,8 +116,9 @@ { // 4:3 monitor case, 1280x1024 gfx::Rect window_bounds; - GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect((1280 - kMaximumWindowWidth) / 2, kDesktopBorderSize, kMaximumWindowWidth, 1024 - kDesktopBorderSize), window_bounds); @@ -122,8 +126,9 @@ { // 4:3 monitor case, 1600x1200 gfx::Rect window_bounds; - GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect((1600 - kMaximumWindowWidth) / 2, kDesktopBorderSize, kMaximumWindowWidth, 1200 - kDesktopBorderSize), window_bounds); @@ -131,8 +136,9 @@ { // 16:10 monitor case, 1680x1050 gfx::Rect window_bounds; - GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect((1680 - kMaximumWindowWidth) / 2, kDesktopBorderSize, kMaximumWindowWidth, 1050 - kDesktopBorderSize), window_bounds); @@ -140,8 +146,9 @@ { // 16:10 monitor case, 1920x1200 gfx::Rect window_bounds; - GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect((1920 - kMaximumWindowWidth) / 2, kDesktopBorderSize, kMaximumWindowWidth, 1200 - kDesktopBorderSize), window_bounds); @@ -153,10 +160,10 @@ TEST_F(WindowSizerAshTest, LastWindowBoundsCase) { { // normal, in the middle of the screen somewhere. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels + kDesktopBorderSize, kWindowTilePixels + kDesktopBorderSize, 500, 400) .ToString(), @@ -165,10 +172,10 @@ { // taskbar on top. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(), - gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, taskbar_top_work_area, gfx::Rect(), + gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels + kDesktopBorderSize, std::max(kWindowTilePixels + kDesktopBorderSize, 34 /* toolbar height */), @@ -179,10 +186,10 @@ { // Too small to satisify the minimum visibility condition. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 29, 29), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 29, 29), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels + kDesktopBorderSize, kWindowTilePixels + kDesktopBorderSize, 30 /* not 29 */, 30 /* not 29 */) @@ -193,10 +200,10 @@ { // Normal. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels + kDesktopBorderSize, kWindowTilePixels + kDesktopBorderSize, 500, 400) .ToString(), @@ -210,8 +217,9 @@ gfx::Rect initial_bounds(kDesktopBorderSize, kDesktopBorderSize, 500, 400); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -219,8 +227,9 @@ gfx::Rect initial_bounds(0, 0, 1024, 768); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -228,9 +237,9 @@ gfx::Rect initial_bounds(-600, 10, 500, 400); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, left_s1024x768, - initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, left_s1024x768, initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -238,9 +247,9 @@ gfx::Rect initial_bounds(-1024, 0, 1024, 768); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, left_s1024x768, - initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, left_s1024x768, initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -250,9 +259,9 @@ gfx::Rect initial_bounds(1074, 50, 600, 500); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), - initial_bounds, right_s1024x768, PERSISTED, NULL, - gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), + initial_bounds, right_s1024x768, PERSISTED, NULL, + gfx::Rect(), &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -262,9 +271,9 @@ gfx::Rect initial_bounds(1274, 50, 600, 500); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), - initial_bounds, right_s1024x768, PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), + initial_bounds, right_s1024x768, PERSISTED, NULL, + gfx::Rect(), &window_bounds); EXPECT_EQ("1224,50 600x500", window_bounds.ToString()); } @@ -274,17 +283,18 @@ gfx::Rect initial_bounds(1274, 50, 900, 700); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), - initial_bounds, right_s1024x768, PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), + initial_bounds, right_s1024x768, PERSISTED, NULL, + gfx::Rect(), &window_bounds); EXPECT_EQ("1024,0 800x600", window_bounds.ToString()); } { // width and height too small gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 29, 29), - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 29, 29), gfx::Rect(), + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 30 /* not 29 */, 30 /* not 29 */) .ToString(), @@ -295,10 +305,10 @@ TEST_F(WindowSizerAshTest, LastWindowOffscreenWithNonAggressiveRepositioning) { { // taskbar on left. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), - gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, taskbar_left_work_area, gfx::Rect(), + gfx::Rect(kDesktopBorderSize, kDesktopBorderSize, 500, 400), + gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels + kDesktopBorderSize, kWindowTilePixels + kDesktopBorderSize, 500, 400) .ToString(), @@ -308,9 +318,9 @@ { // offset would put the new window offscreen at the bottom but the minimum // visibility condition is barely satisfied without relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(10, 728, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(10, 728, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738, 500, 400).ToString(), window_bounds.ToString()); } @@ -318,9 +328,9 @@ { // offset would put the new window offscreen at the bottom and the minimum // visibility condition is satisified by relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(10, 729, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(10, 729, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738 /* not 739 */, 500, @@ -331,9 +341,9 @@ { // offset would put the new window offscreen at the right but the minimum // visibility condition is barely satisfied without relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(984, 10, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(984, 10, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994, 10 + kWindowTilePixels, 500, 400).ToString(), window_bounds.ToString()); } @@ -341,9 +351,9 @@ { // offset would put the new window offscreen at the right and the minimum // visibility condition is satisified by relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 10, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(985, 10, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 10 + kWindowTilePixels, 500, @@ -354,9 +364,9 @@ { // offset would put the new window offscreen at the bottom right and the // minimum visibility condition is satisified by relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 729, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(985, 729, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, @@ -367,7 +377,7 @@ // Test the placement of newly created windows. TEST_F(WindowSizerAshTest, PlaceNewWindows) { - // Create a browser to pass into the GetWindowBounds function. + // Create a browser to pass into the util::GetWindowBounds function. std::unique_ptr<TestingProfile> profile(new TestingProfile()); // Creating a popup handler here to make sure it does not interfere with the // existing windows. @@ -397,26 +407,28 @@ browser_window->Show(); { // Make sure that popups do not get changed. gfx::Rect window_bounds; - GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), - gfx::Rect(50, 100, 300, 150), bottom_s1600x1200, PERSISTED, - browser_popup.get(), gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), + gfx::Rect(50, 100, 300, 150), bottom_s1600x1200, + PERSISTED, browser_popup.get(), gfx::Rect(), + &window_bounds); EXPECT_EQ("50,100 300x150", window_bounds.ToString()); } browser_window->Hide(); { // If a window is there but not shown the persisted default should be used. gfx::Rect window_bounds; - GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), - gfx::Rect(50, 100, 300, 150), bottom_s1600x1200, - PERSISTED, browser.get(), gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), + gfx::Rect(50, 100, 300, 150), bottom_s1600x1200, + PERSISTED, browser.get(), gfx::Rect(), + &window_bounds); EXPECT_EQ("50,100 300x150", window_bounds.ToString()); } { // If a window is there but not shown the default should be returned. gfx::Rect window_bounds; - GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), - gfx::Rect(), bottom_s1600x1200, - DEFAULT, browser.get(), gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(), + bottom_s1600x1200, DEFAULT, browser.get(), + gfx::Rect(), &window_bounds); // Note: We need to also take the defaults maximum width into account here // since that might get used if the resolution is too big. EXPECT_EQ( @@ -434,7 +446,8 @@ // This test supplements "PlaceNewWindows" by testing the creation of a newly // created browser window on an empty desktop. TEST_F(WindowSizerAshTest, PlaceNewBrowserWindowOnEmptyDesktop) { - // Create a browser to pass into the GetWindowBoundsAndShowState function. + // Create a browser to pass into the util::GetWindowBoundsAndShowState + // function. std::unique_ptr<TestingProfile> profile(new TestingProfile()); Browser::CreateParams native_params(profile.get(), true); std::unique_ptr<Browser> browser( @@ -448,7 +461,7 @@ // screen is less than or equal to our limit (1366 pixels width). gfx::Rect window_bounds; ui::WindowShowState out_show_state1 = ui::SHOW_STATE_DEFAULT; - GetWindowBoundsAndShowState( + util::GetWindowBoundsAndShowState( p1366x768, // The screen resolution. p1366x768, // The monitor work area. gfx::Rect(), // The second monitor. @@ -465,7 +478,7 @@ // If there is a stored coordinate however, that should be taken instead. ui::WindowShowState out_show_state2 = ui::SHOW_STATE_DEFAULT; - GetWindowBoundsAndShowState( + util::GetWindowBoundsAndShowState( p1366x768, // The screen resolution. p1366x768, // The monitor work area. gfx::Rect(), // The second monitor. @@ -483,7 +496,7 @@ // A larger monitor should not trigger auto-maximize. ui::WindowShowState out_show_state3 = ui::SHOW_STATE_DEFAULT; - GetWindowBoundsAndShowState( + util::GetWindowBoundsAndShowState( p1600x1200, // The screen resolution. p1600x1200, // The monitor work area. gfx::Rect(), // The second monitor. @@ -540,9 +553,9 @@ // First new window should be in the primary. { gfx::Rect window_bounds; - GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds, gfx::Rect(), - secondary_bounds, PERSISTED, new_browser.get(), gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds, gfx::Rect(), + secondary_bounds, PERSISTED, new_browser.get(), + gfx::Rect(), &window_bounds); // TODO(oshima): Use exact bounds when the window_sizer_ash is // moved to ash and changed to include the result from // RearrangeVisibleWindowOnShow. @@ -564,7 +577,7 @@ ash::Shell::GetRootWindowForNewWindows()); gfx::Rect window_bounds; ui::WindowShowState out_show_state = ui::SHOW_STATE_DEFAULT; - GetWindowBoundsAndShowState( + util::GetWindowBoundsAndShowState( p1600x1200, p1600x1200, secondary_bounds, gfx::Rect(), secondary_bounds, ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_DEFAULT, PERSISTED, new_browser.get(), gfx::Rect(), 1u, &window_bounds, &out_show_state); @@ -583,9 +596,9 @@ ash::Shell::GetRootWindowForNewWindows()); gfx::Rect window_bounds; - GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds, gfx::Rect(), - secondary_bounds, PERSISTED, new_browser.get(), gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1600x1200, p1600x1200, secondary_bounds, gfx::Rect(), + secondary_bounds, PERSISTED, new_browser.get(), + gfx::Rect(), &window_bounds); // TODO(oshima): Use exact bounds when the window_sizer_ash is // moved to ash and changed to include the result from // RearrangeVisibleWindowOnShow. @@ -610,27 +623,30 @@ // Tabbed windows should retrieve the saved window state - since there is a // top window. - EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, - GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_NORMAL, - BOTH, browser.get(), p1600x1200, p1600x1200)); - // A window that is smaller than the whole work area is set to default state. - EXPECT_EQ(ui::SHOW_STATE_DEFAULT, - GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, - BOTH, browser.get(), p1280x1024, p1600x1200)); - // A window that is sized to occupy the whole work area is maximized. - EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, - GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, - BOTH, browser.get(), p1600x1200, p1600x1200)); - // Non tabbed windows should always follow the window saved visibility state. EXPECT_EQ( ui::SHOW_STATE_MAXIMIZED, - GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_NORMAL, BOTH, - browser_popup.get(), p1600x1200, p1600x1200)); - // The non tabbed window will take the status of the last active of its kind. + util::GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_NORMAL, + BOTH, browser.get(), p1600x1200, p1600x1200)); + // A window that is smaller than the whole work area is set to default state. EXPECT_EQ( - ui::SHOW_STATE_NORMAL, - GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, BOTH, - browser_popup.get(), p1600x1200, p1600x1200)); + ui::SHOW_STATE_DEFAULT, + util::GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, + BOTH, browser.get(), p1280x1024, p1600x1200)); + // A window that is sized to occupy the whole work area is maximized. + EXPECT_EQ( + ui::SHOW_STATE_MAXIMIZED, + util::GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, + BOTH, browser.get(), p1600x1200, p1600x1200)); + // Non tabbed windows should always follow the window saved visibility state. + EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, + util::GetWindowShowState( + ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_NORMAL, BOTH, + browser_popup.get(), p1600x1200, p1600x1200)); + // The non tabbed window will take the status of the last active of its kind. + EXPECT_EQ(ui::SHOW_STATE_NORMAL, + util::GetWindowShowState( + ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, BOTH, + browser_popup.get(), p1600x1200, p1600x1200)); // Now create a top level window and check again for both. Only the tabbed // window should follow the top level window's state. @@ -640,29 +656,30 @@ CreateTestWindowInShellWithId(3), gfx::Rect(16, 32, 640, 320), ¶ms2)); // A tabbed window should now take the top level window state. - EXPECT_EQ(ui::SHOW_STATE_DEFAULT, - GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_DEFAULT, + EXPECT_EQ( + ui::SHOW_STATE_DEFAULT, + util::GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_DEFAULT, BOTH, browser.get(), p1600x1200, p1600x1200)); // Non tabbed windows should always follow the window saved visibility state. - EXPECT_EQ( - ui::SHOW_STATE_MAXIMIZED, - GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_MINIMIZED, - BOTH, browser_popup.get(), p1600x1200, p1600x1200)); + EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, + util::GetWindowShowState( + ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_MINIMIZED, BOTH, + browser_popup.get(), p1600x1200, p1600x1200)); // In smaller screen resolutions we default to maximized if there is no other // window visible. int min_size = ash::WindowPositioner::GetForceMaximizedWidthLimit() / 2; if (min_size > 0) { const gfx::Rect tiny_screen(0, 0, min_size, min_size); - EXPECT_EQ( - ui::SHOW_STATE_DEFAULT, - GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_DEFAULT, - BOTH, browser.get(), tiny_screen, tiny_screen)); + EXPECT_EQ(ui::SHOW_STATE_DEFAULT, + util::GetWindowShowState( + ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_DEFAULT, BOTH, + browser.get(), tiny_screen, tiny_screen)); browser->window()->Hide(); - EXPECT_EQ( - ui::SHOW_STATE_MAXIMIZED, - GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_DEFAULT, - BOTH, browser2.get(), tiny_screen, tiny_screen)); + EXPECT_EQ(ui::SHOW_STATE_MAXIMIZED, + util::GetWindowShowState( + ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_DEFAULT, BOTH, + browser2.get(), tiny_screen, tiny_screen)); } } @@ -684,25 +701,26 @@ // Check that a browser creation state always get used if not given as // SHOW_STATE_DEFAULT. - ui::WindowShowState window_show_state = - GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_MAXIMIZED, - DEFAULT, browser.get(), p1600x1200, p1600x1200); + ui::WindowShowState window_show_state = util::GetWindowShowState( + ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_MAXIMIZED, DEFAULT, + browser.get(), p1600x1200, p1600x1200); EXPECT_EQ(window_show_state, ui::SHOW_STATE_DEFAULT); browser->set_initial_show_state(ui::SHOW_STATE_MINIMIZED); - EXPECT_EQ( - GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_MAXIMIZED, - BOTH, browser.get(), p1600x1200, p1600x1200), - ui::SHOW_STATE_MINIMIZED); + EXPECT_EQ(util::GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, + ui::SHOW_STATE_MAXIMIZED, BOTH, + browser.get(), p1600x1200, p1600x1200), + ui::SHOW_STATE_MINIMIZED); browser->set_initial_show_state(ui::SHOW_STATE_NORMAL); - EXPECT_EQ( - GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, ui::SHOW_STATE_MAXIMIZED, - BOTH, browser.get(), p1600x1200, p1600x1200), - ui::SHOW_STATE_NORMAL); + EXPECT_EQ(util::GetWindowShowState(ui::SHOW_STATE_MAXIMIZED, + ui::SHOW_STATE_MAXIMIZED, BOTH, + browser.get(), p1600x1200, p1600x1200), + ui::SHOW_STATE_NORMAL); browser->set_initial_show_state(ui::SHOW_STATE_MAXIMIZED); - EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL, ui::SHOW_STATE_NORMAL, + EXPECT_EQ( + util::GetWindowShowState(ui::SHOW_STATE_NORMAL, ui::SHOW_STATE_NORMAL, BOTH, browser.get(), p1600x1200, p1600x1200), - ui::SHOW_STATE_MAXIMIZED); + ui::SHOW_STATE_MAXIMIZED); // Check that setting the maximized command line option is forcing the // maximized state. @@ -710,19 +728,20 @@ switches::kStartMaximized); browser->set_initial_show_state(ui::SHOW_STATE_NORMAL); - EXPECT_EQ(GetWindowShowState(ui::SHOW_STATE_NORMAL, ui::SHOW_STATE_NORMAL, + EXPECT_EQ( + util::GetWindowShowState(ui::SHOW_STATE_NORMAL, ui::SHOW_STATE_NORMAL, BOTH, browser.get(), p1600x1200, p1600x1200), - ui::SHOW_STATE_MAXIMIZED); + ui::SHOW_STATE_MAXIMIZED); // The popup should favor the initial show state over the command line. - EXPECT_EQ( - GetWindowShowState(ui::SHOW_STATE_NORMAL, ui::SHOW_STATE_NORMAL, BOTH, - browser_popup.get(), p1600x1200, p1600x1200), - ui::SHOW_STATE_NORMAL); + EXPECT_EQ(util::GetWindowShowState( + ui::SHOW_STATE_NORMAL, ui::SHOW_STATE_NORMAL, BOTH, + browser_popup.get(), p1600x1200, p1600x1200), + ui::SHOW_STATE_NORMAL); } TEST_F(WindowSizerAshTest, DefaultStateBecomesMaximized) { - // Create a browser to pass into the GetWindowBounds function. + // Create a browser to pass into the util::GetWindowBounds function. std::unique_ptr<TestingProfile> profile(new TestingProfile()); Browser::CreateParams native_params(profile.get(), true); std::unique_ptr<Browser> browser( @@ -798,13 +817,13 @@ &trusted_popup_create_params)); // Trusted popup windows should follow the saved show state and ignore the // last show state. - EXPECT_EQ( - ui::SHOW_STATE_DEFAULT, - GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, BOTH, - trusted_popup.get(), p1280x1024, p1600x1200)); + EXPECT_EQ(ui::SHOW_STATE_DEFAULT, + util::GetWindowShowState( + ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, BOTH, + trusted_popup.get(), p1280x1024, p1600x1200)); // A popup that is sized to occupy the whole work area has default state. - EXPECT_EQ( - ui::SHOW_STATE_DEFAULT, - GetWindowShowState(ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, BOTH, - trusted_popup.get(), p1600x1200, p1600x1200)); + EXPECT_EQ(ui::SHOW_STATE_DEFAULT, + util::GetWindowShowState( + ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_NORMAL, BOTH, + trusted_popup.get(), p1600x1200, p1600x1200)); }
diff --git a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc index 2406dbc..87889980 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.cc
@@ -23,6 +23,8 @@ namespace { +using util = WindowSizerTestUtil; + // TODO(rjkroege): Use the common TestScreen. class TestScreen : public display::Screen { public: @@ -185,20 +187,21 @@ int kWindowTilePixels = WindowSizer::kWindowTilePixels; -// The window sizer commonly used test functions. -void GetWindowBoundsAndShowState(const gfx::Rect& monitor1_bounds, - const gfx::Rect& monitor1_work_area, - const gfx::Rect& monitor2_bounds, - const gfx::Rect& bounds, - const gfx::Rect& work_area, - ui::WindowShowState show_state_persisted, - ui::WindowShowState show_state_last, - Source source, - const Browser* browser, - const gfx::Rect& passed_in, - size_t display_index, - gfx::Rect* out_bounds, - ui::WindowShowState* out_show_state) { +// static +void WindowSizerTestUtil::GetWindowBoundsAndShowState( + const gfx::Rect& monitor1_bounds, + const gfx::Rect& monitor1_work_area, + const gfx::Rect& monitor2_bounds, + const gfx::Rect& bounds, + const gfx::Rect& work_area, + ui::WindowShowState show_state_persisted, + ui::WindowShowState show_state_last, + Source source, + const Browser* browser, + const gfx::Rect& passed_in, + size_t display_index, + gfx::Rect* out_bounds, + ui::WindowShowState* out_show_state) { DCHECK(out_show_state); TestScreen test_screen; test_screen.AddDisplay(monitor1_bounds, monitor1_work_area); @@ -218,23 +221,9 @@ out_bounds, out_show_state); } -void GetWindowBounds(const gfx::Rect& monitor1_bounds, - const gfx::Rect& monitor1_work_area, - const gfx::Rect& monitor2_bounds, - const gfx::Rect& bounds, - const gfx::Rect& work_area, - Source source, - const Browser* browser, - const gfx::Rect& passed_in, - gfx::Rect* out_bounds) { - ui::WindowShowState out_show_state = ui::SHOW_STATE_DEFAULT; - GetWindowBoundsAndShowState( - monitor1_bounds, monitor1_work_area, monitor2_bounds, bounds, work_area, - ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_DEFAULT, source, browser, - passed_in, 0u, out_bounds, &out_show_state); -} -ui::WindowShowState GetWindowShowState( +// static +ui::WindowShowState WindowSizerTestUtil::GetWindowShowState( ui::WindowShowState show_state_persisted, ui::WindowShowState show_state_last, Source source, @@ -262,6 +251,23 @@ return out_show_state; } +// static +void WindowSizerTestUtil::GetWindowBounds(const gfx::Rect& monitor1_bounds, + const gfx::Rect& monitor1_work_area, + const gfx::Rect& monitor2_bounds, + const gfx::Rect& bounds, + const gfx::Rect& work_area, + Source source, + const Browser* browser, + const gfx::Rect& passed_in, + gfx::Rect* out_bounds) { + ui::WindowShowState out_show_state = ui::SHOW_STATE_DEFAULT; + GetWindowBoundsAndShowState( + monitor1_bounds, monitor1_work_area, monitor2_bounds, bounds, work_area, + ui::SHOW_STATE_DEFAULT, ui::SHOW_STATE_DEFAULT, source, browser, + passed_in, 0u, out_bounds, &out_show_state); +} + #if !defined(OS_MACOSX) TEST(WindowSizerTestCommon, PersistedWindowOffscreenWithNonAggressiveRepositioning) { @@ -270,27 +276,27 @@ gfx::Rect initial_bounds(-470, 50, 500, 400); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - initial_bounds, gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } { // off the left and the minimum visibility condition is satisfied by // relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-471, 50, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 50, 500, 400).ToString(), window_bounds.ToString()); } { // off the top gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -370, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, -370, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("50,0 500x400", window_bounds.ToString()); } @@ -299,18 +305,18 @@ gfx::Rect initial_bounds(994, 50, 500, 400); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - initial_bounds, gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } { // off the right and the minimum visibility condition is satisified by // relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(995, 50, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 50, 500, 400).ToString(), window_bounds.ToString()); } @@ -320,27 +326,27 @@ gfx::Rect initial_bounds(50, 738, 500, 400); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - initial_bounds, gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } { // off the bottom and the minimum visibility condition is satisified by // relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 739, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, 739, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 738 /* not 739 */, 500, 400).ToString(), window_bounds.ToString()); } { // off the topleft gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, -371, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-471, -371, 500, 400), gfx::Rect(), + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 0, 500, 400).ToString(), window_bounds.ToString()); } @@ -348,9 +354,9 @@ { // off the topright and the minimum visibility condition is satisified by // relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, -371, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(995, -371, 500, 400), gfx::Rect(), + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 0, 500, 400).ToString(), window_bounds.ToString()); } @@ -358,9 +364,9 @@ { // off the bottomleft and the minimum visibility condition is satisified by // relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, 739, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-471, 739, 500, 400), gfx::Rect(), + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(-470 /* not -471 */, 738 /* not 739 */, 500, @@ -371,9 +377,9 @@ { // off the bottomright and the minimum visibility condition is satisified by // relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, 739, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(995, 739, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, @@ -383,68 +389,68 @@ { // entirely off left gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-700, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-700, 50, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(-470 /* not -700 */, 50, 500, 400).ToString(), window_bounds.ToString()); } { // entirely off left (monitor was detached since last run) gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-700, 50, 500, 400), left_s1024x768, PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-700, 50, 500, 400), left_s1024x768, + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("0,50 500x400", window_bounds.ToString()); } { // entirely off top gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -500, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, -500, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("50,0 500x400", window_bounds.ToString()); } { // entirely off top (monitor was detached since last run) gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -500, 500, 400), top_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, -500, 500, 400), top_s1024x768, + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("50,0 500x400", window_bounds.ToString()); } { // entirely off right gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(1200, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(1200, 50, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 1200 */, 50, 500, 400).ToString(), window_bounds.ToString()); } { // entirely off right (monitor was detached since last run) gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(1200, 50, 500, 400), right_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(1200, 50, 500, 400), right_s1024x768, + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("524,50 500x400", window_bounds.ToString()); } { // entirely off bottom gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 800, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, 800, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 738 /* not 800 */, 500, 400).ToString(), window_bounds.ToString()); } { // entirely off bottom (monitor was detached since last run) gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 800, 500, 400), bottom_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, 800, 500, 400), bottom_s1024x768, + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ("50,368 500x400", window_bounds.ToString()); } } @@ -454,17 +460,17 @@ TEST(WindowSizerTestCommon, AdjustFitSize) { { // Check that the window gets resized to the screen. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, - gfx::Rect(-10, -10, 1024 + 20, 768 + 20), &window_bounds); + util::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), gfx::Rect(), DEFAULT, + NULL, gfx::Rect(-10, -10, 1024 + 20, 768 + 20), &window_bounds); EXPECT_EQ("0,0 1024x768", window_bounds.ToString()); } { // Check that a window which hangs out of the screen get moved back in. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, - gfx::Rect(1020, 700, 100, 100), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, + gfx::Rect(1020, 700, 100, 100), &window_bounds); EXPECT_EQ("924,668 100x100", window_bounds.ToString()); } }
diff --git a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.h b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.h index 5e10dd2b..e58bdc6 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_common_unittest.h +++ b/chrome/browser/ui/window_sizer/window_sizer_common_unittest.h
@@ -88,54 +88,63 @@ enum Source { DEFAULT, LAST_ACTIVE, PERSISTED, BOTH }; -// Sets up the window bounds, monitor bounds, show states and more to get the -// resulting |out_bounds| and |out_show_state| from the WindowSizer. -// |source| specifies which type of data gets set for the test: Either the -// last active window, the persisted value which was stored earlier, both or -// none. For all these states the |bounds| and |work_area| get used, for the -// show states either |show_state_persisted| or |show_state_last| will be used. -// |display_index| is the index of the display to return from -// GetDisplayNearestWindow(), and is only used on aura. -void GetWindowBoundsAndShowState(const gfx::Rect& monitor1_bounds, - const gfx::Rect& monitor1_work_area, - const gfx::Rect& monitor2_bounds, - const gfx::Rect& bounds, - const gfx::Rect& work_area, - ui::WindowShowState show_state_persisted, - ui::WindowShowState show_state_last, - Source source, - const Browser* browser, - const gfx::Rect& passed_in, - size_t display_index, - gfx::Rect* out_bounds, - ui::WindowShowState* out_show_state); +class WindowSizerTestUtil { + public: + // Sets up the window bounds, monitor bounds, show states and more to get the + // resulting |out_bounds| and |out_show_state| from the WindowSizer. + // |source| specifies which type of data gets set for the test: Either the + // last active window, the persisted value which was stored earlier, both or + // none. For all these states the |bounds| and |work_area| get used, for the + // show states either |show_state_persisted| or |show_state_last| will be + // used. |display_index| is the index of the display to return from + // GetDisplayNearestWindow(), and is only used on aura. + static void GetWindowBoundsAndShowState( + const gfx::Rect& monitor1_bounds, + const gfx::Rect& monitor1_work_area, + const gfx::Rect& monitor2_bounds, + const gfx::Rect& bounds, + const gfx::Rect& work_area, + ui::WindowShowState show_state_persisted, + ui::WindowShowState show_state_last, + Source source, + const Browser* browser, + const gfx::Rect& passed_in, + size_t display_index, + gfx::Rect* out_bounds, + ui::WindowShowState* out_show_state); -// Sets up the window bounds, monitor bounds, and work area to get the -// resulting |out_bounds| from the WindowSizer. -// |source| specifies which type of data gets set for the test: Either the -// last active window, the persisted value which was stored earlier, both or -// none. For all these states the |bounds| and |work_area| get used, for the -// show states either |show_state_persisted| or |show_state_last| will be used. -void GetWindowBounds(const gfx::Rect& monitor1_bounds, - const gfx::Rect& monitor1_work_area, - const gfx::Rect& monitor2_bounds, - const gfx::Rect& bounds, - const gfx::Rect& work_area, - Source source, - const Browser* browser, - const gfx::Rect& passed_in, - gfx::Rect* out_bounds); + // Sets up the window bounds, monitor bounds, and work area to get the + // resulting |out_bounds| from the WindowSizer. + // |source| specifies which type of data gets set for the test: Either the + // last active window, the persisted value which was stored earlier, both or + // none. For all these states the |bounds| and |work_area| get used, for the + // show states either |show_state_persisted| or |show_state_last| will be + // used. + static void GetWindowBounds(const gfx::Rect& monitor1_bounds, + const gfx::Rect& monitor1_work_area, + const gfx::Rect& monitor2_bounds, + const gfx::Rect& bounds, + const gfx::Rect& work_area, + Source source, + const Browser* browser, + const gfx::Rect& passed_in, + gfx::Rect* out_bounds); -// Sets up the window |bounds| and various system states which have an influence -// on the WindowSizer and then determines the resulting show state from it. -// |bounds| specifies the |browser| last or persistent bounds depending on -// |source|. The |display_config| is the primary display configuration used. -ui::WindowShowState GetWindowShowState( - ui::WindowShowState show_state_persisted, - ui::WindowShowState show_state_last, - Source source, - const Browser* browser, - const gfx::Rect& bounds, - const gfx::Rect& display_config); + // Sets up the window |bounds| and various system states which have an + // influence on the WindowSizer and then determines the resulting show state + // from it. |bounds| specifies the |browser| last or persistent bounds + // depending on |source|. The |display_config| is the primary display + // configuration used. + static ui::WindowShowState GetWindowShowState( + ui::WindowShowState show_state_persisted, + ui::WindowShowState show_state_last, + Source source, + const Browser* browser, + const gfx::Rect& bounds, + const gfx::Rect& display_config); + + private: + DISALLOW_IMPLICIT_CONSTRUCTORS(WindowSizerTestUtil); +}; #endif // CHROME_BROWSER_UI_WINDOW_SIZER_WINDOW_SIZER_COMMON_UNITTEST_H_
diff --git a/chrome/browser/ui/window_sizer/window_sizer_unittest.cc b/chrome/browser/ui/window_sizer/window_sizer_unittest.cc index 8e7e296..6849f7bec9 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_unittest.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_unittest.cc
@@ -8,13 +8,18 @@ #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" +namespace { +using util = WindowSizerTestUtil; +} + // Test that the window is sized appropriately for the first run experience // where the default window bounds calculation is invoked. TEST(WindowSizerTest, DefaultSizeCase) { { // 4:3 monitor case, 1024x768, no taskbar gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 1024 - kWindowTilePixels * 2, 768 - kWindowTilePixels * 2), @@ -23,9 +28,9 @@ { // 4:3 monitor case, 1024x768, taskbar on bottom gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, taskbar_bottom_work_area, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 1024 - kWindowTilePixels * 2, (taskbar_bottom_work_area.height() - @@ -35,9 +40,9 @@ { // 4:3 monitor case, 1024x768, taskbar on right gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, taskbar_right_work_area, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, taskbar_right_work_area.width() - kWindowTilePixels*2, 768 - kWindowTilePixels * 2), @@ -46,9 +51,9 @@ { // 4:3 monitor case, 1024x768, taskbar on left gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x() + kWindowTilePixels, kWindowTilePixels, taskbar_left_work_area.width() - kWindowTilePixels * 2, @@ -59,9 +64,9 @@ { // 4:3 monitor case, 1024x768, taskbar on top gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(), - gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(), + gfx::Rect(), gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, taskbar_top_work_area.y() + kWindowTilePixels, 1024 - kWindowTilePixels * 2, @@ -71,8 +76,9 @@ { // 4:3 monitor case, 1280x1024 gfx::Rect window_bounds; - GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1280x1024, p1280x1024, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, WindowSizer::kWindowMaxDefaultWidth, 1024 - kWindowTilePixels * 2), @@ -81,8 +87,9 @@ { // 4:3 monitor case, 1600x1200 gfx::Rect window_bounds; - GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1600x1200, p1600x1200, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, WindowSizer::kWindowMaxDefaultWidth, 1200 - kWindowTilePixels * 2), @@ -101,8 +108,9 @@ window_width / 2 - static_cast<int>(kWindowTilePixels * 1.5); #endif // defined(OS_MACOSX) gfx::Rect window_bounds; - GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1680x1050, p1680x1050, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, expected_window_width, 1050 - kWindowTilePixels * 2), window_bounds); @@ -120,8 +128,9 @@ window_width / 2 - static_cast<int>(kWindowTilePixels * 1.5); #endif // defined(OS_MACOSX) gfx::Rect window_bounds; - GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(), - gfx::Rect(), DEFAULT, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1920x1200, p1920x1200, gfx::Rect(), gfx::Rect(), + gfx::Rect(), DEFAULT, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, expected_window_width, 1200 - kWindowTilePixels * 2), window_bounds); @@ -133,20 +142,20 @@ TEST(WindowSizerTest, LastWindowBoundsCase) { { // normal, in the middle of the screen somewhere. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2, kWindowTilePixels * 2, 500, 400), window_bounds); } { // taskbar on top. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_top_work_area, gfx::Rect(), - gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, taskbar_top_work_area, gfx::Rect(), + gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2, std::max(kWindowTilePixels * 2, 34 /* toolbar height */), @@ -155,10 +164,10 @@ { // Too small to satisify the minimum visibility condition. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(kWindowTilePixels, kWindowTilePixels, 29, 29), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(kWindowTilePixels, kWindowTilePixels, 29, 29), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2, kWindowTilePixels * 2, 30 /* not 29 */, @@ -169,10 +178,10 @@ { // Normal. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2, kWindowTilePixels * 2, 500, 400), window_bounds); } @@ -184,8 +193,9 @@ gfx::Rect initial_bounds(kWindowTilePixels, kWindowTilePixels, 500, 400); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -193,8 +203,9 @@ gfx::Rect initial_bounds(0, 0, 1024, 768); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -202,9 +213,9 @@ gfx::Rect initial_bounds(-600, 10, 500, 400); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, left_s1024x768, - initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, left_s1024x768, initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -212,9 +223,9 @@ gfx::Rect initial_bounds(-1024, 0, 1024, 768); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, left_s1024x768, - initial_bounds, gfx::Rect(), PERSISTED, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, left_s1024x768, initial_bounds, + gfx::Rect(), PERSISTED, NULL, gfx::Rect(), + &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -224,9 +235,9 @@ gfx::Rect initial_bounds(1074, 50, 600, 500); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), - initial_bounds, right_s1024x768, PERSISTED, NULL, - gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), + initial_bounds, right_s1024x768, PERSISTED, NULL, + gfx::Rect(), &window_bounds); EXPECT_EQ(initial_bounds.ToString(), window_bounds.ToString()); } @@ -236,9 +247,9 @@ gfx::Rect initial_bounds(1274, 50, 600, 500); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), - initial_bounds, right_s1024x768, PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), + initial_bounds, right_s1024x768, PERSISTED, NULL, + gfx::Rect(), &window_bounds); EXPECT_EQ("1224,50 600x500", window_bounds.ToString()); } @@ -248,17 +259,18 @@ gfx::Rect initial_bounds(1274, 50, 900, 700); gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), - initial_bounds, right_s1024x768, PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(1024, 0, 800, 600), + initial_bounds, right_s1024x768, PERSISTED, NULL, + gfx::Rect(), &window_bounds); EXPECT_EQ("1024,0 800x600", window_bounds.ToString()); } { // width and height too small gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(kWindowTilePixels, kWindowTilePixels, 29, 29), - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(kWindowTilePixels, kWindowTilePixels, 29, 29), gfx::Rect(), + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels, kWindowTilePixels, 30 /* not 29 */, 30 /* not 29 */), window_bounds); @@ -270,9 +282,10 @@ // be moved higher than the menubar. (Perhaps the user changed // resolution to something smaller before relaunching Chrome?) gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(kWindowTilePixels, kWindowTilePixels, 30, 5000), - gfx::Rect(), PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds( + p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(kWindowTilePixels, kWindowTilePixels, 30, 5000), gfx::Rect(), + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(p1024x768.height(), window_bounds.height()); } #endif // defined(OS_MACOSX) @@ -289,19 +302,19 @@ { // taskbar on left. The new window overlaps slightly with the taskbar, so // it is moved to be flush with the left edge of the work area. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), - gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, taskbar_left_work_area, gfx::Rect(), + gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(taskbar_left_work_area.x(), kWindowTilePixels * 2, 500, 400), window_bounds); } { // offset would put the new window offscreen at the bottom gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(10, 729, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(10, 729, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 0 /* not 729 + kWindowTilePixels */, 500, 400), @@ -310,9 +323,9 @@ { // offset would put the new window offscreen at the right gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 10, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(985, 10, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 985 + kWindowTilePixels*/, 10 + kWindowTilePixels, 500, 400), @@ -321,9 +334,9 @@ { // offset would put the new window offscreen at the bottom right gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 729, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(985, 729, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 985 + kWindowTilePixels*/, 0 /* not 729 + kWindowTilePixels*/, 500, 400), @@ -334,141 +347,141 @@ TEST(WindowSizerTest, PersistedWindowOffscreenWithAggressiveRepositioning) { { // off the left gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-471, 50, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not -471 */, 50, 500, 400), window_bounds); } { // off the top gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -370, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, -370, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); } { // off the right gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(995, 50, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 995 */, 50, 500, 400), window_bounds); } { // off the bottom gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 739, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, 739, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 0 /* not 739 */, 500, 400), window_bounds); } { // off the topleft gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, -371, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-471, -371, 500, 400), gfx::Rect(), + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not -471 */, 0 /* not -371 */, 500, 400), window_bounds); } { // off the topright gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, -371, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(995, -371, 500, 400), gfx::Rect(), + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 995 */, 0 /* not -371 */, 500, 400), window_bounds); } { // off the bottomleft gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-471, 739, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-471, 739, 500, 400), gfx::Rect(), + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not -471 */, 0 /* not 739 */, 500, 400), window_bounds); } { // off the bottomright gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(995, 739, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(995, 739, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 995 */, 0 /* not 739 */, 500, 400), window_bounds); } { // entirely off left gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-700, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-700, 50, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not -700 */, 50, 500, 400), window_bounds); } { // entirely off left (monitor was detached since last run) gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-700, 50, 500, 400), left_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-700, 50, 500, 400), left_s1024x768, + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0, 50, 500, 400), window_bounds); } { // entirely off top gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -500, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, -500, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); } { // entirely off top (monitor was detached since last run) gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, -500, 500, 400), top_s1024x768, PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, -500, 500, 400), top_s1024x768, + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 0, 500, 400), window_bounds); } { // entirely off right gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(1200, 50, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(1200, 50, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not 1200 */, 50, 500, 400), window_bounds); } { // entirely off right (monitor was detached since last run) gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(1200, 50, 500, 400), right_s1024x768, PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(1200, 50, 500, 400), right_s1024x768, + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(524 /* not 1200 */, 50, 500, 400), window_bounds); } { // entirely off bottom gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 800, 500, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, 800, 500, 400), gfx::Rect(), PERSISTED, + NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 0 /* not 800 */, 500, 400), window_bounds); } { // entirely off bottom (monitor was detached since last run) gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(50, 800, 500, 400), bottom_s1024x768, - PERSISTED, NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(50, 800, 500, 400), bottom_s1024x768, + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(50, 368 /* not 800 */, 500, 400), window_bounds); } { // wider than the screen. off both the left and right gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(-100, 50, 2000, 400), gfx::Rect(), PERSISTED, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(-100, 50, 2000, 400), gfx::Rect(), + PERSISTED, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(0 /* not -100 */, 50, 2000, 400), window_bounds); } } @@ -476,10 +489,10 @@ TEST(WindowSizerTest, LastWindowOffscreenWithNonAggressiveRepositioning) { { // taskbar on left. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, taskbar_left_work_area, gfx::Rect(), - gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), - gfx::Rect(), LAST_ACTIVE, NULL, gfx::Rect(), - &window_bounds); + util::GetWindowBounds( + p1024x768, taskbar_left_work_area, gfx::Rect(), + gfx::Rect(kWindowTilePixels, kWindowTilePixels, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(kWindowTilePixels * 2, kWindowTilePixels * 2, 500, 400), window_bounds); } @@ -489,9 +502,9 @@ { // offset would put the new window offscreen at the bottom but the minimum // visibility condition is barely satisfied without relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(10, 728, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(10, 728, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738, 500, 400), window_bounds); } @@ -499,9 +512,9 @@ { // offset would put the new window offscreen at the bottom and the minimum // visibility condition is satisified by relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(10, 729, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(10, 729, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(10 + kWindowTilePixels, 738 /* not 739 */, 500, 400), window_bounds); } @@ -509,18 +522,18 @@ { // offset would put the new window offscreen at the right but the minimum // visibility condition is barely satisfied without relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(984, 10, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(984, 10, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994, 10 + kWindowTilePixels, 500, 400), window_bounds); } { // offset would put the new window offscreen at the right and the minimum // visibility condition is satisified by relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 10, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(985, 10, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 10 + kWindowTilePixels, 500, 400), window_bounds); } @@ -528,9 +541,9 @@ { // offset would put the new window offscreen at the bottom right and the // minimum visibility condition is satisified by relocation. gfx::Rect window_bounds; - GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), - gfx::Rect(985, 729, 500, 400), gfx::Rect(), LAST_ACTIVE, - NULL, gfx::Rect(), &window_bounds); + util::GetWindowBounds(p1024x768, p1024x768, gfx::Rect(), + gfx::Rect(985, 729, 500, 400), gfx::Rect(), + LAST_ACTIVE, NULL, gfx::Rect(), &window_bounds); EXPECT_EQ(gfx::Rect(994 /* not 995 */, 738 /* not 739 */, 500, 400), window_bounds); }
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index d10c09a..ed0b63c 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/buildflag_header.gni") +import("//chrome/browser/vr/features.gni") import("//chrome/common/features.gni") import("//device/vr/features/features.gni") import("//testing/test.gni") @@ -13,6 +15,11 @@ assert(enable_vr) +buildflag_header("vr_build_features") { + header = "vr_features.h" + flags = [ "USE_VR_ASSETS_COMPONENT=$use_vr_assets_component" ] +} + static_library("vr_common") { sources = [ "animation.cc", @@ -202,6 +209,7 @@ "ui_scene_creator.cc", "ui_scene_creator.h", "ui_unsupported_mode.h", + "vr_features.h", "vr_gl_util.cc", "vr_gl_util.h", ] @@ -211,6 +219,7 @@ ] deps = [ + ":vr_build_features", "//base", "//cc/animation", "//cc/paint",
diff --git a/chrome/browser/vr/assets_loader.cc b/chrome/browser/vr/assets_loader.cc index 9e3f3d8..5926379 100644 --- a/chrome/browser/vr/assets_loader.cc +++ b/chrome/browser/vr/assets_loader.cc
@@ -12,6 +12,7 @@ #include "base/values.h" #include "chrome/browser/vr/metrics_helper.h" #include "chrome/browser/vr/model/assets.h" +#include "chrome/browser/vr/vr_features.h" #include "content/public/browser/browser_thread.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/codec/jpeg_codec.h" @@ -54,6 +55,15 @@ return base::Version(kMinVersionWithGradients); } +// static +bool AssetsLoader::AssetsSupported() { +#if BUILDFLAG(USE_VR_ASSETS_COMPONENT) + return true; +#else // BUILDFLAG(USE_VR_ASSETS_COMPONENT) + return false; +#endif // BUILDFLAG(USE_VR_ASSETS_COMPONENT) +} + void AssetsLoader::OnComponentReady( const base::Version& version, const base::FilePath& install_dir,
diff --git a/chrome/browser/vr/assets_loader.h b/chrome/browser/vr/assets_loader.h index 9949d4d..eba61390 100644 --- a/chrome/browser/vr/assets_loader.h +++ b/chrome/browser/vr/assets_loader.h
@@ -47,6 +47,7 @@ static AssetsLoader* GetInstance(); static base::Version MinVersionWithGradients(); + static bool AssetsSupported(); // Tells VR assets that a new VR assets component version is ready for use. void OnComponentReady(const base::Version& version,
diff --git a/chrome/browser/vr/browser_ui_interface.h b/chrome/browser/vr/browser_ui_interface.h index 0da4d6d7..a2283c1 100644 --- a/chrome/browser/vr/browser_ui_interface.h +++ b/chrome/browser/vr/browser_ui_interface.h
@@ -44,7 +44,6 @@ virtual void OnSpeechRecognitionStateChanged(int new_state) = 0; virtual void SetOmniboxSuggestions( std::unique_ptr<OmniboxSuggestions> suggestions) = 0; - virtual void OnAssetsComponentReady() = 0; virtual void OnAssetsLoaded(AssetsLoadStatus status, std::unique_ptr<Assets> assets, const base::Version& component_version) = 0;
diff --git a/chrome/browser/vr/content_input_delegate.cc b/chrome/browser/vr/content_input_delegate.cc index 5ed1aea..d7f465e 100644 --- a/chrome/browser/vr/content_input_delegate.cc +++ b/chrome/browser/vr/content_input_delegate.cc
@@ -59,6 +59,14 @@ MakeMouseEvent(blink::WebInputEvent::kMouseUp, normalized_hit_point)); } +void ContentInputDelegate::OnFocusChanged(bool focused) { + // The call below tells the renderer to clear the focused element. Note that + // we don't need to do anything when focused is true because the renderer + // already knows about the focused element. + if (!focused) + content_->ClearFocusedElement(); +} + void ContentInputDelegate::OnWebInputEdited(const EditedText& info, bool commit) { if (!content_)
diff --git a/chrome/browser/vr/content_input_delegate.h b/chrome/browser/vr/content_input_delegate.h index 1ee8fe2..39a115f 100644 --- a/chrome/browser/vr/content_input_delegate.h +++ b/chrome/browser/vr/content_input_delegate.h
@@ -38,6 +38,7 @@ std::unique_ptr<blink::WebInputEvent> event) = 0; // Text input specific. + virtual void ClearFocusedElement() = 0; virtual void OnWebInputEdited(const TextEdits& edits) = 0; virtual void SubmitWebInput() = 0; virtual void RequestWebInputText(TextStateUpdateCallback callback) = 0; @@ -59,6 +60,7 @@ virtual void OnContentUp(const gfx::PointF& normalized_hit_point); // Text Input specific. + void OnFocusChanged(bool focused); void OnWebInputEdited(const EditedText& info, bool commit); // The following functions are virtual so that they may be overridden in the
diff --git a/chrome/browser/vr/elements/content_element.cc b/chrome/browser/vr/elements/content_element.cc index 6800f44..9d0b8b8 100644 --- a/chrome/browser/vr/elements/content_element.cc +++ b/chrome/browser/vr/elements/content_element.cc
@@ -63,6 +63,9 @@ } void ContentElement::OnFocusChanged(bool focused) { + if (delegate_) + delegate_->OnFocusChanged(focused); + focused_ = focused; if (event_handlers_.focus_change) event_handlers_.focus_change.Run(focused);
diff --git a/chrome/browser/vr/elements/content_element_unittest.cc b/chrome/browser/vr/elements/content_element_unittest.cc index bb1fcf33..821fc38 100644 --- a/chrome/browser/vr/elements/content_element_unittest.cc +++ b/chrome/browser/vr/elements/content_element_unittest.cc
@@ -48,6 +48,39 @@ TextInputInfo info_; }; +class TestContentInputForwarder : public ContentInputForwarder { + public: + TestContentInputForwarder() {} + ~TestContentInputForwarder() override {} + + void ForwardEvent(std::unique_ptr<blink::WebInputEvent>, int) override {} + void ForwardDialogEvent(std::unique_ptr<blink::WebInputEvent>) override {} + + void ClearFocusedElement() override { clear_focus_called_ = true; } + void OnWebInputEdited(const TextEdits& edits) override { edits_ = edits; } + void SubmitWebInput() override {} + void RequestWebInputText(TextStateUpdateCallback) override { + text_state_requested_ = true; + } + + TextEdits edits() { return edits_; } + bool text_state_requested() { return text_state_requested_; } + bool clear_focus_called() { return clear_focus_called_; } + + void Reset() { + edits_.clear(); + text_state_requested_ = false; + clear_focus_called_ = false; + } + + private: + TextEdits edits_; + bool text_state_requested_ = false; + bool clear_focus_called_ = false; + + DISALLOW_COPY_AND_ASSIGN(TestContentInputForwarder); +}; + class ContentElementSceneTest : public UiTest { public: void SetUp() override { @@ -64,6 +97,10 @@ text_input_delegate_ = std::make_unique<StrictMock<MockTextInputDelegate>>(); + input_forwarder_ = std::make_unique<TestContentInputForwarder>(); + ui_->GetContentInputDelegateForTest()->SetContentInputForwarderForTest( + input_forwarder_.get()); + auto* content = static_cast<ContentElement*>(scene_->GetUiElementByName(kContentQuad)); content->SetTextInputDelegate(text_input_delegate_.get()); @@ -72,6 +109,7 @@ protected: std::unique_ptr<StrictMock<MockTextInputDelegate>> text_input_delegate_; + std::unique_ptr<TestContentInputForwarder> input_forwarder_; testing::Sequence in_sequence_; }; @@ -120,37 +158,16 @@ EXPECT_CALL(*kb_delegate, SetTransform(_)).InSequence(in_sequence_); ui_->ShowSoftInput(false); EXPECT_TRUE(OnBeginFrame()); + + // Taking focus away from content should clear the delegate state. + EXPECT_CALL(*kb_delegate, OnBeginFrame()).InSequence(in_sequence_); + EXPECT_CALL(*kb_delegate, SetTransform(_)).InSequence(in_sequence_); + EXPECT_FALSE(input_forwarder_->clear_focus_called()); + content->OnFocusChanged(false); + EXPECT_TRUE(input_forwarder_->clear_focus_called()); + EXPECT_TRUE(OnBeginFrame()); } -class TestContentInputForwarder : public ContentInputForwarder { - public: - TestContentInputForwarder() {} - ~TestContentInputForwarder() override {} - - void ForwardEvent(std::unique_ptr<blink::WebInputEvent>, int) override {} - void ForwardDialogEvent(std::unique_ptr<blink::WebInputEvent>) override {} - - void OnWebInputEdited(const TextEdits& edits) override { edits_ = edits; } - void SubmitWebInput() override {} - void RequestWebInputText(TextStateUpdateCallback) override { - text_state_requested_ = true; - } - - TextEdits edits() { return edits_; } - bool text_state_requested() { return text_state_requested_; } - - void Reset() { - edits_.clear(); - text_state_requested_ = false; - } - - private: - TextEdits edits_; - bool text_state_requested_ = false; - - DISALLOW_COPY_AND_ASSIGN(TestContentInputForwarder); -}; - class ContentElementInputEditingTest : public UiTest { public: void SetUp() override {
diff --git a/chrome/browser/vr/elements/shadow.cc b/chrome/browser/vr/elements/shadow.cc index c9f25162..20232f4 100644 --- a/chrome/browser/vr/elements/shadow.cc +++ b/chrome/browser/vr/elements/shadow.cc
@@ -115,7 +115,7 @@ // This value adjust how the shadow translates due to depth changes. Increasing // this number effectively makes the faked light sounce appear higher (the // shadow descends more quickly). -static constexpr float kYShadowOffset = 0.06f; +static constexpr float kYShadowOffset = 0.03f; } // namespace
diff --git a/chrome/browser/vr/model/model.h b/chrome/browser/vr/model/model.h index 6f33dd3..45733d6 100644 --- a/chrome/browser/vr/model/model.h +++ b/chrome/browser/vr/model/model.h
@@ -45,8 +45,7 @@ UiElementRenderer::TextureLocation content_overlay_location = UiElementRenderer::kTextureLocationLocal; bool update_ready_snackbar_enabled = false; - bool waiting_for_background = true; - bool can_apply_new_background = false; + bool waiting_for_background = false; bool background_loaded = false; bool supports_selection = true; bool needs_keyboard_update = false;
diff --git a/chrome/browser/vr/model/text_input_info.cc b/chrome/browser/vr/model/text_input_info.cc index c7383fb..7f0354fa 100644 --- a/chrome/browser/vr/model/text_input_info.cc +++ b/chrome/browser/vr/model/text_input_info.cc
@@ -143,7 +143,13 @@ previous.CommittedTextBeforeCursor()); bool had_composition = previous.CompositionSize() > 0 && current.CompositionSize() == 0; - if (had_composition) { + // If the composition changes while there was a composition previously, we + // first finish the previous composition by clearing then commiting it, then + // we set the new composition. + bool new_composition = + previous.composition_start != current.composition_start && + previous.CompositionSize() > 0; + if (had_composition || new_composition) { edits.push_back(TextEditAction(TextEditActionType::CLEAR_COMPOSING_TEXT)); } @@ -151,7 +157,9 @@ // We only want to delete text if the was no selection previously. In the case // where there was a selection, its the editor's responsibility to ensure that // the selected text gets modified when a new edit occurs. - if (previous.SelectionSize() == 0) { + bool had_selection = + previous.SelectionSize() > 0 && current.SelectionSize() == 0; + if (!had_selection) { to_delete = previous.CommittedTextBeforeCursor().size() - common_prefix_length; if (to_delete > 0) { @@ -163,7 +171,7 @@ int to_commit = current.CommittedTextBeforeCursor().size() - common_prefix_length; - if (to_commit > 0) { + if (to_commit > 0 || had_selection) { DCHECK(to_delete == 0); edits.push_back(TextEditAction(TextEditActionType::COMMIT_TEXT, current.CommittedTextBeforeCursor().substr( @@ -171,10 +179,10 @@ to_commit)); } if (current.CompositionSize() > 0) { - DCHECK(to_commit <= 0); - int cursor = previous.CompositionSize() > 0 - ? current.CompositionSize() - previous.CompositionSize() - : current.CompositionSize(); + int cursor = current.CompositionSize(); + if (!new_composition) { + cursor = current.CompositionSize() - previous.CompositionSize(); + } edits.push_back(TextEditAction(TextEditActionType::SET_COMPOSING_TEXT, current.ComposingText(), cursor)); }
diff --git a/chrome/browser/vr/model/text_input_info_unittest.cc b/chrome/browser/vr/model/text_input_info_unittest.cc index 47162c1..d1222fa 100644 --- a/chrome/browser/vr/model/text_input_info_unittest.cc +++ b/chrome/browser/vr/model/text_input_info_unittest.cc
@@ -92,6 +92,12 @@ EXPECT_EQ(edits.size(), 1u); EXPECT_EQ(edits[0], TextEditAction(TextEditActionType::COMMIT_TEXT, base::UTF8ToUTF16("ha"), 2)); + + // There was a selection and backspace was pressed. + edits = EditedText(Text(" text", 0, 0), Text("short text", 0, 5)).GetDiff(); + EXPECT_EQ(edits.size(), 1u); + EXPECT_EQ(edits[0], TextEditAction(TextEditActionType::COMMIT_TEXT, + base::UTF8ToUTF16(""), 0)); } TEST_F(TextInputInfoTest, CompositionDiff) { @@ -142,6 +148,32 @@ EXPECT_EQ(edits[0], TextEditAction(TextEditActionType::CLEAR_COMPOSING_TEXT)); EXPECT_EQ(edits[1], TextEditAction(TextEditActionType::COMMIT_TEXT, base::UTF8ToUTF16("hi"), 2)); + + // A new composition without finishing the previous composition. This could + // happen when we get coalesced events from the keyboard. For example, when + // the user presses the spacebar and a key right after while there is already + // an ongoing composition, the keyboard may give us a new composition without + // finishing the previous composition. + edits = + EditedText(Text("hii hello", 3, 3, 2, 3), Text("hi hello", 2, 2, 0, 2)) + .GetDiff(); + EXPECT_EQ(edits.size(), 3u); + EXPECT_EQ(edits[0], TextEditAction(TextEditActionType::CLEAR_COMPOSING_TEXT)); + EXPECT_EQ(edits[1], TextEditAction(TextEditActionType::COMMIT_TEXT, + base::UTF8ToUTF16("hi"), 2)); + EXPECT_EQ(edits[2], TextEditAction(TextEditActionType::SET_COMPOSING_TEXT, + base::UTF8ToUTF16("i"), 1)); + // Same as above, but the new composition happens by deleting the current + // composition. + edits = + EditedText(Text("hi hello", 2, 2, 0, 2), Text("hii hello", 3, 3, 2, 3)) + .GetDiff(); + EXPECT_EQ(edits.size(), 3u); + EXPECT_EQ(edits[0], TextEditAction(TextEditActionType::CLEAR_COMPOSING_TEXT)); + EXPECT_EQ(edits[1], TextEditAction(TextEditActionType::DELETE_TEXT, + base::UTF8ToUTF16(""), -2)); + EXPECT_EQ(edits[2], TextEditAction(TextEditActionType::SET_COMPOSING_TEXT, + base::UTF8ToUTF16("hi"), 2)); } } // namespace vr
diff --git a/chrome/browser/vr/test/mock_browser_ui_interface.h b/chrome/browser/vr/test/mock_browser_ui_interface.h index 120a7d7..f440ca75 100644 --- a/chrome/browser/vr/test/mock_browser_ui_interface.h +++ b/chrome/browser/vr/test/mock_browser_ui_interface.h
@@ -38,7 +38,6 @@ MOCK_METHOD1(SetRecognitionResult, void(const base::string16& result)); MOCK_METHOD1(OnSpeechRecognitionStateChanged, void(int new_state)); void SetOmniboxSuggestions(std::unique_ptr<OmniboxSuggestions> suggestions) {} - MOCK_METHOD0(OnAssetsComponentReady, void()); void OnAssetsLoaded(AssetsLoadStatus status, std::unique_ptr<Assets> assets, const base::Version& component_version) {}
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc index 59b908f2..1a9e124 100644 --- a/chrome/browser/vr/testapp/vr_test_context.cc +++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -195,9 +195,6 @@ CycleOrigin(); model_->can_navigate_back = !model_->can_navigate_back; break; - case ui::DomCode::US_C: - model_->can_apply_new_background = true; - break; case ui::DomCode::US_P: model_->toggle_mode(kModeRepositionWindow); break; @@ -581,22 +578,6 @@ state = (state + 1) % states.size(); } -void VrTestContext::LoadAssets() { - base::Version assets_component_version(VR_ASSETS_COMPONENT_VERSION); - auto assets = std::make_unique<Assets>(); - if (!(LoadPng(IDR_VR_BACKGROUND_IMAGE, &assets->background) && - LoadPng(IDR_VR_NORMAL_GRADIENT_IMAGE, &assets->normal_gradient) && - LoadPng(IDR_VR_INCOGNITO_GRADIENT_IMAGE, &assets->incognito_gradient) && - LoadPng(IDR_VR_FULLSCREEN_GRADIENT_IMAGE, - &assets->fullscreen_gradient))) { - ui_->OnAssetsLoaded(AssetsLoadStatus::kInvalidContent, nullptr, - assets_component_version); - return; - } - ui_->OnAssetsLoaded(AssetsLoadStatus::kSuccess, std::move(assets), - assets_component_version); -} - RenderInfo VrTestContext::GetRenderInfo() const { RenderInfo render_info; render_info.head_pose = head_pose_; @@ -617,4 +598,20 @@ return origin; } +void VrTestContext::LoadAssets() { + base::Version assets_component_version(VR_ASSETS_COMPONENT_VERSION); + auto assets = std::make_unique<Assets>(); + if (!(LoadPng(IDR_VR_BACKGROUND_IMAGE, &assets->background) && + LoadPng(IDR_VR_NORMAL_GRADIENT_IMAGE, &assets->normal_gradient) && + LoadPng(IDR_VR_INCOGNITO_GRADIENT_IMAGE, &assets->incognito_gradient) && + LoadPng(IDR_VR_FULLSCREEN_GRADIENT_IMAGE, + &assets->fullscreen_gradient))) { + ui_->OnAssetsLoaded(AssetsLoadStatus::kInvalidContent, nullptr, + assets_component_version); + return; + } + ui_->OnAssetsLoaded(AssetsLoadStatus::kSuccess, std::move(assets), + assets_component_version); +} + } // namespace vr
diff --git a/chrome/browser/vr/testapp/vr_test_context.h b/chrome/browser/vr/testapp/vr_test_context.h index bbee184..5ee4ae5a 100644 --- a/chrome/browser/vr/testapp/vr_test_context.h +++ b/chrome/browser/vr/testapp/vr_test_context.h
@@ -54,7 +54,6 @@ void StartAutocomplete(const AutocompleteRequest& request) override; void StopAutocomplete() override; void Navigate(GURL gurl) override; - void LoadAssets() override; void set_window_size(const gfx::Size& size) { window_size_ = size; } @@ -69,6 +68,7 @@ gfx::Transform ViewProjectionMatrix() const; ControllerModel UpdateController(const RenderInfo& render_info); gfx::Point3F LaserOrigin() const; + void LoadAssets(); std::unique_ptr<Ui> ui_; gfx::Size window_size_;
diff --git a/chrome/browser/vr/ui.cc b/chrome/browser/vr/ui.cc index 4e27170..ea703bf 100644 --- a/chrome/browser/vr/ui.cc +++ b/chrome/browser/vr/ui.cc
@@ -201,10 +201,6 @@ model_->omnibox_suggestions = suggestions->suggestions; } -void Ui::OnAssetsComponentReady() { - model_->can_apply_new_background = true; -} - bool Ui::CanSendWebVrVSync() { return model_->web_vr_enabled() && !model_->web_vr.awaiting_min_splash_screen_duration(); @@ -294,21 +290,21 @@ } void Ui::OnAppButtonClicked() { - // App button clicks should be a no-op when auto-presenting WebVR. - if (model_->web_vr_autopresentation_enabled()) { + // App button clicks should be a no-op when auto-presenting WebVR or if + // browsing mode is disabled. + if (model_->web_vr_autopresentation_enabled() || model_->browsing_disabled) return; - } - - // If browsing mode is disabled, the app button should no-op. - if (model_->browsing_disabled) { - return; - } if (model_->reposition_window_enabled()) { model_->pop_mode(kModeRepositionWindow); return; } + if (model_->editing_web_input) { + ShowSoftInput(false); + return; + } + // App button click exits the WebVR presentation and fullscreen. browser_->ExitPresent(); browser_->ExitFullscreen(); @@ -389,10 +385,6 @@ #endif } -void Ui::OnAssetsLoading() { - model_->can_apply_new_background = false; -} - void Ui::OnAssetsLoaded(AssetsLoadStatus status, std::unique_ptr<Assets> assets, const base::Version& component_version) { @@ -444,7 +436,7 @@ model_->browsing_disabled = ui_initial_state.browsing_disabled; model_->skips_redraw_when_not_dirty = ui_initial_state.skips_redraw_when_not_dirty; - model_->waiting_for_background = ui_initial_state.assets_available; + model_->waiting_for_background = ui_initial_state.assets_supported; model_->supports_selection = ui_initial_state.supports_selection; model_->needs_keyboard_update = ui_initial_state.needs_keyboard_update; }
diff --git a/chrome/browser/vr/ui.h b/chrome/browser/vr/ui.h index 41ab75fc..ee25e69 100644 --- a/chrome/browser/vr/ui.h +++ b/chrome/browser/vr/ui.h
@@ -40,8 +40,7 @@ bool browsing_disabled = false; bool has_or_can_request_audio_permission = true; bool skips_redraw_when_not_dirty = false; - // TODO(tiborg): Remove this flag. - bool assets_available = false; + bool assets_supported = false; bool supports_selection = true; bool needs_keyboard_update = false; }; @@ -94,13 +93,11 @@ void OnSpeechRecognitionStateChanged(int new_state) override; void SetOmniboxSuggestions( std::unique_ptr<OmniboxSuggestions> suggestions) override; - void OnAssetsComponentReady() override; void OnAssetsLoaded(AssetsLoadStatus status, std::unique_ptr<Assets> assets, const base::Version& component_version) override; void OnAssetsUnavailable() override; - void OnAssetsLoading(); // TODO(ymalik): We expose this to stop sending VSync to the WebVR page until // the splash screen has been visible for its minimum duration. The visibility // logic currently lives in the UI, and it'd be much cleaner if the UI didn't
diff --git a/chrome/browser/vr/ui_browser_interface.h b/chrome/browser/vr/ui_browser_interface.h index 990cfb1..ad0ec29 100644 --- a/chrome/browser/vr/ui_browser_interface.h +++ b/chrome/browser/vr/ui_browser_interface.h
@@ -32,7 +32,6 @@ virtual void SetVoiceSearchActive(bool active) = 0; virtual void StartAutocomplete(const AutocompleteRequest& request) = 0; virtual void StopAutocomplete() = 0; - virtual void LoadAssets() = 0; }; } // namespace vr
diff --git a/chrome/browser/vr/ui_element_renderer.cc b/chrome/browser/vr/ui_element_renderer.cc index e03af1e..fbb98d7e 100644 --- a/chrome/browser/vr/ui_element_renderer.cc +++ b/chrome/browser/vr/ui_element_renderer.cc
@@ -9,6 +9,7 @@ #include <string> #include "base/macros.h" +#include "base/trace_event/trace_event.h" #include "chrome/browser/vr/renderers/base_quad_renderer.h" #include "chrome/browser/vr/renderers/base_renderer.h" #include "chrome/browser/vr/renderers/external_textured_quad_renderer.h" @@ -58,6 +59,7 @@ float opacity, const gfx::SizeF& element_size, float corner_radius) { + TRACE_EVENT0("gpu", "UiElementRenderer::DrawTexturedQuad"); // TODO(vollick): handle drawing this degenerate situation crbug.com/768922 if (corner_radius * 2.0 > element_size.width() || corner_radius * 2.0 > element_size.height()) { @@ -78,6 +80,7 @@ float opacity, const gfx::SizeF& element_size, const CornerRadii& radii) { + TRACE_EVENT0("gpu", "UiElementRenderer::DrawGradientQuad"); FlushIfNecessary(gradient_quad_renderer_.get()); gradient_quad_renderer_->Draw(model_view_proj_matrix, edge_color, center_color, opacity, element_size, radii); @@ -90,6 +93,7 @@ const SkColor grid_color, int gridline_count, float opacity) { + TRACE_EVENT0("gpu", "UiElementRenderer::DrawGradientGridQuad"); FlushIfNecessary(gradient_grid_renderer_.get()); gradient_grid_renderer_->Draw(model_view_proj_matrix, edge_color, center_color, grid_color, gridline_count, @@ -99,6 +103,7 @@ void UiElementRenderer::DrawController( float opacity, const gfx::Transform& model_view_proj_matrix) { + TRACE_EVENT0("gpu", "UiElementRenderer::DrawController"); FlushIfNecessary(controller_renderer_.get()); controller_renderer_->Draw(opacity, model_view_proj_matrix); } @@ -106,6 +111,7 @@ void UiElementRenderer::DrawLaser( float opacity, const gfx::Transform& model_view_proj_matrix) { + TRACE_EVENT0("gpu", "UiElementRenderer::DrawLaser"); FlushIfNecessary(laser_renderer_.get()); laser_renderer_->Draw(opacity, model_view_proj_matrix); } @@ -113,6 +119,7 @@ void UiElementRenderer::DrawReticle( float opacity, const gfx::Transform& model_view_proj_matrix) { + TRACE_EVENT0("gpu", "UiElementRenderer::DrawReticle"); FlushIfNecessary(reticle_renderer_.get()); reticle_renderer_->Draw(opacity, model_view_proj_matrix); } @@ -130,6 +137,7 @@ SkColor color, float opacity, float corner_radius) { + TRACE_EVENT0("gpu", "UiElementRenderer::DrawShadow"); FlushIfNecessary(shadow_renderer_.get()); shadow_renderer_->Draw(model_view_proj_matrix, element_size, x_padding, y_padding, y_offset, color, opacity, corner_radius); @@ -138,6 +146,7 @@ void UiElementRenderer::DrawStars( float t, const gfx::Transform& model_view_proj_matrix) { + TRACE_EVENT0("gpu", "UiElementRenderer::DrawStars"); FlushIfNecessary(stars_renderer_.get()); stars_renderer_->Draw(t, model_view_proj_matrix); } @@ -151,6 +160,7 @@ float normal_factor, float incognito_factor, float fullscreen_factor) { + TRACE_EVENT0("gpu", "UiElementRenderer::DrawBackground"); FlushIfNecessary(background_renderer_.get()); background_renderer_->Draw(model_view_proj_matrix, texture_data_handle, normal_gradient_texture_data_handle, @@ -162,6 +172,7 @@ void UiElementRenderer::DrawKeyboard(const CameraModel& camera_model, KeyboardDelegate* delegate) { + TRACE_EVENT0("gpu", "UiElementRenderer::DrawKeyboard"); FlushIfNecessary(keyboard_renderer_.get()); keyboard_renderer_->Draw(camera_model, delegate); }
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h index 1effdbec..a38e736f 100644 --- a/chrome/browser/vr/ui_scene_constants.h +++ b/chrome/browser/vr/ui_scene_constants.h
@@ -34,7 +34,7 @@ kContentVerticalOffsetDMM * kContentDistance; static constexpr float kContentCornerRadius = 0.005f * kContentWidth; static constexpr float kContentShadowOffset = 0.09f; -static constexpr float kContentShadowIntesity = 0.3f; +static constexpr float kContentShadowIntesity = 0.4f; static constexpr float kBackplaneSize = 1000.0f; static constexpr float kBackgroundDistanceMultiplier = 1.414f; @@ -209,7 +209,7 @@ static constexpr float kOmniboxCloseButtonVerticalOffsetDMM = -0.75f; static constexpr float kOmniboxCornerRadiusDMM = 0.006f; static constexpr float kOmniboxCloseButtonDepthOffset = -0.35f; -static constexpr float kOmniboxShadowOffset = 0.015f; +static constexpr float kOmniboxShadowOffset = 0.07f; static constexpr float kOmniboxShadowIntensity = 0.4f; static constexpr int kOmniboxTransitionMs = 300;
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index 6623271..52d6e09 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -906,6 +906,7 @@ auto shadow = Create<Shadow>(kContentQuadShadow, kPhaseForeground); shadow->set_intensity(kContentShadowIntesity); shadow->SetTranslate(0, 0, -kContentShadowOffset); + shadow->set_corner_radius(kContentCornerRadius); auto main_content = std::make_unique<ContentElement>( content_input_delegate_, @@ -917,7 +918,6 @@ if (focused) { e->UpdateInput(model->web_input_text_field_info); } else { - model->editing_web_input = false; e->UpdateInput(EditedText()); } }, @@ -1508,7 +1508,7 @@ float, Model, model_, model->reposition_window_enabled() ? kRepositionContentOpacity : 1.0f, UiElement, content_toggle.get(), SetOpacity)); - scene_->AddParentUiElement(kContentQuad, std::move(content_toggle)); + scene_->AddParentUiElement(kContentQuadShadow, std::move(content_toggle)); auto hit_plane = Create<InvisibleHitTarget>(kContentRepositionHitPlane, kPhaseForeground); @@ -1803,21 +1803,7 @@ kDownloadedSnackbar, model_, kFileDownloadDoneIcon, l10n_util::GetStringUTF16(IDS_VR_COMPONENT_UPDATE_READY), base::i18n::ToUpper(l10n_util::GetStringUTF16(IDS_VR_COMPONENT_APPLY)), - base::BindRepeating( - [](UiBrowserInterface* browser, Ui* ui) { - ui->OnAssetsLoading(); - browser->LoadAssets(); - }, - base::Unretained(browser_), base::Unretained(ui_))); - snackbar->AddBinding(std::make_unique<Binding<bool>>( - VR_BIND_LAMBDA([](Model* m) { return m->can_apply_new_background; }, - base::Unretained(model_)), - VR_BIND_LAMBDA( - [](UiElement* s, const bool& value) { - s->SetVisible(value); - s->SetRotate(1, 0, 0, value ? 0 : kSnackbarMoveInAngle); - }, - base::Unretained(snackbar.get())))); + base::DoNothing()); snackbar->SetVisible(false); snackbar->SetRotate(1, 0, 0, kSnackbarMoveInAngle); snackbar->SetTransitionedProperties({OPACITY, TRANSFORM});
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc index da1ded3..a3b91be2 100644 --- a/chrome/browser/vr/ui_unittest.cc +++ b/chrome/browser/vr/ui_unittest.cc
@@ -556,6 +556,18 @@ EXPECT_TRUE(scene_->GetUiElementByName(kUpdateKeyboardPrompt)->IsVisible()); } +TEST_F(UiTest, ExitWebInputEditingOnAppButtonClick) { + CreateScene(kNotInCct, kNotInWebVr); + EXPECT_FALSE(scene_->GetUiElementByName(kKeyboard)->IsVisible()); + ui_->ShowSoftInput(true); + OnBeginFrame(); + EXPECT_TRUE(scene_->GetUiElementByName(kKeyboard)->IsVisible()); + ui_->OnAppButtonClicked(); + OnBeginFrame(); + // Clicking app button should hide the keyboard. + EXPECT_FALSE(scene_->GetUiElementByName(kKeyboard)->IsVisible()); +} + TEST_F(UiTest, UiUpdatesForShowingExitPrompt) { CreateScene(kNotInCct, kNotInWebVr); @@ -1091,7 +1103,7 @@ TEST_F(UiTest, DefaultBackgroundWhenNoAssetAvailable) { UiInitialState state; - state.assets_available = false; + state.assets_supported = false; CreateScene(state); EXPECT_FALSE(IsVisible(k2dBrowsingTexturedBackground)); @@ -1101,7 +1113,7 @@ TEST_F(UiTest, TextureBackgroundAfterAssetLoaded) { UiInitialState state; - state.assets_available = true; + state.assets_supported = true; CreateScene(state); EXPECT_FALSE(IsVisible(k2dBrowsingTexturedBackground));
diff --git a/chrome/browser/vr/vr_gl_util.cc b/chrome/browser/vr/vr_gl_util.cc index 9096f26..67586cc 100644 --- a/chrome/browser/vr/vr_gl_util.cc +++ b/chrome/browser/vr/vr_gl_util.cc
@@ -51,6 +51,8 @@ glDeleteShader(shader_handle); shader_handle = 0; } + } else { + error = "Could not create a shader handle (did not attempt compilation)."; } return shader_handle;
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index b204e28f..2a3abe3 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -37,13 +37,6 @@ const base::Feature kFullscreenToolbarReveal{"FullscreenToolbarReveal", base::FEATURE_ENABLED_BY_DEFAULT}; -#if BUILDFLAG(MAC_VIEWS_BROWSER) -// Causes Views browser builds to use Views browser windows by default rather -// than Cocoa browser windows. -const base::Feature kViewsBrowserWindows{"ViewsBrowserWindows", - base::FEATURE_DISABLED_BY_DEFAULT}; -#endif - // Use toolkit-views for profile chooser menu. const base::Feature kViewsProfileChooser{"ViewsProfileChooser", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index 8080b07..f9646bc 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -32,9 +32,6 @@ #if defined(OS_MACOSX) extern const base::Feature kAppleScriptExecuteJavaScriptMenuItem; extern const base::Feature kShow10_9ObsoleteInfobar; -#if BUILDFLAG(MAC_VIEWS_BROWSER) -extern const base::Feature kViewsBrowserWindows; -#endif extern const base::Feature kViewsProfileChooser; extern const base::Feature kViewsTaskManager; #endif // defined(OS_MACOSX)
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 40c9ea1c..20af8e3b 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -347,12 +347,12 @@ ":test_support", "//base", "//chrome/browser/profiling_host:profiling_browsertests", - "//components/grpc_support/test:quic_test_server", "//components/nacl/common:buildflags", "//components/spellcheck:buildflags", "//components/sync:test_support_model", "//extensions/features", "//media:media_features", + "//net:test_support", "//ppapi/features", "//printing/features", "//rlz/features", @@ -422,7 +422,6 @@ deps += [ "//chrome/android:app_hooks_java", "//chrome/android:chrome_java", - "//chrome/android:class_register_java", "//v8:v8_external_startup_data_assets", ] @@ -931,7 +930,7 @@ "//components/strings", "//components/sync", "//components/translate/core/common", - "//content/public/common:features", + "//content/public/common:buildflags", "//content/test:test_support", "//crypto:platform", "//crypto:test_support", @@ -2807,7 +2806,6 @@ "//base:base_java", "//chrome/android:app_hooks_java", "//chrome/android:chrome_java", - "//chrome/android:class_register_java", "//components/gcm_driver/instance_id/android:instance_id_driver_java", "//components/gcm_driver/instance_id/android:instance_id_driver_test_support_java", "//content/public/android:content_java",
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index 6f1c719..f863f3a5 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -293,6 +293,7 @@ 'ElementAttributeTest.testCanRetrieveTheCurrentValueOfATextFormField_emailInput', 'ElementAttributeTest.testShouldReturnTrueForPresentBooleanAttributes', 'ElementAttributeTest.testShouldReturnValueOfOnClickAttribute', + 'ElementAttributeTest.testCanRetrieveTheCurrentValueOfATextFormField_textInput', 'JavascriptEnabledDriverTest.testShouldBeAbleToFindElementAfterJavascriptCausesANewPageToLoad', 'JavascriptEnabledDriverTest.testShouldBeAbleToSwitchToFocusedElement', 'JavascriptEnabledDriverTest.testShouldBeAbleToDetermineTheLocationOfAnElement',
diff --git a/chrome/test/data/extensions/api_test/mime_handler_view/index.js b/chrome/test/data/extensions/api_test/mime_handler_view/index.js index 747554a3..6eaac5a 100644 --- a/chrome/test/data/extensions/api_test/mime_handler_view/index.js +++ b/chrome/test/data/extensions/api_test/mime_handler_view/index.js
@@ -38,12 +38,10 @@ } function expectSuccessfulRead(response) { - chrome.test.assertEq(200, response.status); chrome.test.assertEq('content to read\n', response.data); } function expectSuccessfulReadLong(response) { - chrome.test.assertEq(200, response.status); chrome.test.assertTrue(response.data.startsWith('content to read\n')); }
diff --git a/chrome/test/data/password/recurring_dynamic_form.html b/chrome/test/data/password/recurring_dynamic_form.html new file mode 100644 index 0000000..935c2f0 --- /dev/null +++ b/chrome/test/data/password/recurring_dynamic_form.html
@@ -0,0 +1,31 @@ +<html> +<script> + +function addForm() { + var dynamicForm = document.createElement('form'); + dynamicForm.setAttribute('method', 'post'); + dynamicForm.setAttribute('action', 'done.html'); + dynamicForm.setAttribute('onsubmit', 'return true;'); + + var inputUsername = document.createElement('input'); + inputUsername.setAttribute('type', 'text'); + + var inputPassword = document.createElement('input'); + inputPassword.setAttribute('type', 'password'); + + var submitButton = document.createElement('input'); + submitButton.setAttribute('type', 'submit'); + submitButton.setAttribute('value', 'Submit'); + + dynamicForm.appendChild(inputUsername); + dynamicForm.appendChild(inputPassword); + dynamicForm.appendChild(submitButton); + + document.body.appendChild(dynamicForm); +} + +</script> + +<body> +</body> +</html>
diff --git a/chrome/test/data/webrtc/peerconnection_getstats.js b/chrome/test/data/webrtc/peerconnection_getstats.js index e63909bb..ac43e9a 100644 --- a/chrome/test/data/webrtc/peerconnection_getstats.js +++ b/chrome/test/data/webrtc/peerconnection_getstats.js
@@ -129,6 +129,7 @@ framesPerSecond: 'number', framesCaptured: 'number', framesSent: 'number', + hugeFramesSent: 'number', framesReceived: 'number', framesDecoded: 'number', framesDropped: 'number',
diff --git a/chromecast/base/BUILD.gn b/chromecast/base/BUILD.gn index 6c37621..7a1f923 100644 --- a/chromecast/base/BUILD.gn +++ b/chromecast/base/BUILD.gn
@@ -279,6 +279,8 @@ android_library("base_java") { java_src_dir = "//chromecast/base/java/src" java_files = [ + "$java_src_dir/org/chromium/chromecast/base/BiConsumer.java", + "$java_src_dir/org/chromium/chromecast/base/BiFunction.java", "$java_src_dir/org/chromium/chromecast/base/Both.java", "$java_src_dir/org/chromium/chromecast/base/CircularBuffer.java", "$java_src_dir/org/chromium/chromecast/base/Controller.java", @@ -286,7 +288,6 @@ "$java_src_dir/org/chromium/chromecast/base/Function.java", "$java_src_dir/org/chromium/chromecast/base/Itertools.java", "$java_src_dir/org/chromium/chromecast/base/Observable.java", - "$java_src_dir/org/chromium/chromecast/base/ReactiveUtils.java", "$java_src_dir/org/chromium/chromecast/base/ScopeFactories.java", "$java_src_dir/org/chromium/chromecast/base/ScopeFactory.java", "$java_src_dir/org/chromium/chromecast/base/Unit.java", @@ -312,7 +313,6 @@ "$java_test_dir/org/chromium/chromecast/base/CircularBufferTest.java", "$java_test_dir/org/chromium/chromecast/base/ItertoolsTest.java", "$java_test_dir/org/chromium/chromecast/base/ObservableAndControllerTest.java", - "$java_test_dir/org/chromium/chromecast/base/ReactiveUtilsTest.java", "$java_test_dir/org/chromium/chromecast/base/ScopeFactoriesTest.java", "$java_test_dir/org/chromium/chromecast/base/TestUtils.java", "$java_test_dir/org/chromium/chromecast/base/UnitTest.java",
diff --git a/chromecast/base/java/src/org/chromium/chromecast/base/BiConsumer.java b/chromecast/base/java/src/org/chromium/chromecast/base/BiConsumer.java new file mode 100644 index 0000000..06bd183 --- /dev/null +++ b/chromecast/base/java/src/org/chromium/chromecast/base/BiConsumer.java
@@ -0,0 +1,15 @@ +// 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.chromecast.base; + +/** + * A function that takes two arguments and returns void. + * + * TODO(sanfin): replace with Java 8 library if we're ever able to use the Java 8 library. + * + * @param <A> The first argument type. + * @param <B> The second argument type. + */ +public interface BiConsumer<A, B> { public void accept(A first, B second); }
diff --git a/chromecast/base/java/src/org/chromium/chromecast/base/BiFunction.java b/chromecast/base/java/src/org/chromium/chromecast/base/BiFunction.java new file mode 100644 index 0000000..62320157 --- /dev/null +++ b/chromecast/base/java/src/org/chromium/chromecast/base/BiFunction.java
@@ -0,0 +1,16 @@ +// 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.chromecast.base; + +/** + * A function that takes two arguments and returns a value. + * + * TODO(sanfin): replace with Java 8 library if we're ever able to use the Java 8 library. + * + * @param <A> The first argument type. + * @param <B> The second argument type. + * @param <R> The return type. + */ +public interface BiFunction<A, B, R> { public R apply(A first, B second); }
diff --git a/chromecast/base/java/src/org/chromium/chromecast/base/Both.java b/chromecast/base/java/src/org/chromium/chromecast/base/Both.java index 174cb70..0ea3847 100644 --- a/chromecast/base/java/src/org/chromium/chromecast/base/Both.java +++ b/chromecast/base/java/src/org/chromium/chromecast/base/Both.java
@@ -53,4 +53,18 @@ assert b != null; return new Both<>(a, b); } + + /** + * Turns a function of two arguments into a function of a single Both argument. + */ + public static <A, B, R> Function<Both<A, B>, R> adapt(BiFunction<A, B, R> function) { + return (Both<A, B> data) -> function.apply(data.first, data.second); + } + + /** + * Turns a consumer of two arguments into a consumer of a single Both argument. + */ + public static <A, B> Consumer<Both<A, B>> adapt(BiConsumer<A, B> consumer) { + return (Both<A, B> data) -> consumer.accept(data.first, data.second); + } }
diff --git a/chromecast/base/java/src/org/chromium/chromecast/base/ReactiveUtils.java b/chromecast/base/java/src/org/chromium/chromecast/base/ReactiveUtils.java deleted file mode 100644 index 4a9c64288..0000000 --- a/chromecast/base/java/src/org/chromium/chromecast/base/ReactiveUtils.java +++ /dev/null
@@ -1,52 +0,0 @@ -// 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.chromecast.base; - -/** - * Helper functions for working with Observables. - */ -public final class ReactiveUtils { - // Uninstantiable. - private ReactiveUtils() {} - - /** - * Interface representing actions to perform when activating and deactivating a state whose type - * is a Both structure. The arguments to the create() function are the fields of the Both value. - * - * @param <A> The type of the first argument to create(). - * @param <B> The type of the second argument to create(). - */ - public interface BothScopeFactory<A, B> { public AutoCloseable create(A first, B second); } - - /** - * A helper to make reacting to combinations of two Observables more readable. - * - * This disassembles the Both value observed by the `.and()`-conjunction of Observables and - * injects the constituent fields in the BothScopeFactory's create() function. - * - * This allows you to rewrite this: - * - * observableA.and(observableB).watch((Both<A, B> data) -> { - * A a = data.first; - * B b = data.second; - * ... - * }); - * - * as this: - * - * watchBoth(observableA.and(observableB), (A a, B b) -> ...); - * - * This is not as composable as chained `.and()` calls, which can be extended to an arbitrary - * number of parameters. But it is more readable for the case where you are observing two - * Observables. - * - * @param <A> The first type in the Both structure. - * @param <B> The second type in the Both structure. - */ - public static <A, B> Observable<Both<A, B>> watchBoth(Observable<Both<A, B>> observable, - BothScopeFactory<? super A, ? super B> scopeFactory) { - return observable.watch((Both<A, B> data) -> scopeFactory.create(data.first, data.second)); - } -}
diff --git a/chromecast/base/java/src/org/chromium/chromecast/base/ScopeFactories.java b/chromecast/base/java/src/org/chromium/chromecast/base/ScopeFactories.java index 24057e0..2f19dada 100644 --- a/chromecast/base/java/src/org/chromium/chromecast/base/ScopeFactories.java +++ b/chromecast/base/java/src/org/chromium/chromecast/base/ScopeFactories.java
@@ -34,6 +34,30 @@ } /** + * Shorthand for making a ScopeFactory that only has side effects on activation, and has a Both + * object for activation data. + * + * For example, one can refactor the following: + * + * observableA.and(observableB).watch((Both<A, B> data) -> { + * A a = data.first; + * B b = data.second; + * ... // side effects on activation + * return () -> {}; // no side effects on deactivation. + * }); + * + * ... into this: + * + * observableA.and(observableB).watch(ScopeFactories.onEnter((A a, B b) -> ...)); + * + * @param <A> The first argument of the consumer (and the first item in the Both). + * @param <B> The second argument of the consumer (and the second item in the Both). + */ + public static <A, B> ScopeFactory<Both<A, B>> onEnter(BiConsumer<A, B> consumer) { + return onEnter(Both.adapt(consumer)); + } + + /** * Shorthand for making a ScopeFactory that only has side effects on deactivation. * * @param <T> The type of the activation data. @@ -51,4 +75,53 @@ public static <T> ScopeFactory<T> onExit(Runnable runnable) { return onExit((T value) -> runnable.run()); } + + /** + * Shorthand for making a ScopeFactory that only has side effects on deactivation, and has a + * Both object for activation data. + * + * For example, one can refactor the following: + * + * observableA.and(observableB).watch((Both<A, B> data) -> { + * A a = data.first; + * B b = data.second; + * return () -> { + * // side effects on deactivation. + * }; + * }); + * + * ... into this: + * + * observableA.and(observableB).watch(ScopeFactories.onExit((A a, B b) -> ...)); + * + * @param <A> The first argument of the consumer (and the first item in the Both). + * @param <B> The second argument of the consumer (and the second item in the Both). + */ + public static <A, B> ScopeFactory<Both<A, B>> onExit(BiConsumer<A, B> consumer) { + return onExit(Both.adapt(consumer)); + } + + /** + * Adapts a ScopeFactory-like function that takes two arguments into a true ScopeFactory that + * takes a Both object. + * + * @param <A> The type of the first argument (and the first item in the Both). + * @param <B> The type of the second argument (and the second item in the Both). + * + * For example, one can refactor the following: + * + * observableA.and(observableB).watch((Both<A, B> data) -> { + * A a = data.first; + * B b = data.second; + * ... + * }); + * + * ... into this: + * + * observableA.and(observableB).watch(ScopeFactories.both((A a, B b) -> ...)); + */ + public static <A, B> ScopeFactory<Both<A, B>> both( + BiFunction<? super A, ? super B, AutoCloseable> function) { + return (Both<A, B> data) -> function.apply(data.first, data.second); + } }
diff --git a/chromecast/base/java/test/org/chromium/chromecast/base/BothTest.java b/chromecast/base/java/test/org/chromium/chromecast/base/BothTest.java index 8717d56..fff1c80 100644 --- a/chromecast/base/java/test/org/chromium/chromecast/base/BothTest.java +++ b/chromecast/base/java/test/org/chromium/chromecast/base/BothTest.java
@@ -4,12 +4,17 @@ package org.chromium.chromecast.base; +import static org.hamcrest.Matchers.contains; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.BlockJUnit4ClassRunner; +import java.util.ArrayList; +import java.util.List; + /** * Tests for Both. */ @@ -52,4 +57,17 @@ Function<Both<Integer, String>, String> getSecond = Both::getSecond; assertEquals(getSecond.apply(x), "two"); } + + @Test + public void testAdaptBiFunction() { + String result = Both.adapt((String a, String b) -> a + b).apply(Both.both("a", "b")); + assertEquals(result, "ab"); + } + + @Test + public void testAdaptBiConsumer() { + List<String> result = new ArrayList<>(); + Both.adapt((String a, String b) -> result.add(a + b)).apply(Both.both("A", "B")); + assertThat(result, contains("AB")); + } }
diff --git a/chromecast/base/java/test/org/chromium/chromecast/base/ReactiveUtilsTest.java b/chromecast/base/java/test/org/chromium/chromecast/base/ReactiveUtilsTest.java deleted file mode 100644 index e57b5afb..0000000 --- a/chromecast/base/java/test/org/chromium/chromecast/base/ReactiveUtilsTest.java +++ /dev/null
@@ -1,57 +0,0 @@ -// 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.chromecast.base; - -import static org.hamcrest.Matchers.contains; -import static org.junit.Assert.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.BlockJUnit4ClassRunner; - -import org.chromium.chromecast.base.TestUtils.Base; -import org.chromium.chromecast.base.TestUtils.Derived; - -import java.util.ArrayList; -import java.util.List; - -/** - * Tests for helper methods used to work with Observables. - */ -@RunWith(BlockJUnit4ClassRunner.class) -public class ReactiveUtilsTest { - @Test - public void testWatchBothWithStrings() { - Controller<String> controllerA = new Controller<>(); - Controller<String> controllerB = new Controller<>(); - List<String> result = new ArrayList<>(); - ReactiveUtils.watchBoth(controllerA.and(controllerB), (String a, String b) -> { - result.add("enter: " + a + ", " + b); - return () -> result.add("exit: " + a + ", " + b); - }); - controllerA.set("A"); - controllerB.set("B"); - controllerA.set("AA"); - controllerB.set("BB"); - assertThat(result, - contains("enter: A, B", "exit: A, B", "enter: AA, B", "exit: AA, B", - "enter: AA, BB")); - } - - @Test - public void testWatchBothWithSuperclassAsScopeFactoryParameters() { - Controller<Derived> controllerA = new Controller<>(); - Controller<Derived> controllerB = new Controller<>(); - List<String> result = new ArrayList<>(); - // Compile error if generics are wrong. - ReactiveUtils.watchBoth(controllerA.and(controllerB), (Base a, Base b) -> { - result.add("enter: " + a + ", " + b); - return () -> result.add("exit: " + a + ", " + b); - }); - controllerA.set(new Derived()); - controllerB.set(new Derived()); - assertThat(result, contains("enter: Derived, Derived")); - } -}
diff --git a/chromecast/base/java/test/org/chromium/chromecast/base/ScopeFactoriesTest.java b/chromecast/base/java/test/org/chromium/chromecast/base/ScopeFactoriesTest.java index c79b3fa..8028dec 100644 --- a/chromecast/base/java/test/org/chromium/chromecast/base/ScopeFactoriesTest.java +++ b/chromecast/base/java/test/org/chromium/chromecast/base/ScopeFactoriesTest.java
@@ -134,4 +134,67 @@ contains("enter Derived", "enter and ignore data", "exit and ignore data", "exit Derived")); } + + @Test + public void testWatchBothWithStrings() { + Controller<String> controllerA = new Controller<>(); + Controller<String> controllerB = new Controller<>(); + List<String> result = new ArrayList<>(); + controllerA.and(controllerB).watch(ScopeFactories.both((String a, String b) -> { + result.add("enter: " + a + ", " + b); + return () -> result.add("exit: " + a + ", " + b); + })); + controllerA.set("A"); + controllerB.set("B"); + controllerA.set("AA"); + controllerB.set("BB"); + assertThat(result, + contains("enter: A, B", "exit: A, B", "enter: AA, B", "exit: AA, B", + "enter: AA, BB")); + } + + @Test + public void testWatchBothWithSuperclassAsScopeFactoryParameters() { + Controller<Derived> controllerA = new Controller<>(); + Controller<Derived> controllerB = new Controller<>(); + List<String> result = new ArrayList<>(); + // Compile error if generics are wrong. + controllerA.and(controllerB).watch(ScopeFactories.both((Base a, Base b) -> { + result.add("enter: " + a + ", " + b); + return () -> result.add("exit: " + a + ", " + b); + })); + controllerA.set(new Derived()); + controllerB.set(new Derived()); + assertThat(result, contains("enter: Derived, Derived")); + } + + @Test + public void testWatchBothOnEnter() { + Controller<String> controllerA = new Controller<>(); + Controller<String> controllerB = new Controller<>(); + List<String> result = new ArrayList<>(); + controllerA.and(controllerB).watch(ScopeFactories.onEnter((String a, String b) -> { + result.add("enter: " + a + ", " + b); + })); + controllerA.set("A"); + controllerB.set("B"); + controllerA.set("AA"); + controllerB.set("BB"); + assertThat(result, contains("enter: A, B", "enter: AA, B", "enter: AA, BB")); + } + + @Test + public void testWatchBothOnExit() { + Controller<String> controllerA = new Controller<>(); + Controller<String> controllerB = new Controller<>(); + List<String> result = new ArrayList<>(); + controllerA.and(controllerB).watch(ScopeFactories.onExit((String a, String b) -> { + result.add("exit: " + a + ", " + b); + })); + controllerA.set("A"); + controllerB.set("B"); + controllerA.set("AA"); + controllerB.set("BB"); + assertThat(result, contains("exit: A, B", "exit: AA, B")); + } }
diff --git a/chromecast/browser/extensions/cast_extension_web_contents_observer.cc b/chromecast/browser/extensions/cast_extension_web_contents_observer.cc index 6edada3..55ba563 100644 --- a/chromecast/browser/extensions/cast_extension_web_contents_observer.cc +++ b/chromecast/browser/extensions/cast_extension_web_contents_observer.cc
@@ -14,4 +14,13 @@ CastExtensionWebContentsObserver::~CastExtensionWebContentsObserver() {} +void CastExtensionWebContentsObserver::CreateForWebContents( + content::WebContents* web_contents) { + content::WebContentsUserData< + CastExtensionWebContentsObserver>::CreateForWebContents(web_contents); + + // Initialize this instance if necessary. + FromWebContents(web_contents)->Initialize(); +} + } // namespace extensions
diff --git a/chromecast/browser/extensions/cast_extension_web_contents_observer.h b/chromecast/browser/extensions/cast_extension_web_contents_observer.h index 8d548350..e3acfc2 100644 --- a/chromecast/browser/extensions/cast_extension_web_contents_observer.h +++ b/chromecast/browser/extensions/cast_extension_web_contents_observer.h
@@ -18,6 +18,10 @@ public: ~CastExtensionWebContentsObserver() override; + // Creates and initializes an instance of this class for the given + // |web_contents|, if it doesn't already exist. + static void CreateForWebContents(content::WebContents* web_contents); + private: friend class content::WebContentsUserData<CastExtensionWebContentsObserver>;
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index d8db4a6..7cb4bc3 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -10448.0.0 \ No newline at end of file +10460.0.0 \ No newline at end of file
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index cfdd295..af9350b 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -151,8 +151,6 @@ "validation.h", "webdata/autocomplete_sync_bridge.cc", "webdata/autocomplete_sync_bridge.h", - "webdata/autocomplete_syncable_service.cc", - "webdata/autocomplete_syncable_service.h", "webdata/autofill_change.cc", "webdata/autofill_change.h", "webdata/autofill_data_type_controller.cc",
diff --git a/components/autofill/core/browser/webdata/autocomplete_syncable_service.cc b/components/autofill/core/browser/webdata/autocomplete_syncable_service.cc deleted file mode 100644 index 6053afa..0000000 --- a/components/autofill/core/browser/webdata/autocomplete_syncable_service.cc +++ /dev/null
@@ -1,430 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h" - -#include <stdint.h> - -#include <utility> - -#include "base/location.h" -#include "base/logging.h" -#include "base/memory/ptr_util.h" -#include "base/strings/utf_string_conversions.h" -#include "components/autofill/core/browser/webdata/autofill_table.h" -#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" -#include "components/sync/model/sync_error.h" -#include "components/sync/model/sync_error_factory.h" -#include "components/sync/protocol/autofill_specifics.pb.h" -#include "components/sync/protocol/sync.pb.h" -#include "components/webdata/common/web_database.h" -#include "net/base/escape.h" - -namespace autofill { -namespace { - -const char kAutofillEntryNamespaceTag[] = "autofill_entry|"; - -// Merges timestamps from the |sync_timestamps| and the |local_entry|. -// Returns true if they were different, false if they were the same. If the -// timestamps were different, fills |date_created| and |date_last_used| with the -// merged timestamps. The |sync_timestamps| vector is assumed to be sorted. -bool MergeTimestamps( - const google::protobuf::RepeatedField<int64_t>& sync_timestamps, - const AutofillEntry& local_entry, - base::Time* date_created, - base::Time* date_last_used) { - if (sync_timestamps.size() == 0) { - *date_created = local_entry.date_created(); - *date_last_used = local_entry.date_last_used(); - return true; - } - - base::Time sync_date_created = - base::Time::FromInternalValue(*sync_timestamps.begin()); - base::Time sync_date_last_used = - base::Time::FromInternalValue(*sync_timestamps.rbegin()); - - if (sync_date_created == local_entry.date_created() && - sync_date_last_used == local_entry.date_last_used()) - return false; - - *date_created = std::min(local_entry.date_created(), sync_date_created); - *date_last_used = std::max(local_entry.date_last_used(), sync_date_last_used); - return true; -} - -void* UserDataKey() { - // Use the address of a static that COMDAT folding won't ever fold - // with something else. - static int user_data_key = 0; - return reinterpret_cast<void*>(&user_data_key); -} - -} // namespace - -AutocompleteSyncableService::AutocompleteSyncableService( - AutofillWebDataBackend* web_data_backend) - : web_data_backend_(web_data_backend), scoped_observer_(this) { - DCHECK(web_data_backend_); - - scoped_observer_.Add(web_data_backend_); -} - -AutocompleteSyncableService::~AutocompleteSyncableService() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -} - -// static -void AutocompleteSyncableService::CreateForWebDataServiceAndBackend( - AutofillWebDataService* web_data_service, - AutofillWebDataBackend* web_data_backend) { - web_data_service->GetDBUserData()->SetUserData( - UserDataKey(), - base::WrapUnique(new AutocompleteSyncableService(web_data_backend))); -} - -// static -AutocompleteSyncableService* AutocompleteSyncableService::FromWebDataService( - AutofillWebDataService* web_data_service) { - return static_cast<AutocompleteSyncableService*>( - web_data_service->GetDBUserData()->GetUserData(UserDataKey())); -} - -AutocompleteSyncableService::AutocompleteSyncableService() - : web_data_backend_(nullptr), scoped_observer_(this) { -} - -void AutocompleteSyncableService::InjectStartSyncFlare( - const syncer::SyncableService::StartSyncFlare& flare) { - flare_ = flare; -} - -syncer::SyncMergeResult AutocompleteSyncableService::MergeDataAndStartSyncing( - syncer::ModelType type, - const syncer::SyncDataList& initial_sync_data, - std::unique_ptr<syncer::SyncChangeProcessor> sync_processor, - std::unique_ptr<syncer::SyncErrorFactory> error_handler) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!sync_processor_); - DCHECK(sync_processor); - DCHECK(error_handler); - - syncer::SyncMergeResult merge_result(type); - error_handler_ = std::move(error_handler); - std::vector<AutofillEntry> entries; - if (!LoadAutofillData(&entries)) { - merge_result.set_error(error_handler_->CreateAndUploadError( - FROM_HERE, - "Could not load autocomplete data from the WebDatabase.")); - return merge_result; - } - - AutocompleteEntryMap new_db_entries; - for (auto it = entries.begin(); it != entries.end(); ++it) { - new_db_entries[it->key()] = - std::make_pair(syncer::SyncChange::ACTION_ADD, it); - } - - sync_processor_ = std::move(sync_processor); - - std::vector<AutofillEntry> new_synced_entries; - // Go through and check for all the entries that sync already knows about. - // CreateOrUpdateEntry() will remove entries that are same with the synced - // ones from |new_db_entries|. - for (const auto& it : initial_sync_data) - CreateOrUpdateEntry(it, &new_db_entries, &new_synced_entries); - - if (!SaveChangesToWebData(new_synced_entries)) { - merge_result.set_error(error_handler_->CreateAndUploadError( - FROM_HERE, - "Failed to update webdata.")); - return merge_result; - } - - syncer::SyncChangeList new_changes; - for (const auto& it : new_db_entries) { - new_changes.push_back( - syncer::SyncChange(FROM_HERE, - it.second.first, - CreateSyncData(*(it.second.second)))); - } - - merge_result.set_error( - sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); - - // This will schedule a deletion operation on the DB thread, which will - // trigger a notification to propagate the deletion to Sync. - // NOTE: This must be called *after* the ProcessSyncChanges call above. - // Otherwise, an item that Sync is not yet aware of might expire, causing a - // Sync error when that item's deletion is propagated to Sync. - web_data_backend_->RemoveExpiredFormElements(); - - web_data_backend_->NotifyThatSyncHasStarted(type); - - return merge_result; -} - -void AutocompleteSyncableService::StopSyncing(syncer::ModelType type) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK_EQ(syncer::AUTOFILL, type); - - sync_processor_.reset(); - error_handler_.reset(); -} - -syncer::SyncDataList AutocompleteSyncableService::GetAllSyncData( - syncer::ModelType type) const { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(sync_processor_); - DCHECK_EQ(type, syncer::AUTOFILL); - - syncer::SyncDataList current_data; - - std::vector<AutofillEntry> entries; - if (!LoadAutofillData(&entries)) - return current_data; - - for (const AutofillEntry& it : entries) - current_data.push_back(CreateSyncData(it)); - - return current_data; -} - -syncer::SyncError AutocompleteSyncableService::ProcessSyncChanges( - const base::Location& from_here, - const syncer::SyncChangeList& change_list) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(sync_processor_); - - if (!sync_processor_) { - syncer::SyncError error(FROM_HERE, - syncer::SyncError::DATATYPE_ERROR, - "Models not yet associated.", - syncer::AUTOFILL); - return error; - } - - // Data is loaded only if we get new ADD/UPDATE change. - std::vector<AutofillEntry> entries; - std::unique_ptr<AutocompleteEntryMap> db_entries; - std::vector<AutofillEntry> new_entries; - - syncer::SyncError list_processing_error; - - for (const auto& i : change_list) { - DCHECK(i.IsValid()); - switch (i.change_type()) { - case syncer::SyncChange::ACTION_ADD: - case syncer::SyncChange::ACTION_UPDATE: - if (!db_entries) { - if (!LoadAutofillData(&entries)) { - return error_handler_->CreateAndUploadError( - FROM_HERE, - "Could not get the autocomplete data from WebDatabase."); - } - db_entries.reset(new AutocompleteEntryMap); - for (std::vector<AutofillEntry>::iterator it = entries.begin(); - it != entries.end(); ++it) { - (*db_entries)[it->key()] = - std::make_pair(syncer::SyncChange::ACTION_ADD, it); - } - } - CreateOrUpdateEntry(i.sync_data(), db_entries.get(), &new_entries); - break; - - case syncer::SyncChange::ACTION_DELETE: { - DCHECK(i.sync_data().GetSpecifics().has_autofill()) - << "Autofill specifics data not present on delete!"; - const sync_pb::AutofillSpecifics& autofill = - i.sync_data().GetSpecifics().autofill(); - if (autofill.has_value()) - list_processing_error = AutofillEntryDelete(autofill); - else - DVLOG(1) << "Delete for old-style autofill profile being dropped!"; - break; - } - - case syncer::SyncChange::ACTION_INVALID: - NOTREACHED(); - return error_handler_->CreateAndUploadError( - FROM_HERE, - "ProcessSyncChanges failed on ChangeType " + - syncer::SyncChange::ChangeTypeToString(i.change_type())); - } - } - - if (!SaveChangesToWebData(new_entries)) { - return error_handler_->CreateAndUploadError( - FROM_HERE, - "Failed to update webdata."); - } - - // This will schedule a deletion operation on the DB thread, which will - // trigger a notification to propagate the deletion to Sync. - web_data_backend_->RemoveExpiredFormElements(); - - return list_processing_error; -} - -void AutocompleteSyncableService::AutofillEntriesChanged( - const AutofillChangeList& changes) { - // Check if sync is on. If we receive this notification prior to sync being - // started, we'll notify sync to start as soon as it can and later process all - // entries when MergeDataAndStartSyncing() is called. If we receive this - // notification after sync has exited, it will be synced the next time Chrome - // starts. - if (sync_processor_) { - ActOnChanges(changes); - } else if (!flare_.is_null()) { - flare_.Run(syncer::AUTOFILL); - flare_.Reset(); - } -} - -bool AutocompleteSyncableService::LoadAutofillData( - std::vector<AutofillEntry>* entries) const { - return GetAutofillTable()->GetAllAutofillEntries(entries); -} - -bool AutocompleteSyncableService::SaveChangesToWebData( - const std::vector<AutofillEntry>& new_entries) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!GetAutofillTable()->UpdateAutofillEntries(new_entries)) - return false; - - web_data_backend_->NotifyOfMultipleAutofillChanges(); - return true; -} - -// Creates or updates an autocomplete entry based on |data|. -void AutocompleteSyncableService::CreateOrUpdateEntry( - const syncer::SyncData& data, - AutocompleteEntryMap* loaded_data, - std::vector<AutofillEntry>* new_entries) { - const sync_pb::EntitySpecifics& specifics = data.GetSpecifics(); - const sync_pb::AutofillSpecifics& autofill_specifics(specifics.autofill()); - - if (!autofill_specifics.has_value()) { - DVLOG(1) << "Add/Update for old-style autofill profile being dropped!"; - return; - } - - AutofillKey key(autofill_specifics.name(), autofill_specifics.value()); - AutocompleteEntryMap::iterator it = loaded_data->find(key); - const google::protobuf::RepeatedField<int64_t>& timestamps = - autofill_specifics.usage_timestamp(); - if (it == loaded_data->end()) { - // New entry. - base::Time date_created, date_last_used; - if (!timestamps.empty()) { - date_created = base::Time::FromInternalValue(*timestamps.begin()); - date_last_used = base::Time::FromInternalValue(*timestamps.rbegin()); - } - new_entries->push_back(AutofillEntry(key, date_created, date_last_used)); - } else { - // Entry already present - merge if necessary. - base::Time date_created, date_last_used; - bool different = MergeTimestamps(timestamps, *it->second.second, - &date_created, &date_last_used); - if (different) { - AutofillEntry new_entry( - it->second.second->key(), date_created, date_last_used); - new_entries->push_back(new_entry); - // Update the sync db since the timestamps have changed. - *(it->second.second) = new_entry; - it->second.first = syncer::SyncChange::ACTION_UPDATE; - } else { - loaded_data->erase(it); - } - } -} - -// static -void AutocompleteSyncableService::WriteAutofillEntry( - const AutofillEntry& entry, sync_pb::EntitySpecifics* autofill_specifics) { - sync_pb::AutofillSpecifics* autofill = - autofill_specifics->mutable_autofill(); - autofill->set_name(base::UTF16ToUTF8(entry.key().name())); - autofill->set_value(base::UTF16ToUTF8(entry.key().value())); - autofill->add_usage_timestamp(entry.date_created().ToInternalValue()); - if (entry.date_created() != entry.date_last_used()) - autofill->add_usage_timestamp(entry.date_last_used().ToInternalValue()); -} - -syncer::SyncError AutocompleteSyncableService::AutofillEntryDelete( - const sync_pb::AutofillSpecifics& autofill) { - if (!GetAutofillTable()->RemoveFormElement( - base::UTF8ToUTF16(autofill.name()), - base::UTF8ToUTF16(autofill.value()))) { - return error_handler_->CreateAndUploadError( - FROM_HERE, - "Could not remove autocomplete entry from WebDatabase."); - } - return syncer::SyncError(); -} - -void AutocompleteSyncableService::ActOnChanges( - const AutofillChangeList& changes) { - DCHECK(sync_processor_); - syncer::SyncChangeList new_changes; - for (const auto& change : changes) { - switch (change.type()) { - case AutofillChange::ADD: - case AutofillChange::UPDATE: { - base::Time date_created, date_last_used; - bool success = GetAutofillTable()->GetAutofillTimestamps( - change.key().name(), change.key().value(), - &date_created, &date_last_used); - DCHECK(success); - AutofillEntry entry(change.key(), date_created, date_last_used); - syncer::SyncChange::SyncChangeType change_type = - (change.type() == AutofillChange::ADD) ? - syncer::SyncChange::ACTION_ADD : - syncer::SyncChange::ACTION_UPDATE; - new_changes.push_back(syncer::SyncChange(FROM_HERE, - change_type, - CreateSyncData(entry))); - break; - } - - case AutofillChange::REMOVE: { - AutofillEntry entry(change.key(), base::Time(), base::Time()); - new_changes.push_back( - syncer::SyncChange(FROM_HERE, - syncer::SyncChange::ACTION_DELETE, - CreateSyncData(entry))); - break; - } - } - } - syncer::SyncError error = - sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); - if (error.IsSet()) { - DVLOG(1) << "[AUTOCOMPLETE SYNC] Failed processing change. Error: " - << error.message(); - } -} - -syncer::SyncData AutocompleteSyncableService::CreateSyncData( - const AutofillEntry& entry) const { - sync_pb::EntitySpecifics autofill_specifics; - WriteAutofillEntry(entry, &autofill_specifics); - std::string tag(KeyToTag(base::UTF16ToUTF8(entry.key().name()), - base::UTF16ToUTF8(entry.key().value()))); - return syncer::SyncData::CreateLocalData(tag, tag, autofill_specifics); -} - -AutofillTable* AutocompleteSyncableService::GetAutofillTable() const { - return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase()); -} - -// static -std::string AutocompleteSyncableService::KeyToTag(const std::string& name, - const std::string& value) { - std::string prefix(kAutofillEntryNamespaceTag); - return prefix + net::EscapePath(name) + "|" + net::EscapePath(value); -} - -} // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autocomplete_syncable_service.h b/components/autofill/core/browser/webdata/autocomplete_syncable_service.h deleted file mode 100644 index 72a22f7..0000000 --- a/components/autofill/core/browser/webdata/autocomplete_syncable_service.h +++ /dev/null
@@ -1,171 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOCOMPLETE_SYNCABLE_SERVICE_H_ -#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOCOMPLETE_SYNCABLE_SERVICE_H_ - -#include <map> -#include <memory> -#include <set> -#include <string> -#include <utility> -#include <vector> - -#include "base/macros.h" -#include "base/scoped_observer.h" -#include "base/sequence_checker.h" -#include "base/supports_user_data.h" -#include "components/autofill/core/browser/webdata/autofill_change.h" -#include "components/autofill/core/browser/webdata/autofill_entry.h" -#include "components/autofill/core/browser/webdata/autofill_webdata_backend.h" -#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" -#include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h" -#include "components/sync/model/sync_change.h" -#include "components/sync/model/sync_data.h" -#include "components/sync/model/sync_error.h" -#include "components/sync/model/syncable_service.h" - -namespace browser_sync { -class FakeServerUpdater; -class ProfileSyncServiceAutofillTest; -} // namespace browser_sync - -namespace syncer { -class SyncErrorFactory; -} // namespace syncer - -namespace sync_pb { -class AutofillSpecifics; -} // namespace sync_pb - -namespace autofill { - -class AutofillTable; - -// The sync implementation for autocomplete. -// MergeDataAndStartSyncing() called first, it does cloud->local and -// local->cloud syncs. Then for each cloud change we receive -// ProcessSyncChanges() and for each local change Observe() is called. -class AutocompleteSyncableService - : public base::SupportsUserData::Data, - public syncer::SyncableService, - public AutofillWebDataServiceObserverOnDBSequence { - public: - ~AutocompleteSyncableService() override; - - // Creates a new AutocompleteSyncableService and hangs it off of - // |web_data_service|, which takes ownership. - static void CreateForWebDataServiceAndBackend( - AutofillWebDataService* web_data_service, - AutofillWebDataBackend* web_data_backend); - - // Retrieves the AutocompleteSyncableService stored on |web_data_service|. - static AutocompleteSyncableService* FromWebDataService( - AutofillWebDataService* web_data_service); - - static syncer::ModelType model_type() { return syncer::AUTOFILL; } - - // syncer::SyncableService: - syncer::SyncMergeResult MergeDataAndStartSyncing( - syncer::ModelType type, - const syncer::SyncDataList& initial_sync_data, - std::unique_ptr<syncer::SyncChangeProcessor> sync_processor, - std::unique_ptr<syncer::SyncErrorFactory> error_handler) override; - void StopSyncing(syncer::ModelType type) override; - syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override; - syncer::SyncError ProcessSyncChanges( - const base::Location& from_here, - const syncer::SyncChangeList& change_list) override; - - // AutofillWebDataServiceObserverOnDBSequence: - void AutofillEntriesChanged(const AutofillChangeList& changes) override; - - // Provides a StartSyncFlare to the SyncableService. See sync_start_util for - // more. - void InjectStartSyncFlare( - const syncer::SyncableService::StartSyncFlare& flare); - - protected: - explicit AutocompleteSyncableService( - AutofillWebDataBackend* web_data_backend); - - // Helper to query WebDatabase for the current autocomplete state. - // Made virtual for ease of mocking in the unit-test. - virtual bool LoadAutofillData(std::vector<AutofillEntry>* entries) const; - - // Helper to persist any changes that occured during model association to - // the WebDatabase. |entries| will be either added or updated. - // Made virtual for ease of mocking in the unit-test. - virtual bool SaveChangesToWebData(const std::vector<AutofillEntry>& entries); - - private: - friend class browser_sync::FakeServerUpdater; - friend class browser_sync::ProfileSyncServiceAutofillTest; - - // This is a helper map used only in Merge/Process* functions. The lifetime - // of the iterator is longer than the map object. The bool in the pair is used - // to indicate if the item needs to be added (true) or updated (false). - typedef std::map<AutofillKey, - std::pair<syncer::SyncChange::SyncChangeType, - std::vector<AutofillEntry>::iterator>> - AutocompleteEntryMap; - - // Creates or updates an autocomplete entry based on |data|. - // |data| - an entry for sync. - // |loaded_data| - entries that were loaded from local storage. - // |new_entries| - entries that came from the sync. - // |ignored_entries| - entries that came from the sync, but too old to be - // stored and immediately discarded. - void CreateOrUpdateEntry(const syncer::SyncData& data, - AutocompleteEntryMap* loaded_data, - std::vector<AutofillEntry>* new_entries); - - // Writes |entry| data into supplied |autofill_specifics|. - static void WriteAutofillEntry(const AutofillEntry& entry, - sync_pb::EntitySpecifics* autofill_specifics); - - // Deletes the database entry corresponding to the |autofill| specifics. - syncer::SyncError AutofillEntryDelete( - const sync_pb::AutofillSpecifics& autofill); - - syncer::SyncData CreateSyncData(const AutofillEntry& entry) const; - - // Syncs |changes| to the cloud. - void ActOnChanges(const AutofillChangeList& changes); - - // Returns the table associated with the |web_data_backend_|. - AutofillTable* GetAutofillTable() const; - - static std::string KeyToTag(const std::string& name, - const std::string& value); - - // For unit-tests. - AutocompleteSyncableService(); - void set_sync_processor(syncer::SyncChangeProcessor* sync_processor) { - sync_processor_.reset(sync_processor); - } - - // The |web_data_backend_| is expected to outlive |this|. - AutofillWebDataBackend* const web_data_backend_; - - ScopedObserver<AutofillWebDataBackend, AutocompleteSyncableService> - scoped_observer_; - - // We receive ownership of |sync_processor_| in MergeDataAndStartSyncing() and - // destroy it in StopSyncing(). - std::unique_ptr<syncer::SyncChangeProcessor> sync_processor_; - - // We receive ownership of |error_handler_| in MergeDataAndStartSyncing() and - // destroy it in StopSyncing(). - std::unique_ptr<syncer::SyncErrorFactory> error_handler_; - - syncer::SyncableService::StartSyncFlare flare_; - - SEQUENCE_CHECKER(sequence_checker_); - - DISALLOW_COPY_AND_ASSIGN(AutocompleteSyncableService); -}; - -} // namespace autofill - -#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOCOMPLETE_SYNCABLE_SERVICE_H_
diff --git a/components/autofill/core/browser/webdata/autofill_data_type_controller.cc b/components/autofill/core/browser/webdata/autofill_data_type_controller.cc index 922d2325..1308021 100644 --- a/components/autofill/core/browser/webdata/autofill_data_type_controller.cc +++ b/components/autofill/core/browser/webdata/autofill_data_type_controller.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/metrics/histogram.h" #include "components/autofill/core/browser/personal_data_manager.h" -#include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/common/autofill_pref_names.h" #include "components/prefs/pref_service.h"
diff --git a/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc b/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc index 677b806..5f88eac4 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc +++ b/components/autofill/core/browser/webdata/autofill_profile_data_type_controller.cc
@@ -9,7 +9,6 @@ #include "base/bind.h" #include "base/metrics/histogram.h" #include "components/autofill/core/browser/personal_data_manager.h" -#include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/autofill/core/common/autofill_pref_names.h" #include "components/prefs/pref_service.h"
diff --git a/components/browser_sync/abstract_profile_sync_service_test.cc b/components/browser_sync/abstract_profile_sync_service_test.cc index cb706fa..a331fb14 100644 --- a/components/browser_sync/abstract_profile_sync_service_test.cc +++ b/components/browser_sync/abstract_profile_sync_service_test.cc
@@ -43,7 +43,7 @@ syncer::SyncClient* sync_client, invalidation::InvalidationService* invalidator, const base::WeakPtr<syncer::SyncPrefs>& sync_prefs, - const base::Closure& callback); + base::OnceClosure callback); ~SyncEngineForProfileSyncTest() override; void Initialize(InitParams params) override; @@ -54,7 +54,7 @@ // Invoked at the start of HandleSyncManagerInitializationOnFrontendLoop. // Allows extra initialization work to be performed before the engine comes // up. - base::Closure callback_; + base::OnceClosure callback_; DISALLOW_COPY_AND_ASSIGN(SyncEngineForProfileSyncTest); }; @@ -64,21 +64,22 @@ syncer::SyncClient* sync_client, invalidation::InvalidationService* invalidator, const base::WeakPtr<syncer::SyncPrefs>& sync_prefs, - const base::Closure& callback) + base::OnceClosure callback) : SyncBackendHostImpl( "dummy_debug_name", sync_client, invalidator, sync_prefs, temp_dir.Append(base::FilePath(FILE_PATH_LITERAL("test")))), - callback_(callback) {} + callback_(std::move(callback)) {} SyncEngineForProfileSyncTest::~SyncEngineForProfileSyncTest() {} void SyncEngineForProfileSyncTest::Initialize(InitParams params) { params.http_factory_getter = base::Bind(&GetHttpPostProviderFactory); params.sync_manager_factory = - std::make_unique<syncer::SyncManagerFactoryForProfileSyncTest>(callback_); + std::make_unique<syncer::SyncManagerFactoryForProfileSyncTest>( + std::move(callback_)); params.credentials.email = "testuser@gmail.com"; params.credentials.sync_token = "token"; params.credentials.scope_set.insert(GaiaConstants::kChromeSyncOAuth2Scope); @@ -160,7 +161,7 @@ void AbstractProfileSyncServiceTest::CreateSyncService( std::unique_ptr<syncer::SyncClient> sync_client, - const base::Closure& initialization_success_callback) { + base::OnceClosure initialization_success_callback) { ASSERT_TRUE(sync_client); ProfileSyncService::InitParams init_params = profile_sync_service_bundle_.CreateBasicInitParams( @@ -175,7 +176,7 @@ temp_dir_.GetPath(), sync_service_->GetSyncClient(), profile_sync_service_bundle_.fake_invalidation_service(), sync_service_->sync_prefs()->AsWeakPtr(), - initialization_success_callback))); + std::move(initialization_success_callback)))); sync_service_->SetFirstSetupComplete(); }
diff --git a/components/browser_sync/abstract_profile_sync_service_test.h b/components/browser_sync/abstract_profile_sync_service_test.h index 2171b68..05d355b3 100644 --- a/components/browser_sync/abstract_profile_sync_service_test.h +++ b/components/browser_sync/abstract_profile_sync_service_test.h
@@ -53,7 +53,7 @@ // NotifyInitializationSuccess. |sync_client| is passed to the service. The // created service is stored in |sync_service_|. void CreateSyncService(std::unique_ptr<syncer::SyncClient> sync_client, - const base::Closure& initialization_success_callback); + base::OnceClosure initialization_success_callback); base::Thread* data_type_thread() { return &data_type_thread_; }
diff --git a/components/browser_sync/profile_sync_service_autofill_unittest.cc b/components/browser_sync/profile_sync_service_autofill_unittest.cc index 54dd4a7..921fddc 100644 --- a/components/browser_sync/profile_sync_service_autofill_unittest.cc +++ b/components/browser_sync/profile_sync_service_autofill_unittest.cc
@@ -29,10 +29,8 @@ #include "components/autofill/core/browser/country_names.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/personal_data_manager.h" -#include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_change.h" #include "components/autofill/core/browser/webdata/autofill_data_type_controller.h" -#include "components/autofill/core/browser/webdata/autofill_entry.h" #include "components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h" #include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_table.h" @@ -60,10 +58,8 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -using autofill::AutocompleteSyncableService; using autofill::AutofillChange; using autofill::AutofillChangeList; -using autofill::AutofillEntry; using autofill::AutofillKey; using autofill::AutofillProfile; using autofill::AutofillProfileChange; @@ -77,7 +73,6 @@ using base::Time; using base::TimeDelta; using base::WaitableEvent; -using syncer::AUTOFILL; using syncer::AUTOFILL_PROFILE; using syncer::BaseNode; using syncer::syncable::CREATE; @@ -111,33 +106,11 @@ 0.0); } -void RunAndSignal(const base::Closure& cb, WaitableEvent* event) { - cb.Run(); +void RunAndSignal(base::OnceClosure cb, WaitableEvent* event) { + std::move(cb).Run(); event->Signal(); } -AutofillEntry MakeAutofillEntry(const std::string& name, - const std::string& value, - int time_shift0, - int time_shift1) { - // Time deep in the past would cause Autocomplete sync to discard the - // entries. - static Time base_time = Time::Now().LocalMidnight(); - - Time date_created = base_time + TimeDelta::FromSeconds(time_shift0); - Time date_last_used = date_created; - if (time_shift1 >= 0) - date_last_used = base_time + TimeDelta::FromSeconds(time_shift1); - return AutofillEntry(AutofillKey(ASCIIToUTF16(name), ASCIIToUTF16(value)), - date_created, date_last_used); -} - -AutofillEntry MakeAutofillEntry(const std::string& name, - const std::string& value, - int time_shift) { - return MakeAutofillEntry(name, value, time_shift, -1); -} - } // namespace class AutofillTableMock : public AutofillTable { @@ -146,15 +119,11 @@ MOCK_METHOD2(RemoveFormElement, bool(const base::string16& name, const base::string16& value)); // NOLINT - MOCK_METHOD1(GetAllAutofillEntries, - bool(std::vector<AutofillEntry>* entries)); // NOLINT MOCK_METHOD4(GetAutofillTimestamps, bool(const base::string16& name, // NOLINT const base::string16& value, Time* date_created, Time* date_last_used)); - MOCK_METHOD1(UpdateAutofillEntries, - bool(const std::vector<AutofillEntry>&)); // NOLINT MOCK_METHOD1(GetAutofillProfiles, bool(std::vector<std::unique_ptr<AutofillProfile>>*)); // NOLINT MOCK_METHOD1(UpdateAutofillProfile, bool(const AutofillProfile&)); // NOLINT @@ -183,8 +152,8 @@ public: MockAutofillBackend( WebDatabase* web_database, - const base::Closure& on_changed, - const base::Callback<void(syncer::ModelType)>& on_sync_started, + const base::RepeatingClosure& on_changed, + const base::RepeatingCallback<void(syncer::ModelType)>& on_sync_started, const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) : web_database_(web_database), on_changed_(on_changed), @@ -212,28 +181,13 @@ private: WebDatabase* web_database_; - base::Closure on_changed_; - base::Callback<void(syncer::ModelType)> on_sync_started_; + base::RepeatingClosure on_changed_; + base::RepeatingCallback<void(syncer::ModelType)> on_sync_started_; const scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; }; class ProfileSyncServiceAutofillTest; -template <class AutofillProfile> -syncer::ModelType GetModelType() { - return syncer::UNSPECIFIED; -} - -template <> -syncer::ModelType GetModelType<AutofillEntry>() { - return AUTOFILL; -} - -template <> -syncer::ModelType GetModelType<AutofillProfile>() { - return AUTOFILL_PROFILE; -} - class TokenWebDataServiceFake : public TokenWebData { public: TokenWebDataServiceFake( @@ -268,7 +222,6 @@ const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner) : AutofillWebDataService(ui_task_runner, db_task_runner), web_database_(nullptr), - autocomplete_syncable_service_(nullptr), autofill_profile_syncable_service_(nullptr), syncable_service_created_or_destroyed_( base::WaitableEvent::ResetPolicy::AUTOMATIC, @@ -281,17 +234,17 @@ void StartSyncableService() { // The |autofill_profile_syncable_service_| must be constructed on the DB // sequence. - const base::Closure& on_changed_callback = base::Bind( + const base::RepeatingClosure& on_changed_callback = base::BindRepeating( &WebDataServiceFake::NotifyAutofillMultipleChangedOnUISequence, AsWeakPtr()); - const base::Callback<void(syncer::ModelType)> on_sync_started_callback = - base::Bind(&WebDataServiceFake::NotifySyncStartedOnUISequence, - AsWeakPtr()); + const base::RepeatingCallback<void(syncer::ModelType)>& + on_sync_started_callback = base::BindRepeating( + &WebDataServiceFake::NotifySyncStartedOnUISequence, AsWeakPtr()); db_task_runner_->PostTask( FROM_HERE, base::Bind(&WebDataServiceFake::CreateSyncableService, base::Unretained(this), on_changed_callback, - on_sync_started_callback)); + std::move(on_sync_started_callback))); syncable_service_created_or_destroyed_.Wait(); } @@ -308,27 +261,15 @@ WebDatabase* GetDatabase() override { return web_database_; } - void OnAutofillEntriesChanged(const AutofillChangeList& changes) { - WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - - base::Closure notify_cb = - base::Bind(&AutocompleteSyncableService::AutofillEntriesChanged, - base::Unretained(autocomplete_syncable_service_), changes); - db_task_runner_->PostTask(FROM_HERE, - base::Bind(&RunAndSignal, notify_cb, &event)); - event.Wait(); - } - void OnAutofillProfileChanged(const AutofillProfileChange& changes) { WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED); - base::Closure notify_cb = base::Bind( - &AutocompleteSyncableService::AutofillProfileChanged, + base::OnceClosure notify_cb = base::BindOnce( + &AutofillProfileSyncableService::AutofillProfileChanged, base::Unretained(autofill_profile_syncable_service_), changes); - db_task_runner_->PostTask(FROM_HERE, - base::Bind(&RunAndSignal, notify_cb, &event)); + db_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&RunAndSignal, std::move(notify_cb), &event)); event.Wait(); } @@ -336,20 +277,16 @@ ~WebDataServiceFake() override {} void CreateSyncableService( - const base::Closure& on_changed_callback, - const base::Callback<void(syncer::ModelType)>& on_sync_started) { + const base::RepeatingClosure& on_changed_callback, + const base::RepeatingCallback<void(syncer::ModelType)>& on_sync_started) { ASSERT_TRUE(db_task_runner_->RunsTasksInCurrentSequence()); // These services are deleted in DestroySyncableService(). backend_ = std::make_unique<MockAutofillBackend>( GetDatabase(), on_changed_callback, on_sync_started, ui_task_runner_.get()); - AutocompleteSyncableService::CreateForWebDataServiceAndBackend( - this, backend_.get()); AutofillProfileSyncableService::CreateForWebDataServiceAndBackend( this, backend_.get(), "en-US"); - autocomplete_syncable_service_ = - AutocompleteSyncableService::FromWebDataService(this); autofill_profile_syncable_service_ = AutofillProfileSyncableService::FromWebDataService(this); @@ -358,14 +295,12 @@ void DestroySyncableService() { ASSERT_TRUE(db_task_runner_->RunsTasksInCurrentSequence()); - autocomplete_syncable_service_ = nullptr; autofill_profile_syncable_service_ = nullptr; backend_.reset(); syncable_service_created_or_destroyed_.Signal(); } WebDatabase* web_database_; - AutocompleteSyncableService* autocomplete_syncable_service_; AutofillProfileSyncableService* autofill_profile_syncable_service_; std::unique_ptr<autofill::AutofillWebDataBackend> backend_; @@ -393,8 +328,7 @@ MOCK_METHOD0(Refresh, void()); }; -template <class T> -class AddAutofillHelper; +class AddAutofillProfileHelper; class ProfileSyncServiceAutofillTest : public AbstractProfileSyncServiceTest, @@ -449,12 +383,6 @@ builder.set_activate_model_creation(); sync_client_owned_ = builder.Build(); sync_client_ = sync_client_owned_.get(); - - // When UpdateAutofillEntries() is called with an empty list, the return - // value should be |true|, rather than the default of |false|. - std::vector<AutofillEntry> empty; - EXPECT_CALL(autofill_table_, UpdateAutofillEntries(empty)) - .WillRepeatedly(Return(true)); } ~ProfileSyncServiceAutofillTest() override { @@ -469,20 +397,18 @@ sync_service()->Shutdown(); } - int GetSyncCount(syncer::ModelType type) { + int GetSyncCount() { syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare()); syncer::ReadNode node(&trans); - if (node.InitTypeRoot(type) != BaseNode::INIT_OK) + if (node.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) return 0; return node.GetTotalNodeCount() - 1; } - void StartSyncService(const base::Closure& callback, - bool will_fail_association, - syncer::ModelType type) { + void StartAutofillProfileSyncService(base::OnceClosure callback) { SigninManagerBase* signin = profile_sync_service_bundle()->signin_manager(); signin->SetAuthenticatedAccountInfo("12345", "test_user@gmail.com"); - CreateSyncService(std::move(sync_client_owned_), callback); + CreateSyncService(std::move(sync_client_owned_), std::move(callback)); EXPECT_CALL(*profile_sync_service_bundle()->component_factory(), CreateDataTypeManager(_, _, _, _, _, _)) @@ -497,14 +423,17 @@ profile_sync_service_bundle()->auth_service()->UpdateCredentials( signin->GetAuthenticatedAccountId(), "oauth2_login_token"); - sync_service()->RegisterDataTypeController(CreateDataTypeController(type)); + sync_service()->RegisterDataTypeController( + std::make_unique<AutofillProfileDataTypeController>( + data_type_thread()->task_runner(), base::DoNothing(), sync_client_, + web_data_service_)); sync_service()->Initialize(); base::RunLoop().Run(); // It's possible this test triggered an unrecoverable error, in which case // we can't get the sync count. if (sync_service()->IsSyncActive()) { - EXPECT_EQ(GetSyncCount(type), + EXPECT_EQ(GetSyncCount(), association_stats_.num_sync_items_after_association); } EXPECT_EQ(association_stats_.num_sync_items_after_association, @@ -513,23 +442,6 @@ association_stats_.num_sync_items_deleted); } - bool AddAutofillSyncNode(const AutofillEntry& entry) { - syncer::WriteTransaction trans(FROM_HERE, sync_service()->GetUserShare()); - syncer::WriteNode node(&trans); - std::string tag = AutocompleteSyncableService::KeyToTag( - base::UTF16ToUTF8(entry.key().name()), - base::UTF16ToUTF8(entry.key().value())); - syncer::WriteNode::InitUniqueByCreationResult result = - node.InitUniqueByCreation(AUTOFILL, tag); - if (result != syncer::WriteNode::INIT_SUCCESS) - return false; - - sync_pb::EntitySpecifics specifics; - AutocompleteSyncableService::WriteAutofillEntry(entry, &specifics); - node.SetEntitySpecifics(specifics); - return true; - } - bool AddAutofillSyncNode(const AutofillProfile& profile) { syncer::WriteTransaction trans(FROM_HERE, sync_service()->GetUserShare()); syncer::WriteNode node(&trans); @@ -545,45 +457,6 @@ return true; } - bool GetAutofillEntriesFromSyncDB(std::vector<AutofillEntry>* entries, - std::vector<AutofillProfile>* profiles) { - syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare()); - syncer::ReadNode autofill_root(&trans); - if (autofill_root.InitTypeRoot(AUTOFILL) != BaseNode::INIT_OK) { - return false; - } - - int64_t child_id = autofill_root.GetFirstChildId(); - while (child_id != syncer::kInvalidId) { - syncer::ReadNode child_node(&trans); - if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK) - return false; - - const sync_pb::AutofillSpecifics& autofill( - child_node.GetEntitySpecifics().autofill()); - if (autofill.has_value()) { - AutofillKey key(base::UTF8ToUTF16(autofill.name()), - base::UTF8ToUTF16(autofill.value())); - std::vector<Time> timestamps; - int timestamps_count = autofill.usage_timestamp_size(); - for (int i = 0; i < timestamps_count; ++i) { - timestamps.push_back( - Time::FromInternalValue(autofill.usage_timestamp(i))); - } - entries->push_back( - AutofillEntry(key, timestamps.front(), timestamps.back())); - } else if (autofill.has_profile()) { - AutofillProfile p; - p.set_guid(autofill.profile().guid()); - AutofillProfileSyncableService::OverwriteProfileWithServerData( - autofill.profile(), &p); - profiles->push_back(p); - } - child_id = child_node.GetSuccessorId(); - } - return true; - } - bool GetAutofillProfilesFromSyncDBUnderProfileNode( std::vector<AutofillProfile>* profiles) { syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare()); @@ -613,24 +486,6 @@ void SetIdleChangeProcessorExpectations() { EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0); EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).Times(0); - - // Only permit UpdateAutofillEntries() to be called with an empty list. - std::vector<AutofillEntry> empty; - EXPECT_CALL(autofill_table_, UpdateAutofillEntries(Not(empty))).Times(0); - } - - std::unique_ptr<syncer::DataTypeController> CreateDataTypeController( - syncer::ModelType type) { - DCHECK(type == AUTOFILL || type == AUTOFILL_PROFILE); - if (type == AUTOFILL) { - return std::make_unique<AutofillDataTypeController>( - data_type_thread()->task_runner(), base::DoNothing(), sync_client_, - web_data_service_); - } else { - return std::make_unique<AutofillProfileDataTypeController>( - data_type_thread()->task_runner(), base::DoNothing(), sync_client_, - web_data_service_); - } } AutofillTableMock& autofill_table() { return autofill_table_; } @@ -642,21 +497,14 @@ WebDataServiceFake* web_data_service() { return web_data_service_.get(); } private: - friend class AddAutofillHelper<AutofillEntry>; - friend class AddAutofillHelper<AutofillProfile>; + friend class AddAutofillProfileHelper; base::WeakPtr<syncer::SyncableService> GetSyncableServiceForType( syncer::ModelType type) { - DCHECK(type == AUTOFILL || type == AUTOFILL_PROFILE); - if (type == AUTOFILL) { - return AutocompleteSyncableService::FromWebDataService( - web_data_service_.get()) - ->AsWeakPtr(); - } else { - return AutofillProfileSyncableService::FromWebDataService( - web_data_service_.get()) - ->AsWeakPtr(); - } + DCHECK(type == AUTOFILL_PROFILE); + return AutofillProfileSyncableService::FromWebDataService( + web_data_service_.get()) + ->AsWeakPtr(); } AutofillTableMock autofill_table_; @@ -675,24 +523,23 @@ DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceAutofillTest); }; -template <class T> -class AddAutofillHelper { +class AddAutofillProfileHelper { public: - AddAutofillHelper(ProfileSyncServiceAutofillTest* test, - const std::vector<T>& entries) - : callback_(base::Bind(&AddAutofillHelper::AddAutofillCallback, - base::Unretained(this), - test, - entries)), + AddAutofillProfileHelper(ProfileSyncServiceAutofillTest* test, + const std::vector<AutofillProfile>& entries) + : callback_(base::BindOnce(&AddAutofillProfileHelper::AddAutofillCallback, + base::Unretained(this), + test, + entries)), success_(false) {} - const base::Closure& callback() const { return callback_; } + base::OnceClosure callback() { return std::move(callback_); } bool success() { return success_; } private: void AddAutofillCallback(ProfileSyncServiceAutofillTest* test, - const std::vector<T>& entries) { - if (!test->CreateRoot(GetModelType<T>())) + const std::vector<AutofillProfile>& entries) { + if (!test->CreateRoot(AUTOFILL_PROFILE)) return; for (size_t i = 0; i < entries.size(); ++i) { @@ -702,167 +549,10 @@ success_ = true; } - base::Closure callback_; + base::OnceClosure callback_; bool success_; }; -// Overload write transaction to use custom NotifyTransactionComplete -class WriteTransactionTest : public WriteTransaction { - public: - WriteTransactionTest(const base::Location& from_here, - WriterTag writer, - syncer::syncable::Directory* directory, - WaitableEvent* wait_for_syncapi) - : WriteTransaction(from_here, writer, directory), - wait_for_syncapi_(wait_for_syncapi) {} - - void NotifyTransactionComplete(syncer::ModelTypeSet types) override { - // This is where we differ. Force a thread change here, giving another - // thread a chance to create a WriteTransaction - wait_for_syncapi_->Wait(); - - WriteTransaction::NotifyTransactionComplete(types); - } - - private: - WaitableEvent* const wait_for_syncapi_; -}; - -// Our fake server updater. Needs the RefCountedThreadSafe inheritance so we can -// post tasks with it. -class FakeServerUpdater : public base::RefCountedThreadSafe<FakeServerUpdater> { - public: - FakeServerUpdater(TestProfileSyncService* service, - WaitableEvent* wait_for_start, - WaitableEvent* wait_for_syncapi, - scoped_refptr<base::SequencedTaskRunner> db_task_runner) - : entry_(MakeAutofillEntry("0", "0", 0)), - service_(service), - wait_for_start_(wait_for_start), - wait_for_syncapi_(wait_for_syncapi), - is_finished_(base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED), - db_task_runner_(db_task_runner) {} - - void Update() { - // This gets called in a modelsafeworker thread. - ASSERT_TRUE(db_task_runner_->RunsTasksInCurrentSequence()); - - syncer::UserShare* user_share = service_->GetUserShare(); - syncer::syncable::Directory* directory = user_share->directory.get(); - - // Create autofill protobuf. - std::string tag = AutocompleteSyncableService::KeyToTag( - base::UTF16ToUTF8(entry_.key().name()), - base::UTF16ToUTF8(entry_.key().value())); - sync_pb::AutofillSpecifics new_autofill; - new_autofill.set_name(base::UTF16ToUTF8(entry_.key().name())); - new_autofill.set_value(base::UTF16ToUTF8(entry_.key().value())); - new_autofill.add_usage_timestamp(entry_.date_created().ToInternalValue()); - if (entry_.date_created() != entry_.date_last_used()) { - new_autofill.add_usage_timestamp( - entry_.date_last_used().ToInternalValue()); - } - - sync_pb::EntitySpecifics entity_specifics; - entity_specifics.mutable_autofill()->CopyFrom(new_autofill); - - { - // Tell main thread we've started - wait_for_start_->Signal(); - - // Create write transaction. - WriteTransactionTest trans(FROM_HERE, UNITTEST, directory, - wait_for_syncapi_); - - // Create actual entry based on autofill protobuf information. - // Simulates effects of UpdateLocalDataFromServerData - MutableEntry parent(&trans, GET_TYPE_ROOT, AUTOFILL); - MutableEntry item(&trans, CREATE, AUTOFILL, parent.GetId(), tag); - ASSERT_TRUE(item.good()); - item.PutSpecifics(entity_specifics); - item.PutServerSpecifics(entity_specifics); - item.PutBaseVersion(1); - syncer::syncable::Id server_item_id = - service_->id_factory()->NewServerId(); - item.PutId(server_item_id); - syncer::syncable::Id new_predecessor; - ASSERT_TRUE(item.PutPredecessor(new_predecessor)); - } - DVLOG(1) << "FakeServerUpdater finishing."; - is_finished_.Signal(); - } - - void CreateNewEntry(const AutofillEntry& entry) { - entry_ = entry; - ASSERT_FALSE(db_task_runner_->RunsTasksInCurrentSequence()); - if (!db_task_runner_->PostTask( - FROM_HERE, base::Bind(&FakeServerUpdater::Update, this))) { - NOTREACHED() << "Failed to post task to the db sequence."; - return; - } - } - - void WaitForUpdateCompletion() { is_finished_.Wait(); } - - private: - friend class base::RefCountedThreadSafe<FakeServerUpdater>; - ~FakeServerUpdater() {} - - AutofillEntry entry_; - TestProfileSyncService* service_; - WaitableEvent* const wait_for_start_; - WaitableEvent* const wait_for_syncapi_; - WaitableEvent is_finished_; - syncer::syncable::Id parent_id_; - scoped_refptr<base::SequencedTaskRunner> db_task_runner_; - - DISALLOW_COPY_AND_ASSIGN(FakeServerUpdater); -}; - -// TODO(skrul): Test abort startup. -// TODO(skrul): Test processing of cloud changes. -// TODO(tim): Add autofill data type controller test, and a case to cover -// waiting for the PersonalDataManager. -TEST_F(ProfileSyncServiceAutofillTest, FailModelAssociation) { - // Don't create the root autofill node so startup fails. - StartSyncService(base::Closure(), true, AUTOFILL); - EXPECT_TRUE(sync_service()->HasUnrecoverableError()); -} - -TEST_F(ProfileSyncServiceAutofillTest, EmptyNativeEmptySync) { - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(Return(true)); - SetIdleChangeProcessorExpectations(); - CreateRootHelper create_root(this, AUTOFILL); - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(create_root.callback(), false, AUTOFILL); - EXPECT_TRUE(create_root.success()); - std::vector<AutofillEntry> sync_entries; - std::vector<AutofillProfile> sync_profiles; - ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); - EXPECT_EQ(0U, sync_entries.size()); - EXPECT_EQ(0U, sync_profiles.size()); -} - -TEST_F(ProfileSyncServiceAutofillTest, HasNativeEntriesEmptySync) { - std::vector<AutofillEntry> entries; - entries.push_back(MakeAutofillEntry("foo", "bar", 1)); - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(entries), Return(true))); - SetIdleChangeProcessorExpectations(); - CreateRootHelper create_root(this, AUTOFILL); - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - std::vector<AutofillEntry> sync_entries; - std::vector<AutofillProfile> sync_profiles; - ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); - ASSERT_EQ(1U, sync_entries.size()); - EXPECT_EQ(entries[0], sync_entries[0]); - EXPECT_EQ(0U, sync_profiles.size()); -} - TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) { std::vector<std::unique_ptr<AutofillProfile>> profiles; std::vector<AutofillProfile> expected_profiles; @@ -880,7 +570,7 @@ EXPECT_CALL(personal_data_manager(), Refresh()); SetIdleChangeProcessorExpectations(); CreateRootHelper create_root(this, AUTOFILL_PROFILE); - StartSyncService(create_root.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(create_root.callback()); ASSERT_TRUE(create_root.success()); std::vector<AutofillProfile> sync_profiles; ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles)); @@ -888,140 +578,6 @@ EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0])); } -TEST_F(ProfileSyncServiceAutofillTest, HasNativeWithDuplicatesEmptySync) { - // There is buggy autofill code that allows duplicate name/value - // pairs to exist in the database with separate pair_ids. - std::vector<AutofillEntry> entries; - entries.push_back(MakeAutofillEntry("foo", "bar", 1)); - entries.push_back(MakeAutofillEntry("dup", "", 2)); - entries.push_back(MakeAutofillEntry("dup", "", 3)); - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(entries), Return(true))); - SetIdleChangeProcessorExpectations(); - CreateRootHelper create_root(this, AUTOFILL); - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - std::vector<AutofillEntry> sync_entries; - std::vector<AutofillProfile> sync_profiles; - ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); - EXPECT_EQ(2U, sync_entries.size()); -} - -TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge) { - AutofillEntry native_entry(MakeAutofillEntry("native", "entry", 1)); - AutofillEntry sync_entry(MakeAutofillEntry("sync", "entry", 2)); - - std::vector<AutofillEntry> native_entries; - native_entries.push_back(native_entry); - - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true))); - - std::vector<AutofillEntry> sync_entries; - sync_entries.push_back(sync_entry); - - AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries); - - EXPECT_CALL(autofill_table(), UpdateAutofillEntries(ElementsAre(sync_entry))) - .WillOnce(Return(true)); - - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL); - ASSERT_TRUE(add_autofill.success()); - - std::set<AutofillEntry> expected_entries; - expected_entries.insert(native_entry); - expected_entries.insert(sync_entry); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(), - new_sync_entries.end()); - - EXPECT_EQ(expected_entries, new_sync_entries_set); -} - -TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncNoMerge_NullTerminated) { - const char kEntry[] = "entry"; - // A value which contains null terminating symbol. - std::string entry(kEntry, arraysize(kEntry)); - AutofillEntry native_entry0(MakeAutofillEntry("native", kEntry, 1)); - AutofillEntry native_entry1(MakeAutofillEntry("native", entry, 1)); - AutofillEntry sync_entry0(MakeAutofillEntry("sync", kEntry, 2)); - AutofillEntry sync_entry1(MakeAutofillEntry("sync", entry, 2)); - - std::vector<AutofillEntry> native_entries; - native_entries.push_back(native_entry0); - native_entries.push_back(native_entry1); - - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true))); - - std::vector<AutofillEntry> sync_entries; - sync_entries.push_back(sync_entry0); - sync_entries.push_back(sync_entry1); - - AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries); - - // Expecting that sync_entry0 and sync_entry1 will be written in an autofill - // table and a value in sync_entry1 won't lose null terminating symbol. - EXPECT_CALL(autofill_table(), - UpdateAutofillEntries(ElementsAre(sync_entry0, sync_entry1))) - .WillOnce(Return(true)); - - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL); - ASSERT_TRUE(add_autofill.success()); - - // Expecting that native_entry0 and native_entry1 won't merge into one entry. - std::set<AutofillEntry> expected_entries; - expected_entries.insert(native_entry0); - expected_entries.insert(native_entry1); - expected_entries.insert(sync_entry0); - expected_entries.insert(sync_entry1); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - std::set<AutofillEntry> new_sync_entries_set(new_sync_entries.begin(), - new_sync_entries.end()); - - EXPECT_EQ(expected_entries, new_sync_entries_set); -} - -TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeEntry) { - AutofillEntry native_entry(MakeAutofillEntry("merge", "entry", 1)); - AutofillEntry sync_entry(MakeAutofillEntry("merge", "entry", 2)); - AutofillEntry merged_entry(MakeAutofillEntry("merge", "entry", 1, 2)); - - std::vector<AutofillEntry> native_entries; - native_entries.push_back(native_entry); - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(native_entries), Return(true))); - - std::vector<AutofillEntry> sync_entries; - sync_entries.push_back(sync_entry); - AddAutofillHelper<AutofillEntry> add_autofill(this, sync_entries); - - EXPECT_CALL(autofill_table(), - UpdateAutofillEntries(ElementsAre(merged_entry))) - .WillOnce(Return(true)); - EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL); - ASSERT_TRUE(add_autofill.success()); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - ASSERT_EQ(1U, new_sync_entries.size()); - EXPECT_EQ(merged_entry, new_sync_entries[0]); -} - TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) { AutofillProfile sync_profile; autofill::test::SetProfileInfoWithGuid( @@ -1046,13 +602,13 @@ std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(autofill_table(), UpdateAutofillProfile(MatchProfiles(sync_profile))) .WillOnce(Return(true)); EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1105,11 +661,11 @@ .WillOnce(Return(true)); std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(personal_data_manager(), Refresh()); // Adds all entries in |sync_profiles| to sync. - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1170,11 +726,11 @@ .WillOnce(Return(true)); std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(personal_data_manager(), Refresh()); // Adds all entries in |sync_profiles| to sync. - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1237,11 +793,11 @@ .WillOnce(Return(true)); std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(personal_data_manager(), Refresh()); // Adds all entries in |sync_profiles| to sync. - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1289,11 +845,11 @@ .WillOnce(Return(true)); std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(personal_data_manager(), Refresh()); // Adds all entries in |sync_profiles| to sync. - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1336,13 +892,13 @@ std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(autofill_table(), AddAutofillProfile(_)).WillOnce(Return(true)); EXPECT_CALL(autofill_table(), RemoveAutofillProfile(native_guid)) .WillOnce(Return(true)); EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); std::vector<AutofillProfile> new_sync_profiles; @@ -1359,41 +915,13 @@ EXPECT_EQ(base::Time::FromTimeT(1234), new_sync_profiles[0].use_date()); } -TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddEntry) { - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(Return(true)); - EXPECT_CALL(personal_data_manager(), Refresh()); - SetIdleChangeProcessorExpectations(); - CreateRootHelper create_root(this, AUTOFILL); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - - AutofillEntry added_entry(MakeAutofillEntry("added", "entry", 1)); - - EXPECT_CALL(autofill_table(), GetAutofillTimestamps(_, _, _, _)) - .WillOnce(DoAll(SetArgPointee<2>(added_entry.date_created()), - SetArgPointee<3>(added_entry.date_last_used()), - Return(true))); - - AutofillChangeList changes; - changes.push_back(AutofillChange(AutofillChange::ADD, added_entry.key())); - - web_data_service()->OnAutofillEntriesChanged(changes); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - ASSERT_EQ(1U, new_sync_entries.size()); - EXPECT_EQ(added_entry, new_sync_entries[0]); -} TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) { EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)).WillOnce(Return(true)); EXPECT_CALL(personal_data_manager(), Refresh()); SetIdleChangeProcessorExpectations(); CreateRootHelper create_root(this, AUTOFILL_PROFILE); - StartSyncService(create_root.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(create_root.callback()); ASSERT_TRUE(create_root.success()); AutofillProfile added_profile; @@ -1413,62 +941,6 @@ EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0])); } -TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeUpdateEntry) { - AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1)); - std::vector<AutofillEntry> original_entries; - original_entries.push_back(original_entry); - - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true))); - EXPECT_CALL(personal_data_manager(), Refresh()); - CreateRootHelper create_root(this, AUTOFILL); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - - AutofillEntry updated_entry(MakeAutofillEntry("my", "entry", 1, 2)); - - EXPECT_CALL(autofill_table(), GetAutofillTimestamps(_, _, _, _)) - .WillOnce(DoAll(SetArgPointee<2>(updated_entry.date_created()), - SetArgPointee<3>(updated_entry.date_last_used()), - Return(true))); - - AutofillChangeList changes; - changes.push_back( - AutofillChange(AutofillChange::UPDATE, updated_entry.key())); - web_data_service()->OnAutofillEntriesChanged(changes); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - ASSERT_EQ(1U, new_sync_entries.size()); - EXPECT_EQ(updated_entry, new_sync_entries[0]); -} - -TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveEntry) { - AutofillEntry original_entry(MakeAutofillEntry("my", "entry", 1)); - std::vector<AutofillEntry> original_entries; - original_entries.push_back(original_entry); - - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .WillOnce(DoAll(SetArgPointee<0>(original_entries), Return(true))); - EXPECT_CALL(personal_data_manager(), Refresh()); - CreateRootHelper create_root(this, AUTOFILL); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - - AutofillChangeList changes; - changes.push_back( - AutofillChange(AutofillChange::REMOVE, original_entry.key())); - web_data_service()->OnAutofillEntriesChanged(changes); - - std::vector<AutofillEntry> new_sync_entries; - std::vector<AutofillProfile> new_sync_profiles; - ASSERT_TRUE( - GetAutofillEntriesFromSyncDB(&new_sync_entries, &new_sync_profiles)); - ASSERT_EQ(0U, new_sync_entries.size()); -} - TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) { AutofillProfile sync_profile; autofill::test::SetProfileInfoWithGuid( @@ -1492,9 +964,9 @@ std::vector<AutofillProfile> sync_profiles; sync_profiles.push_back(sync_profile); - AddAutofillHelper<AutofillProfile> add_autofill(this, sync_profiles); + AddAutofillProfileHelper add_autofill(this, sync_profiles); EXPECT_CALL(personal_data_manager(), Refresh()); - StartSyncService(add_autofill.callback(), false, AUTOFILL_PROFILE); + StartAutofillProfileSyncService(add_autofill.callback()); ASSERT_TRUE(add_autofill.success()); AutofillProfileChange change(AutofillProfileChange::REMOVE, @@ -1507,62 +979,4 @@ ASSERT_EQ(0U, new_sync_profiles.size()); } -TEST_F(ProfileSyncServiceAutofillTest, ServerChangeRace) { - // Once for MergeDataAndStartSyncing() and twice for ProcessSyncChanges(), via - // LoadAutofillData(). - EXPECT_CALL(autofill_table(), GetAllAutofillEntries(_)) - .Times(3) - .WillRepeatedly(Return(true)); - // On the other hand Autofill and Autocomplete are separated now, so - // GetAutofillProfiles() should not be called. - EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)).Times(0); - EXPECT_CALL(autofill_table(), UpdateAutofillEntries(_)) - .WillRepeatedly(Return(true)); - EXPECT_CALL(personal_data_manager(), Refresh()).Times(3); - CreateRootHelper create_root(this, AUTOFILL); - StartSyncService(create_root.callback(), false, AUTOFILL); - ASSERT_TRUE(create_root.success()); - - std::unique_ptr<WaitableEvent> wait_for_start( - new WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED)); - std::unique_ptr<WaitableEvent> wait_for_syncapi( - new WaitableEvent(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED)); - scoped_refptr<FakeServerUpdater> updater(new FakeServerUpdater( - sync_service(), wait_for_start.get(), wait_for_syncapi.get(), - data_type_thread()->task_runner())); - - // This server side update will stall waiting for CommitWaiter. - updater->CreateNewEntry(MakeAutofillEntry("server", "entry", 1)); - wait_for_start->Wait(); - - AutofillEntry syncapi_entry(MakeAutofillEntry("syncapi", "entry", 2)); - ASSERT_TRUE(AddAutofillSyncNode(syncapi_entry)); - DVLOG(1) << "Syncapi update finished."; - - // If we reach here, it means syncapi succeeded and we didn't deadlock. Yay! - // Signal FakeServerUpdater that it can complete. - wait_for_syncapi->Signal(); - - // Make another entry to ensure nothing broke afterwards and wait for finish - // to clean up. - updater->WaitForUpdateCompletion(); - updater->CreateNewEntry(MakeAutofillEntry("server2", "entry2", 3)); - updater->WaitForUpdateCompletion(); - - // Let callbacks posted on UI sequence execute. - base::RunLoop().RunUntilIdle(); - - std::vector<AutofillEntry> sync_entries; - std::vector<AutofillProfile> sync_profiles; - ASSERT_TRUE(GetAutofillEntriesFromSyncDB(&sync_entries, &sync_profiles)); - EXPECT_EQ(3U, sync_entries.size()); - EXPECT_EQ(0U, sync_profiles.size()); - for (size_t i = 0; i < sync_entries.size(); i++) { - DVLOG(1) << "Entry " << i << ": " << sync_entries[i].key().name() << ", " - << sync_entries[i].key().value(); - } -} - } // namespace browser_sync
diff --git a/components/cronet/ios/test/BUILD.gn b/components/cronet/ios/test/BUILD.gn index 7a074f5..a8da143d 100644 --- a/components/cronet/ios/test/BUILD.gn +++ b/components/cronet/ios/test/BUILD.gn
@@ -30,7 +30,6 @@ "//components/cronet/native/test:cronet_native_tests", "//components/cronet/test:test_support", "//components/grpc_support:bidirectional_stream_unittest", - "//components/grpc_support/test:quic_test_server", "//net", "//net:simple_quic_tools", "//net:test_support",
diff --git a/components/cronet/ios/test/cronet_http_test.mm b/components/cronet/ios/test/cronet_http_test.mm index dafe20a..fb95316 100644 --- a/components/cronet/ios/test/cronet_http_test.mm +++ b/components/cronet/ios/test/cronet_http_test.mm
@@ -16,10 +16,10 @@ #include "components/cronet/ios/test/cronet_test_base.h" #include "components/cronet/ios/test/start_cronet.h" #include "components/cronet/test/test_server.h" -#include "components/grpc_support/test/quic_test_server.h" #include "net/base/mac/url_conversions.h" #include "net/base/net_errors.h" #include "net/cert/mock_cert_verifier.h" +#include "net/test/quic_simple_test_server.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" @@ -112,7 +112,7 @@ [Cronet setRequestFilterBlock:^(NSURLRequest* request) { return YES; }]; - StartCronet(grpc_support::GetQuicTestServerPort()); + StartCronet(net::QuicSimpleTestServer::GetPort()); [Cronet registerHttpProtocolHandler]; NSURLSessionConfiguration* config = [NSURLSessionConfiguration ephemeralSessionConfiguration]; @@ -151,7 +151,7 @@ [NSString stringWithFormat:@"{\"ssl_key_log_file\":\"%@\"}", ssl_key_log_file]]; - StartCronet(grpc_support::GetQuicTestServerPort()); + StartCronet(net::QuicSimpleTestServer::GetPort()); bool ssl_file_created = [[NSFileManager defaultManager] fileExistsAtPath:ssl_key_log_file]; @@ -165,7 +165,7 @@ } TEST_F(HttpTest, NSURLSessionReceivesData) { - NSURL* url = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); + NSURL* url = net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); __block BOOL block_used = NO; NSURLSessionDataTask* task = [session_ dataTaskWithURL:url]; [Cronet setRequestFilterBlock:^(NSURLRequest* request) { @@ -176,19 +176,18 @@ StartDataTaskAndWaitForCompletion(task); EXPECT_TRUE(block_used); EXPECT_EQ(nil, [delegate_ error]); - EXPECT_STREQ(grpc_support::kSimpleBodyValue, - base::SysNSStringToUTF8([delegate_ responseBody]).c_str()); + EXPECT_EQ(net::QuicSimpleTestServer::GetSimpleBodyValue(), + base::SysNSStringToUTF8([delegate_ responseBody])); } TEST_F(HttpTest, GetGlobalMetricsDeltas) { NSData* delta1 = [Cronet getGlobalMetricsDeltas]; - - NSURL* url = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); + NSURL* url = net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); NSURLSessionDataTask* task = [session_ dataTaskWithURL:url]; StartDataTaskAndWaitForCompletion(task); EXPECT_EQ(nil, [delegate_ error]); - EXPECT_STREQ(grpc_support::kSimpleBodyValue, - base::SysNSStringToUTF8([delegate_ responseBody]).c_str()); + EXPECT_EQ(net::QuicSimpleTestServer::GetSimpleBodyValue(), + base::SysNSStringToUTF8([delegate_ responseBody])); NSData* delta2 = [Cronet getGlobalMetricsDeltas]; EXPECT_FALSE([delta2 isEqualToData:delta1]); @@ -423,7 +422,7 @@ [Cronet setBrotliEnabled:YES]; - StartCronet(grpc_support::GetQuicTestServerPort()); + StartCronet(net::QuicSimpleTestServer::GetPort()); NSURL* url = net::NSURLWithGURL(GURL(TestServer::GetEchoHeaderURL("Accept-Encoding"))); @@ -438,7 +437,7 @@ [Cronet setBrotliEnabled:NO]; - StartCronet(grpc_support::GetQuicTestServerPort()); + StartCronet(net::QuicSimpleTestServer::GetPort()); NSURL* url = net::NSURLWithGURL(GURL(TestServer::GetEchoHeaderURL("Accept-Encoding"))); @@ -453,7 +452,7 @@ [Cronet setBrotliEnabled:YES]; - StartCronet(grpc_support::GetQuicTestServerPort()); + StartCronet(net::QuicSimpleTestServer::GetPort()); NSURL* url = net::NSURLWithGURL(GURL(TestServer::GetUseEncodingURL("brotli"))); @@ -679,7 +678,7 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" TEST_F(HttpTest, LegacyApi) { - NSURL* url = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); + NSURL* url = net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); __block BOOL block_used = NO; [Cronet setRequestFilterBlock:^(NSURLRequest* request) {
diff --git a/components/cronet/ios/test/cronet_metrics_test.mm b/components/cronet/ios/test/cronet_metrics_test.mm index f4032bd..d5849ab 100644 --- a/components/cronet/ios/test/cronet_metrics_test.mm +++ b/components/cronet/ios/test/cronet_metrics_test.mm
@@ -8,8 +8,8 @@ #include "components/cronet/ios/test/cronet_test_base.h" #include "components/cronet/ios/test/start_cronet.h" #include "components/cronet/test/test_server.h" -#include "components/grpc_support/test/quic_test_server.h" #import "net/base/mac/url_conversions.h" +#include "net/test/quic_simple_test_server.h" #include "testing/gtest_mac.h" #include "url/gurl.h" @@ -26,7 +26,7 @@ TestServer::Start(); [Cronet setMetricsEnabled:metrics_enabled]; - StartCronet(grpc_support::GetQuicTestServerPort()); + StartCronet(net::QuicSimpleTestServer::GetPort()); [Cronet registerHttpProtocolHandler]; NSURLSessionConfiguration* config = @@ -67,7 +67,7 @@ // Tests that metrics data is sane for a QUIC request. TEST_F(CronetEnabledMetricsTest, ProtocolIsQuic) { if (@available(iOS 10, *)) { - NSURL* url = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); + NSURL* url = net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); __block BOOL block_used = NO; NSURLSessionDataTask* task = [session_ dataTaskWithURL:url]; @@ -79,8 +79,8 @@ StartDataTaskAndWaitForCompletion(task); EXPECT_TRUE(block_used); EXPECT_EQ(nil, [delegate_ error]); - EXPECT_STREQ(grpc_support::kSimpleBodyValue, - base::SysNSStringToUTF8([delegate_ responseBody]).c_str()); + EXPECT_EQ(net::QuicSimpleTestServer::GetSimpleBodyValue(), + base::SysNSStringToUTF8([delegate_ responseBody])); NSURLSessionTaskMetrics* task_metrics = delegate_.taskMetrics; ASSERT_TRUE(task_metrics); @@ -246,7 +246,7 @@ // Tests that the metrics API behaves sanely when the request is canceled. TEST_F(CronetEnabledMetricsTest, CanceledRequest) { if (@available(iOS 10, *)) { - NSURL* url = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); + NSURL* url = net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); __block BOOL block_used = NO; NSURLSessionDataTask* task = [session_ dataTaskWithURL:url]; @@ -267,7 +267,7 @@ // Tests the metrics data for a reused connection is correct. TEST_F(CronetEnabledMetricsTest, ReusedConnection) { if (@available(iOS 10, *)) { - NSURL* url = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); + NSURL* url = net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); __block BOOL block_used = NO; NSURLSessionDataTask* task = [session_ dataTaskWithURL:url]; @@ -279,8 +279,8 @@ StartDataTaskAndWaitForCompletion(task); EXPECT_TRUE(block_used); EXPECT_EQ(nil, [delegate_ error]); - EXPECT_STREQ(grpc_support::kSimpleBodyValue, - base::SysNSStringToUTF8([delegate_ responseBody]).c_str()); + EXPECT_EQ(net::QuicSimpleTestServer::GetSimpleBodyValue(), + base::SysNSStringToUTF8([delegate_ responseBody])); NSURLSessionTaskMetrics* task_metrics = [delegate_ taskMetrics]; ASSERT_TRUE(task_metrics); @@ -301,8 +301,8 @@ StartDataTaskAndWaitForCompletion(task); EXPECT_TRUE(block_used); EXPECT_EQ(nil, [delegate_ error]); - EXPECT_STREQ(grpc_support::kSimpleBodyValue, - base::SysNSStringToUTF8([delegate_ responseBody]).c_str()); + EXPECT_EQ(net::QuicSimpleTestServer::GetSimpleBodyValue(), + base::SysNSStringToUTF8([delegate_ responseBody])); task_metrics = delegate_.taskMetrics; ASSERT_TRUE(task_metrics); @@ -322,7 +322,7 @@ // Tests that the metrics disable switch works. TEST_F(CronetDisabledMetricsTest, MetricsDisabled) { if (@available(iOS 10, *)) { - NSURL* url = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); + NSURL* url = net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); __block BOOL block_used = NO; NSURLSessionDataTask* task = [session_ dataTaskWithURL:url]; @@ -334,8 +334,8 @@ StartDataTaskAndWaitForCompletion(task); EXPECT_TRUE(block_used); EXPECT_EQ(nil, [delegate_ error]); - EXPECT_STREQ(grpc_support::kSimpleBodyValue, - base::SysNSStringToUTF8([delegate_ responseBody]).c_str()); + EXPECT_EQ(net::QuicSimpleTestServer::GetSimpleBodyValue(), + base::SysNSStringToUTF8([delegate_ responseBody])); NSURLSessionTaskMetrics* task_metrics = [delegate_ taskMetrics]; ASSERT_TRUE(task_metrics); @@ -362,7 +362,7 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" TEST_F(CronetEnabledMetricsTest, LegacyApi) { - NSURL* url = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); + NSURL* url = net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); __block BOOL block_used = NO; [Cronet setRequestFilterBlock:^(NSURLRequest* request) {
diff --git a/components/cronet/ios/test/cronet_netlog_test.mm b/components/cronet/ios/test/cronet_netlog_test.mm index f2e7f81..3eabe0e 100644 --- a/components/cronet/ios/test/cronet_netlog_test.mm +++ b/components/cronet/ios/test/cronet_netlog_test.mm
@@ -7,7 +7,7 @@ #include "components/cronet/ios/test/cronet_test_base.h" #include "components/cronet/ios/test/start_cronet.h" -#include "components/grpc_support/test/quic_test_server.h" +#include "net/test/quic_simple_test_server.h" #include "testing/gtest/include/gtest/gtest.h" namespace cronet { @@ -17,7 +17,7 @@ NetLogTest() {} ~NetLogTest() override {} - void SetUp() override { StartCronet(grpc_support::GetQuicTestServerPort()); } + void SetUp() override { StartCronet(net::QuicSimpleTestServer::GetPort()); } void TearDown() override { [Cronet stopNetLog]; @@ -112,7 +112,7 @@ setExperimentalOptions: @"{ \"QUIC\" : {\"max_server_configs_stored_in_properties\" : 8} }"]; - StartCronet(grpc_support::GetQuicTestServerPort()); + StartCronet(net::QuicSimpleTestServer::GetPort()); bool netlog_started = [Cronet startNetLogToFile:@"cronet_netlog.json" logBytes:NO]; ASSERT_TRUE(netlog_started);
diff --git a/components/cronet/ios/test/cronet_performance_test.mm b/components/cronet/ios/test/cronet_performance_test.mm index a4bf39e..4d53f42 100644 --- a/components/cronet/ios/test/cronet_performance_test.mm +++ b/components/cronet/ios/test/cronet_performance_test.mm
@@ -13,10 +13,10 @@ #include "base/strings/sys_string_conversions.h" #include "components/cronet/ios/test/cronet_test_base.h" #include "components/cronet/test/test_server.h" -#include "components/grpc_support/test/quic_test_server.h" #include "net/base/mac/url_conversions.h" #include "net/base/net_errors.h" #include "net/cert/mock_cert_verifier.h" +#include "net/test/quic_simple_test_server.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" #include "url/gurl.h" @@ -138,7 +138,7 @@ NSString* rules = base::SysUTF8ToNSString( base::StringPrintf("MAP test.example.com 127.0.0.1:%d," "MAP notfound.example.com ~NOTFOUND", - grpc_support::GetQuicTestServerPort())); + net::QuicSimpleTestServer::GetPort())); [Cronet setHostResolverRulesForTesting:rules]; // This is the end of the behavior normally performed by StartCronet()
diff --git a/components/cronet/ios/test/cronet_pkp_test.mm b/components/cronet/ios/test/cronet_pkp_test.mm index 4535515..e9defa60 100644 --- a/components/cronet/ios/test/cronet_pkp_test.mm +++ b/components/cronet/ios/test/cronet_pkp_test.mm
@@ -4,15 +4,16 @@ #import <Cronet/Cronet.h> +#include "base/strings/sys_string_conversions.h" #include "components/cronet/ios/test/cronet_test_base.h" #include "components/cronet/ios/test/start_cronet.h" -#include "components/grpc_support/test/quic_test_server.h" #include "net/base/mac/url_conversions.h" #include "net/cert/mock_cert_verifier.h" #include "net/test/cert_test_util.h" +#include "net/test/quic_simple_test_server.h" #include "net/test/test_data_directory.h" - #include "testing/gtest_mac.h" +#include "url/gurl.h" namespace { const bool kIncludeSubdomains = true; @@ -29,15 +30,13 @@ protected: void SetUp() override { CronetTestBase::SetUp(); - server_host_ = [NSString stringWithCString:grpc_support::kTestServerHost - encoding:NSUTF8StringEncoding]; - server_domain_ = [NSString stringWithCString:grpc_support::kTestServerDomain - encoding:NSUTF8StringEncoding]; - NSString* request_url_str = - [NSString stringWithCString:grpc_support::kTestServerSimpleUrl - encoding:NSUTF8StringEncoding]; - request_url_ = [NSURL URLWithString:request_url_str]; + server_host_ = + base::SysUTF8ToNSString(net::QuicSimpleTestServer::GetHost()); + server_domain_ = + base::SysUTF8ToNSString(net::QuicSimpleTestServer::GetDomain()); + request_url_ = + net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); // Create a Cronet enabled NSURLSession. NSURLSessionConfiguration* sessionConfig = @@ -89,7 +88,7 @@ error:&error]; CHECK(success); CHECK(!error); - StartCronet(grpc_support::GetQuicTestServerPort()); + StartCronet(net::QuicSimpleTestServer::GetPort()); } // Returns an arbitrary public key hash that doesn't match with any test @@ -205,7 +204,7 @@ // Restart Cronet engine and try the same request again. Since the pins are // not persisted, a successful response is expected. - StartCronet(grpc_support::GetQuicTestServerPort()); + StartCronet(net::QuicSimpleTestServer::GetPort()); ASSERT_NO_FATAL_FAILURE(sendRequestAndAssertResult(request_url_, kSuccess)); }
diff --git a/components/cronet/ios/test/cronet_prefs_test.mm b/components/cronet/ios/test/cronet_prefs_test.mm index 5104f5ac..12d7546 100644 --- a/components/cronet/ios/test/cronet_prefs_test.mm +++ b/components/cronet/ios/test/cronet_prefs_test.mm
@@ -9,12 +9,13 @@ #include "components/cronet/ios/test/cronet_test_base.h" #include "components/cronet/ios/test/start_cronet.h" #include "components/cronet/test/test_server.h" -#include "components/grpc_support/test/quic_test_server.h" #include "net/base/mac/url_conversions.h" +#include "net/test/quic_simple_test_server.h" #include "testing/gtest_mac.h" #include "url/gurl.h" namespace cronet { + class PrefsTest : public CronetTestBase { protected: void SetUp() override { @@ -97,10 +98,10 @@ [Cronet setExperimentalOptions:options]; // Start Cronet Engine - StartCronet(grpc_support::GetQuicTestServerPort()); + StartCronet(net::QuicSimpleTestServer::GetPort()); // Start the request - NSURL* url = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); + NSURL* url = net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); NSURLSessionDataTask* task = [session_ dataTaskWithURL:url]; StartDataTaskAndWaitForCompletion(task);
diff --git a/components/cronet/ios/test/cronet_quic_test.mm b/components/cronet/ios/test/cronet_quic_test.mm index a29a6385..feae7918 100644 --- a/components/cronet/ios/test/cronet_quic_test.mm +++ b/components/cronet/ios/test/cronet_quic_test.mm
@@ -7,9 +7,9 @@ #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" #include "components/cronet/ios/test/cronet_test_base.h" -#include "components/grpc_support/test/quic_test_server.h" #include "net/base/mac/url_conversions.h" #include "net/cert/mock_cert_verifier.h" +#include "net/test/quic_simple_test_server.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" #include "url/gurl.h" @@ -38,7 +38,7 @@ }]; // QUIC Server simple URL. - simple_url_ = net::NSURLWithGURL(GURL(grpc_support::kTestServerSimpleUrl)); + simple_url_ = net::NSURLWithGURL(net::QuicSimpleTestServer::GetSimpleURL()); } void TearDown() override { @@ -54,7 +54,7 @@ NSString* rules = base::SysUTF8ToNSString( base::StringPrintf("MAP test.example.com 127.0.0.1:%d," "MAP notfound.example.com ~NOTFOUND", - grpc_support::GetQuicTestServerPort())); + net::QuicSimpleTestServer::GetPort())); [Cronet setHostResolverRulesForTesting:rules]; // Prepare a session. @@ -98,7 +98,7 @@ // Check that a successful response was received using QUIC. EXPECT_EQ(nil, [delegate_ error]); - EXPECT_EQ(grpc_support::kSimpleBodyValue, + EXPECT_EQ(net::QuicSimpleTestServer::GetSimpleBodyValue(), base::SysNSStringToUTF8(delegate_.responseBody)); if (@available(iOS 10, *)) { NSURLSessionTaskTransactionMetrics* metrics =
diff --git a/components/cronet/ios/test/cronet_test_base.mm b/components/cronet/ios/test/cronet_test_base.mm index 712567a0..36e3562 100644 --- a/components/cronet/ios/test/cronet_test_base.mm +++ b/components/cronet/ios/test/cronet_test_base.mm
@@ -6,13 +6,13 @@ #include "base/location.h" #include "base/threading/thread.h" -#include "components/grpc_support/test/quic_test_server.h" #include "crypto/sha2.h" #include "net/base/net_errors.h" #include "net/cert/asn1_util.h" #include "net/cert/mock_cert_verifier.h" #include "net/cert/x509_util.h" #include "net/test/cert_test_util.h" +#include "net/test/quic_simple_test_server.h" #include "net/test/test_data_directory.h" #pragma mark @@ -200,12 +200,12 @@ void CronetTestBase::SetUp() { ::testing::Test::SetUp(); - grpc_support::StartQuicTestServer(); + net::QuicSimpleTestServer::Start(); delegate_ = [[TestDelegate alloc] init]; } void CronetTestBase::TearDown() { - grpc_support::ShutdownQuicTestServer(); + net::QuicSimpleTestServer::Shutdown(); ::testing::Test::TearDown(); }
diff --git a/components/grpc_support/BUILD.gn b/components/grpc_support/BUILD.gn index 95ada09..515aeba5 100644 --- a/components/grpc_support/BUILD.gn +++ b/components/grpc_support/BUILD.gn
@@ -22,7 +22,6 @@ deps = [ ":grpc_support", "//base", - "//components/grpc_support/test:quic_test_server", "//net", "//net:test_support", ]
diff --git a/components/grpc_support/bidirectional_stream_unittest.cc b/components/grpc_support/bidirectional_stream_unittest.cc index e0bea67..ed57fb64f 100644 --- a/components/grpc_support/bidirectional_stream_unittest.cc +++ b/components/grpc_support/bidirectional_stream_unittest.cc
@@ -15,8 +15,8 @@ #include "base/synchronization/waitable_event.h" #include "components/grpc_support/include/bidirectional_stream_c.h" #include "components/grpc_support/test/get_stream_engine.h" -#include "components/grpc_support/test/quic_test_server.h" #include "net/base/net_errors.h" +#include "net/test/quic_simple_test_server.h" #include "net/test/test_data_directory.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -36,23 +36,28 @@ class BidirectionalStreamTest : public ::testing::TestWithParam<bool> { protected: void SetUp() override { - StartQuicTestServer(); - StartTestStreamEngine(GetQuicTestServerPort()); + net::QuicSimpleTestServer::Start(); + StartTestStreamEngine(net::QuicSimpleTestServer::GetPort()); + quic_server_hello_url_ = net::QuicSimpleTestServer::GetHelloURL().spec(); } void TearDown() override { ShutdownTestStreamEngine(); - ShutdownQuicTestServer(); + net::QuicSimpleTestServer::Shutdown(); } BidirectionalStreamTest() {} ~BidirectionalStreamTest() override {} stream_engine* engine() { - return GetTestStreamEngine(GetQuicTestServerPort()); + return GetTestStreamEngine(net::QuicSimpleTestServer::GetPort()); } + const char* test_hello_url() const { return quic_server_hello_url_.c_str(); } + private: + std::string quic_server_hello_url_; + DISALLOW_COPY_AND_ASSIGN(BidirectionalStreamTest); }; @@ -268,29 +273,40 @@ TestBidirectionalStreamCallback::WriteData::~WriteData() {} TEST_P(BidirectionalStreamTest, StartExampleBidiStream) { - TestBidirectionalStreamCallback test; - test.AddWriteData("Hello, "); - test.AddWriteData("world!"); + TestBidirectionalStreamCallback test_callback; + test_callback.AddWriteData("Hello, "); + test_callback.AddWriteData("world!"); // Use small read buffer size to test that response is split properly. - test.read_buffer_size = 2; - test.stream = bidirectional_stream_create(engine(), &test, test.callback()); - DCHECK(test.stream); - bidirectional_stream_delay_request_headers_until_flush(test.stream, + test_callback.read_buffer_size = 2; + test_callback.stream = bidirectional_stream_create(engine(), &test_callback, + test_callback.callback()); + DCHECK(test_callback.stream); + bidirectional_stream_delay_request_headers_until_flush(test_callback.stream, GetParam()); - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, false); - test.BlockForDone(); - ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); - ASSERT_EQ(std::string(kHelloHeaderValue), - test.response_headers[kHelloHeaderName]); - ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); - ASSERT_EQ(std::string(kHelloBodyValue, 2), test.read_data.front()); + bidirectional_stream_start(test_callback.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, false); + test_callback.BlockForDone(); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloStatus(), + test_callback + .response_headers[net::QuicSimpleTestServer::GetStatusHeaderName()]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloHeaderValue(), + test_callback + .response_headers[net::QuicSimpleTestServer::GetHelloHeaderName()]); + ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, + test_callback.response_step); + ASSERT_EQ(std::string(net::QuicSimpleTestServer::GetHelloBodyValue(), 0, 2), + test_callback.read_data.front()); // Verify that individual read data joined using empty separator match // expected body. - ASSERT_EQ(std::string(kHelloBodyValue), base::StrCat(test.read_data)); - ASSERT_EQ(std::string(kHelloTrailerValue), - test.response_trailers[kHelloTrailerName]); - bidirectional_stream_destroy(test.stream); + ASSERT_EQ(net::QuicSimpleTestServer::GetHelloBodyValue(), + base::StrCat(test_callback.read_data)); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloTrailerValue(), + test_callback + .response_trailers[net::QuicSimpleTestServer::GetHelloTrailerName()]); + bidirectional_stream_destroy(test_callback.stream); } TEST_P(BidirectionalStreamTest, SimplePutWithEmptyWriteDataAtTheEnd) { @@ -302,16 +318,21 @@ DCHECK(test.stream); bidirectional_stream_delay_request_headers_until_flush(test.stream, GetParam()); - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "PUT", &kTestHeadersArray, false); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "PUT", + &kTestHeadersArray, false); test.BlockForDone(); - ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); - ASSERT_EQ(std::string(kHelloHeaderValue), - test.response_headers[kHelloHeaderName]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloStatus(), + test.response_headers[net::QuicSimpleTestServer::GetStatusHeaderName()]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloHeaderValue(), + test.response_headers[net::QuicSimpleTestServer::GetHelloHeaderName()]); ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); - ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front()); - ASSERT_EQ(std::string(kHelloTrailerValue), - test.response_trailers[kHelloTrailerName]); + ASSERT_EQ(net::QuicSimpleTestServer::GetHelloBodyValue(), + test.read_data.front()); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloTrailerValue(), + test.response_trailers[net::QuicSimpleTestServer::GetHelloTrailerName()]); bidirectional_stream_destroy(test.stream); } @@ -324,16 +345,21 @@ GetParam()); // Flush before start is ignored. bidirectional_stream_flush(test.stream); - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "GET", &kTestHeadersArray, true); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "GET", + &kTestHeadersArray, true); test.BlockForDone(); - ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); - ASSERT_EQ(std::string(kHelloHeaderValue), - test.response_headers[kHelloHeaderName]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloStatus(), + test.response_headers[net::QuicSimpleTestServer::GetStatusHeaderName()]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloHeaderValue(), + test.response_headers[net::QuicSimpleTestServer::GetHelloHeaderName()]); ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); - ASSERT_EQ(std::string(kHelloBodyValue), base::StrCat(test.read_data)); - ASSERT_EQ(std::string(kHelloTrailerValue), - test.response_trailers[kHelloTrailerName]); + ASSERT_EQ(net::QuicSimpleTestServer::GetHelloBodyValue(), + test.read_data.front()); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloTrailerValue(), + test.response_trailers[net::QuicSimpleTestServer::GetHelloTrailerName()]); // Flush after done is ignored. bidirectional_stream_flush(test.stream); bidirectional_stream_destroy(test.stream); @@ -351,16 +377,21 @@ GetParam()); // Flush before start is ignored. bidirectional_stream_flush(test.stream); - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, false); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, false); test.BlockForDone(); - ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); - ASSERT_EQ(std::string(kHelloHeaderValue), - test.response_headers[kHelloHeaderName]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloStatus(), + test.response_headers[net::QuicSimpleTestServer::GetStatusHeaderName()]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloHeaderValue(), + test.response_headers[net::QuicSimpleTestServer::GetHelloHeaderName()]); ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); - ASSERT_EQ(std::string(kHelloBodyValue), base::StrCat(test.read_data)); - ASSERT_EQ(std::string(kHelloTrailerValue), - test.response_trailers[kHelloTrailerName]); + ASSERT_EQ(net::QuicSimpleTestServer::GetHelloBodyValue(), + base::StrCat(test.read_data)); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloTrailerValue(), + test.response_trailers[net::QuicSimpleTestServer::GetHelloTrailerName()]); // Flush after done is ignored. bidirectional_stream_flush(test.stream); bidirectional_stream_destroy(test.stream); @@ -381,16 +412,21 @@ GetParam()); // Flush before start is ignored. bidirectional_stream_flush(test.stream); - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, false); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, false); test.BlockForDone(); - ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); - ASSERT_EQ(std::string(kHelloHeaderValue), - test.response_headers[kHelloHeaderName]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloStatus(), + test.response_headers[net::QuicSimpleTestServer::GetStatusHeaderName()]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloHeaderValue(), + test.response_headers[net::QuicSimpleTestServer::GetHelloHeaderName()]); ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); - ASSERT_EQ(std::string(kHelloBodyValue), base::StrCat(test.read_data)); - ASSERT_EQ(std::string(kHelloTrailerValue), - test.response_trailers[kHelloTrailerName]); + ASSERT_EQ(net::QuicSimpleTestServer::GetHelloBodyValue(), + base::StrCat(test.read_data)); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloTrailerValue(), + test.response_trailers[net::QuicSimpleTestServer::GetHelloTrailerName()]); // Flush after done is ignored. bidirectional_stream_flush(test.stream); bidirectional_stream_destroy(test.stream); @@ -408,16 +444,21 @@ GetParam()); // Flush before start is ignored. bidirectional_stream_flush(test.stream); - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, false); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, false); test.BlockForDone(); - ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); - ASSERT_EQ(std::string(kHelloHeaderValue), - test.response_headers[kHelloHeaderName]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloStatus(), + test.response_headers[net::QuicSimpleTestServer::GetStatusHeaderName()]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloHeaderValue(), + test.response_headers[net::QuicSimpleTestServer::GetHelloHeaderName()]); ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); - ASSERT_EQ(std::string(kHelloBodyValue), base::StrCat(test.read_data)); - ASSERT_EQ(std::string(kHelloTrailerValue), - test.response_trailers[kHelloTrailerName]); + ASSERT_EQ(net::QuicSimpleTestServer::GetHelloBodyValue(), + base::StrCat(test.read_data)); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloTrailerValue(), + test.response_trailers[net::QuicSimpleTestServer::GetHelloTrailerName()]); // Flush after done is ignored. bidirectional_stream_flush(test.stream); bidirectional_stream_destroy(test.stream); @@ -463,8 +504,8 @@ GetParam()); // Flush before start is ignored. bidirectional_stream_flush(test.stream); - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, false); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, false); test.BlockForDone(); // Flush after done is ignored. bidirectional_stream_flush(test.stream); @@ -478,11 +519,14 @@ bidirectional_stream_delay_request_headers_until_flush(test.stream, GetParam()); test.cancel_from_step = TestBidirectionalStreamCallback::ON_READ_COMPLETED; - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, true); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, true); test.BlockForDone(); - ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); - ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front()); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloStatus(), + test.response_headers[net::QuicSimpleTestServer::GetStatusHeaderName()]); + ASSERT_EQ(net::QuicSimpleTestServer::GetHelloBodyValue(), + test.read_data.front()); ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step); bidirectional_stream_destroy(test.stream); } @@ -494,10 +538,12 @@ bidirectional_stream_delay_request_headers_until_flush(test.stream, GetParam()); test.cancel_from_step = TestBidirectionalStreamCallback::ON_RESPONSE_STARTED; - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, true); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, true); test.BlockForDone(); - ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloStatus(), + test.response_headers[net::QuicSimpleTestServer::GetStatusHeaderName()]); ASSERT_TRUE(test.read_data.empty()); ASSERT_EQ(TestBidirectionalStreamCallback::ON_CANCELED, test.response_step); bidirectional_stream_destroy(test.stream); @@ -510,11 +556,14 @@ bidirectional_stream_delay_request_headers_until_flush(test.stream, GetParam()); test.cancel_from_step = TestBidirectionalStreamCallback::ON_SUCCEEDED; - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, true); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, true); test.BlockForDone(); - ASSERT_EQ(std::string(kHelloStatus), test.response_headers[kStatusHeader]); - ASSERT_EQ(std::string(kHelloBodyValue), test.read_data.front()); + ASSERT_EQ( + net::QuicSimpleTestServer::GetHelloStatus(), + test.response_headers[net::QuicSimpleTestServer::GetStatusHeaderName()]); + ASSERT_EQ(net::QuicSimpleTestServer::GetHelloBodyValue(), + test.read_data.front()); ASSERT_EQ(TestBidirectionalStreamCallback::ON_SUCCEEDED, test.response_step); bidirectional_stream_destroy(test.stream); } @@ -540,7 +589,7 @@ bool MaybeCancel(bidirectional_stream* stream, ResponseStep step) override { if (step == ResponseStep::ON_READ_COMPLETED) { // Shut down the server dispatcher, and the stream should error out. - ShutdownQuicTestServerDispatcher(); + net::QuicSimpleTestServer::ShutdownDispatcherForTesting(); } return TestBidirectionalStreamCallback::MaybeCancel(stream, step); } @@ -554,8 +603,8 @@ DCHECK(test.stream); bidirectional_stream_delay_request_headers_until_flush(test.stream, GetParam()); - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, false); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, false); test.BlockForDone(); ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); ASSERT_TRUE(test.net_error == net::ERR_QUIC_PROTOCOL_ERROR || @@ -583,7 +632,7 @@ bool MaybeCancel(bidirectional_stream* stream, ResponseStep step) override { if (step == ResponseStep::ON_STREAM_READY) { // Shut down the server dispatcher, and the stream should error out. - ShutdownQuicTestServerDispatcher(); + net::QuicSimpleTestServer::ShutdownDispatcherForTesting(); } return TestBidirectionalStreamCallback::MaybeCancel(stream, step); } @@ -595,8 +644,8 @@ DCHECK(test.stream); bidirectional_stream_delay_request_headers_until_flush(test.stream, GetParam()); - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, false); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, false); test.BlockForDone(); ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); ASSERT_TRUE(test.net_error == net::ERR_QUIC_PROTOCOL_ERROR || @@ -612,7 +661,7 @@ bool MaybeCancel(bidirectional_stream* stream, ResponseStep step) override { if (step == ResponseStep::ON_WRITE_COMPLETED) { // Shut down the server dispatcher, and the stream should error out. - ShutdownQuicTestServerDispatcher(); + net::QuicSimpleTestServer::ShutdownDispatcherForTesting(); } return TestBidirectionalStreamCallback::MaybeCancel(stream, step); } @@ -626,8 +675,8 @@ DCHECK(test.stream); bidirectional_stream_delay_request_headers_until_flush(test.stream, GetParam()); - bidirectional_stream_start(test.stream, kTestServerUrl, 0, - "POST", &kTestHeadersArray, false); + bidirectional_stream_start(test.stream, test_hello_url(), 0, "POST", + &kTestHeadersArray, false); test.BlockForDone(); ASSERT_EQ(TestBidirectionalStreamCallback::ON_FAILED, test.response_step); ASSERT_TRUE(test.net_error == net::ERR_QUIC_PROTOCOL_ERROR ||
diff --git a/components/grpc_support/test/BUILD.gn b/components/grpc_support/test/BUILD.gn index 6f3b7f0d..d0b39f6 100644 --- a/components/grpc_support/test/BUILD.gn +++ b/components/grpc_support/test/BUILD.gn
@@ -5,7 +5,6 @@ ] deps = [ - ":quic_test_server", "//base", "//components/grpc_support", "//components/grpc_support:bidirectional_stream_unittest", @@ -14,21 +13,6 @@ ] } -source_set("quic_test_server") { - testonly = true - sources = [ - "quic_test_server.cc", - "quic_test_server.h", - ] - - deps = [ - "//base", - "//net", - "//net:simple_quic_tools", - "//net:test_support", - ] -} - source_set("get_stream_engine_header") { testonly = true sources = [
diff --git a/components/grpc_support/test/get_stream_engine.cc b/components/grpc_support/test/get_stream_engine.cc index 02c4d1e7..dd9d851 100644 --- a/components/grpc_support/test/get_stream_engine.cc +++ b/components/grpc_support/test/get_stream_engine.cc
@@ -3,6 +3,9 @@ // found in the LICENSE file. #include <memory> +#include <utility> + +#include "components/grpc_support/test/get_stream_engine.h" #include "base/lazy_instance.h" #include "base/macros.h" @@ -13,12 +16,12 @@ #include "base/strings/stringprintf.h" #include "base/threading/thread.h" #include "components/grpc_support/include/bidirectional_stream_c.h" -#include "components/grpc_support/test/quic_test_server.h" #include "net/base/host_port_pair.h" #include "net/cert/mock_cert_verifier.h" #include "net/dns/mapped_host_resolver.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_server_properties_impl.h" +#include "net/test/quic_simple_test_server.h" #include "net/url_request/url_request_test_util.h" namespace grpc_support { @@ -53,7 +56,8 @@ params->enable_quic = true; params->enable_http2 = true; net::AlternativeService alternative_service(net::kProtoQUIC, "", 443); - url::SchemeHostPort quic_hint_server("https", kTestServerHost, 443); + url::SchemeHostPort quic_hint_server( + "https", net::QuicSimpleTestServer::GetHost(), 443); server_properties_->SetQuicAlternativeService( quic_hint_server, alternative_service, base::Time::Max(), net::QuicTransportVersionVector());
diff --git a/components/grpc_support/test/quic_test_server.h b/components/grpc_support/test/quic_test_server.h deleted file mode 100644 index 6bc25da0..0000000 --- a/components/grpc_support/test/quic_test_server.h +++ /dev/null
@@ -1,47 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_GRPC_SUPPORT_TEST_QUIC_TEST_SERVER_H_ -#define COMPONENTS_GRPC_SUPPORT_TEST_QUIC_TEST_SERVER_H_ - -#include <string> - -namespace grpc_support { - -bool StartQuicTestServer(); - -void ShutdownQuicTestServer(); - -// Shuts down the server dispatcher, which results in sending ConnectionClose -// frames to all connected clients. -void ShutdownQuicTestServerDispatcher(); - -int GetQuicTestServerPort(); - -extern const char kTestServerDomain[]; -extern const char kTestServerHost[]; -extern const char kTestServerUrl[]; - -extern const char kStatusHeader[]; - -extern const char kHelloPath[]; -extern const char kHelloBodyValue[]; -extern const char kHelloStatus[]; - -extern const char kHelloHeaderName[]; -extern const char kHelloHeaderValue[]; - -extern const char kHelloTrailerName[]; -extern const char kHelloTrailerValue[]; - -// Simple Url returns response without HTTP/2 trailers. -extern const char kTestServerSimpleUrl[]; -extern const char kSimpleBodyValue[]; -extern const char kSimpleStatus[]; -extern const char kSimpleHeaderName[]; -extern const char kSimpleHeaderValue[]; - -} // namespace grpc_support - -#endif // COMPONENTS_GRPC_SUPPORT_TEST_QUIC_TEST_SERVER_H_
diff --git a/components/nacl/broker/BUILD.gn b/components/nacl/broker/BUILD.gn index 0e9b9d9..07ffe2a 100644 --- a/components/nacl/broker/BUILD.gn +++ b/components/nacl/broker/BUILD.gn
@@ -49,6 +49,13 @@ "//content/public/common/sandbox_init.h", "//content/public/common/sandboxed_process_launcher_delegate.h", ] + + deps = [ + # sandboxed_process_launcher_delegate.h includes headers generated from + # //content/public/common:zygote_buildflags, so this target needs to have a + # dep on it as well. + "//content/public/common:zygote_buildflags", + ] } if (current_cpu == "x86") { @@ -144,7 +151,7 @@ deps = [ "//base", "//content/public/common:static_switches", - "//content/public/common:zygote_features", + "//content/public/common:zygote_buildflags", "//sandbox", "//services/service_manager/sandbox", ]
diff --git a/components/nacl/browser/BUILD.gn b/components/nacl/browser/BUILD.gn index 5a1b541..467443a 100644 --- a/components/nacl/browser/BUILD.gn +++ b/components/nacl/browser/BUILD.gn
@@ -39,7 +39,7 @@ "//components/url_formatter", "//content/public/browser", "//content/public/common", - "//content/public/common:zygote_features", + "//content/public/common:zygote_buildflags", "//mojo/edk/system", "//native_client/src/trusted/service_runtime:sel_main_chrome", "//net",
diff --git a/components/nacl/browser/nacl_process_host.cc b/components/nacl/browser/nacl_process_host.cc index b69582b..47524845 100644 --- a/components/nacl/browser/nacl_process_host.cc +++ b/components/nacl/browser/nacl_process_host.cc
@@ -54,7 +54,7 @@ #include "content/public/common/mojo_channel_switches.h" #include "content/public/common/process_type.h" #include "content/public/common/sandboxed_process_launcher_delegate.h" -#include "content/public/common/zygote_features.h" +#include "content/public/common/zygote_buildflags.h" #include "ipc/ipc_channel.h" #include "mojo/edk/embedder/embedder.h" #include "net/socket/socket_descriptor.h"
diff --git a/components/ntp_snippets/remote/remote_suggestions_status_service_impl.cc b/components/ntp_snippets/remote/remote_suggestions_status_service_impl.cc index 80fb6ee3..fa2af3d 100644 --- a/components/ntp_snippets/remote/remote_suggestions_status_service_impl.cc +++ b/components/ntp_snippets/remote/remote_suggestions_status_service_impl.cc
@@ -6,6 +6,7 @@ #include <string> +#include "base/feature_list.h" #include "components/ntp_snippets/content_suggestions_metrics.h" #include "components/ntp_snippets/features.h" #include "components/ntp_snippets/pref_names.h" @@ -111,7 +112,9 @@ return true; } - if (!list_visible_during_session_) { + if (base::FeatureList::IsEnabled( + ntp_snippets::kArticleSuggestionsExpandableHeader) && + !list_visible_during_session_) { DVLOG(1) << "[GetStatusFromDeps] Disabled because articles list hidden."; return true; }
diff --git a/components/ntp_snippets/remote/remote_suggestions_status_service_impl_unittest.cc b/components/ntp_snippets/remote/remote_suggestions_status_service_impl_unittest.cc index 9294376..829b2c0 100644 --- a/components/ntp_snippets/remote/remote_suggestions_status_service_impl_unittest.cc +++ b/components/ntp_snippets/remote/remote_suggestions_status_service_impl_unittest.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "components/ntp_snippets/features.h" #include "components/ntp_snippets/ntp_snippets_constants.h" @@ -40,6 +41,15 @@ // is enabled. std::unique_ptr<RemoteSuggestionsStatusServiceImpl> MakeService( bool list_hiding_enabled) { + // Enabling/disabling the feature. + if (list_hiding_enabled) { + feature_list_.InitAndEnableFeature( + ntp_snippets::kArticleSuggestionsExpandableHeader); + } else { + feature_list_.InitAndDisableFeature( + ntp_snippets::kArticleSuggestionsExpandableHeader); + } + auto service = std::make_unique<RemoteSuggestionsStatusServiceImpl>( false, utils_.pref_service(), list_hiding_enabled ? std::string() : kTestPrefName); @@ -57,6 +67,7 @@ last_status_ = new_status; } + base::test::ScopedFeatureList feature_list_; RemoteSuggestionsStatus last_status_; test::RemoteSuggestionsTestUtils utils_; variations::testing::VariationParamsManager params_manager_; @@ -165,4 +176,17 @@ EXPECT_EQ(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN, last_status()); } +TEST_F(RemoteSuggestionsStatusServiceImplTest, + DisablingHidingFeatureWhenFolder) { + utils_.pref_service()->SetBoolean(prefs::kArticlesListVisible, false); + auto service = MakeService(/*list_hiding_enabled="*/ false); + + // The state should be enabled when hiding is disabled. + EXPECT_EQ(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_OUT, last_status()); + + // Signin should cause a state change. + service->OnSignInStateChanged(/*has_signed_in=*/true); + EXPECT_EQ(RemoteSuggestionsStatus::ENABLED_AND_SIGNED_IN, last_status()); +} + } // namespace ntp_snippets
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc index 17194ee7..a215665 100644 --- a/components/password_manager/core/browser/password_form_manager.cc +++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -337,14 +337,13 @@ if (CalculateFormSignature(form.form_data) == observed_form_signature_) result |= RESULT_SIGNATURE_MATCH; - if (!form.form_data.name.empty() && - form.form_data.name == observed_form_.form_data.name) + if (form.form_data.name == observed_form_.form_data.name) result |= RESULT_FORM_NAME_MATCH; // Note: although saved password forms might actually have an empty action // URL if they were imported (see bug 1107719), the |form| we see here comes // never from the password store, and should have an exactly matching action. - if (!form.action.is_empty() && form.action == observed_form_.action) + if (form.action == observed_form_.action) result |= RESULT_ACTION_MATCH; return result;
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc index 011dfad..6a4e6d2c 100644 --- a/components/password_manager/core/browser/password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -1893,24 +1893,18 @@ PasswordFormManager::RESULT_SIGNATURE_MATCH); } -TEST_F(PasswordFormManagerTest, NoMatchForEmptyNames) { - // If two forms have no name, it's not evidence for a match. +TEST_F(PasswordFormManagerTest, FormWithEmptyActionAndNameMatchesItself) { + observed_form()->form_data.name.clear(); + observed_form()->action = GURL::EmptyGURL(); + PasswordFormManager form_manager( + password_manager(), client(), client()->driver(), *observed_form(), + std::make_unique<NiceMock<MockFormSaver>>(), fake_form_fetcher()); + form_manager.Init(nullptr); + // Any form should match itself regardless of missing properties. Otherwise, + // a PasswordFormManager instance is created for the same form multiple times. PasswordForm other_form(*observed_form()); - const_cast<PasswordForm&>(form_manager()->observed_form()) - .form_data.name.clear(); - other_form.form_data.name.clear(); - EXPECT_EQ(0, form_manager()->DoesManage(other_form, nullptr) & - PasswordFormManager::RESULT_FORM_NAME_MATCH); -} - -TEST_F(PasswordFormManagerTest, NoMatchForEmtpyActions) { - // If two forms have no actions, it's not evidence for a match. - PasswordForm other_form(*observed_form()); - const_cast<PasswordForm&>(form_manager()->observed_form()).form_data.action = - GURL::EmptyGURL(); - other_form.action = GURL::EmptyGURL(); - EXPECT_EQ(0, form_manager()->DoesManage(other_form, nullptr) & - PasswordFormManager::RESULT_ACTION_MATCH); + EXPECT_EQ(PasswordFormManager::RESULT_COMPLETE_MATCH, + form_manager.DoesManage(other_form, nullptr)); } // Test that if multiple credentials with the same username are stored, and the
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 5d498c0c..593519f2 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -2257,6 +2257,8 @@ }; const std::vector<PasswordForm> observed = {PasswordForm()}; + // PasswordStore requested only once for the same form. + EXPECT_CALL(*store_, GetLogins(_, _)); for (const auto& test_case : kCases) { SCOPED_TRACE(testing::Message("index of test_case = ") @@ -2264,7 +2266,6 @@ EXPECT_CALL(client_, GetMainFrameCertStatus()) .WillRepeatedly(Return(test_case.cert_status)); base::HistogramTester histogram_tester; - EXPECT_CALL(*store_, GetLogins(_, _)); manager()->OnPasswordFormsParsed(&driver_, observed); histogram_tester.ExpectUniqueSample( "PasswordManager.CertificateErrorsWhileSeeingForms",
diff --git a/components/patch_service/public/cpp/patch.cc b/components/patch_service/public/cpp/patch.cc index 14d3b05..837fb25 100644 --- a/components/patch_service/public/cpp/patch.cc +++ b/components/patch_service/public/cpp/patch.cc
@@ -49,6 +49,7 @@ }; void PatchDone(scoped_refptr<PatchParams> params, int result) { + params->file_patcher()->reset(); PatchCallback cb = params->TakeCallback(); if (!cb.is_null()) std::move(cb).Run(result);
diff --git a/components/safe_browsing/common/BUILD.gn b/components/safe_browsing/common/BUILD.gn index 7e01e18..b003b51 100644 --- a/components/safe_browsing/common/BUILD.gn +++ b/components/safe_browsing/common/BUILD.gn
@@ -52,6 +52,7 @@ "//base:base", "//base/test:test_support", "//components/prefs:test_support", + "//content/test:test_support", "//testing/gtest", "//url:url", ]
diff --git a/components/safe_browsing/common/DEPS b/components/safe_browsing/common/DEPS index 60d09aae..0e7f7e1 100644 --- a/components/safe_browsing/common/DEPS +++ b/components/safe_browsing/common/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+components/pref_registry", "+components/prefs", + "+content/public/test", "+crypto/sha2.h", "+ipc", "+url"
diff --git a/components/safe_browsing/common/safe_browsing_prefs.cc b/components/safe_browsing/common/safe_browsing_prefs.cc index 3fcc848..0ca4bb2 100644 --- a/components/safe_browsing/common/safe_browsing_prefs.cc +++ b/components/safe_browsing/common/safe_browsing_prefs.cc
@@ -526,6 +526,8 @@ bool IsURLWhitelistedByPolicy(const GURL& url, StringListPrefMember* pref_member) { DCHECK_CURRENTLY_ON(content::BrowserThread::IO); + if (!pref_member) + return false; std::vector<std::string> sb_whitelist_domains = pref_member->GetValue(); return std::find_if(sb_whitelist_domains.begin(), sb_whitelist_domains.end(), [&url](const std::string& domain) {
diff --git a/components/safe_browsing/common/safe_browsing_prefs_unittest.cc b/components/safe_browsing/common/safe_browsing_prefs_unittest.cc index 34882c6..08ccaa9 100644 --- a/components/safe_browsing/common/safe_browsing_prefs_unittest.cc +++ b/components/safe_browsing/common/safe_browsing_prefs_unittest.cc
@@ -12,6 +12,7 @@ #include "components/prefs/pref_registry_simple.h" #include "components/prefs/testing_pref_service.h" #include "components/safe_browsing/common/safe_browsing_prefs.h" +#include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -35,6 +36,8 @@ prefs_.registry()->RegisterListPref(prefs::kPasswordProtectionLoginURLs); prefs_.registry()->RegisterBooleanPref( prefs::kSafeBrowsingExtendedReportingOptInAllowed, true); + prefs_.registry()->RegisterListPref(prefs::kSafeBrowsingWhitelistDomains); + ResetExperiments(/*can_show_scout=*/false); } @@ -112,6 +115,7 @@ private: std::unique_ptr<base::test::ScopedFeatureList> feature_list_; + content::TestBrowserThreadBundle thread_bundle_; }; // This test ensures that we correctly select between SBER and Scout as the @@ -422,4 +426,23 @@ EXPECT_TRUE(IsExtendedReportingOptInAllowed(prefs_)); } +TEST_F(SafeBrowsingPrefsTest, VerifyIsURLWhitelistedByPolicy) { + GURL target_url("https://www.foo.com"); + // When PrefMember is null, URL is not whitelisted. + EXPECT_FALSE(IsURLWhitelistedByPolicy(target_url, nullptr)); + + EXPECT_FALSE(prefs_.HasPrefPath(prefs::kSafeBrowsingWhitelistDomains)); + base::ListValue whitelisted_domains; + whitelisted_domains.AppendString("foo.com"); + prefs_.Set(prefs::kSafeBrowsingWhitelistDomains, whitelisted_domains); + StringListPrefMember string_list_pref; + string_list_pref.Init(prefs::kSafeBrowsingWhitelistDomains, &prefs_); + EXPECT_TRUE(IsURLWhitelistedByPolicy(target_url, prefs_)); + EXPECT_TRUE(IsURLWhitelistedByPolicy(target_url, &string_list_pref)); + + GURL not_whitelisted_url("https://www.bar.com"); + EXPECT_FALSE(IsURLWhitelistedByPolicy(not_whitelisted_url, prefs_)); + EXPECT_FALSE( + IsURLWhitelistedByPolicy(not_whitelisted_url, &string_list_pref)); +} } // namespace safe_browsing
diff --git a/components/sync/driver/about_sync_util.cc b/components/sync/driver/about_sync_util.cc index 18d80bd..f848f68 100644 --- a/components/sync/driver/about_sync_util.cc +++ b/components/sync/driver/about_sync_util.cc
@@ -527,10 +527,8 @@ } if (snapshot.is_initialized()) { - if (snapshot.legacy_updates_source() != - sync_pb::GetUpdatesCallerInfo::UNKNOWN) { - session_source.SetValue( - ProtoEnumToString(snapshot.legacy_updates_source())); + if (snapshot.get_updates_origin() != sync_pb::SyncEnums::UNKNOWN_ORIGIN) { + session_source.SetValue(ProtoEnumToString(snapshot.get_updates_origin())); } get_key_result.SetValue(GetSyncerErrorString( snapshot.model_neutral_state().last_get_key_result));
diff --git a/components/sync/engine/cycle/sync_cycle_snapshot.cc b/components/sync/engine/cycle/sync_cycle_snapshot.cc index fab6c65..20823b51 100644 --- a/components/sync/engine/cycle/sync_cycle_snapshot.cc +++ b/components/sync/engine/cycle/sync_cycle_snapshot.cc
@@ -36,7 +36,7 @@ base::Time poll_finish_time, const std::vector<int>& num_entries_by_type, const std::vector<int>& num_to_delete_entries_by_type, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource legacy_updates_source) + sync_pb::SyncEnums::GetUpdatesOrigin get_updates_origin) : model_neutral_state_(model_neutral_state), download_progress_markers_(download_progress_markers), is_silenced_(is_silenced), @@ -49,7 +49,7 @@ poll_finish_time_(poll_finish_time), num_entries_by_type_(num_entries_by_type), num_to_delete_entries_by_type_(num_to_delete_entries_by_type), - legacy_updates_source_(legacy_updates_source), + get_updates_origin_(get_updates_origin), is_initialized_(true) {} SyncCycleSnapshot::SyncCycleSnapshot(const SyncCycleSnapshot& other) = default; @@ -82,7 +82,7 @@ value->SetInteger("numHierarchyConflicts", num_hierarchy_conflicts_); value->SetInteger("numServerConflicts", num_server_conflicts_); value->SetInteger("numEntries", num_entries_); - value->SetString("legacySource", ProtoEnumToString(legacy_updates_source_)); + value->SetString("getUpdatesOrigin", ProtoEnumToString(get_updates_origin_)); value->SetBoolean("notificationsEnabled", notifications_enabled_); std::unique_ptr<base::DictionaryValue> counter_entries( @@ -157,9 +157,9 @@ return num_to_delete_entries_by_type_; } -sync_pb::GetUpdatesCallerInfo::GetUpdatesSource -SyncCycleSnapshot::legacy_updates_source() const { - return legacy_updates_source_; +sync_pb::SyncEnums::GetUpdatesOrigin SyncCycleSnapshot::get_updates_origin() + const { + return get_updates_origin_; } } // namespace syncer
diff --git a/components/sync/engine/cycle/sync_cycle_snapshot.h b/components/sync/engine/cycle/sync_cycle_snapshot.h index 1897af2..62aee7e 100644 --- a/components/sync/engine/cycle/sync_cycle_snapshot.h +++ b/components/sync/engine/cycle/sync_cycle_snapshot.h
@@ -30,20 +30,19 @@ class SyncCycleSnapshot { public: SyncCycleSnapshot(); - SyncCycleSnapshot( - const ModelNeutralState& model_neutral_state, - const ProgressMarkerMap& download_progress_markers, - bool is_silenced, - int num_encryption_conflicts, - int num_hierarchy_conflicts, - int num_server_conflicts, - bool notifications_enabled, - size_t num_entries, - base::Time sync_start_time, - base::Time poll_finish_time, - const std::vector<int>& num_entries_by_type, - const std::vector<int>& num_to_delete_entries_by_type, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource legacy_updates_source); + SyncCycleSnapshot(const ModelNeutralState& model_neutral_state, + const ProgressMarkerMap& download_progress_markers, + bool is_silenced, + int num_encryption_conflicts, + int num_hierarchy_conflicts, + int num_server_conflicts, + bool notifications_enabled, + size_t num_entries, + base::Time sync_start_time, + base::Time poll_finish_time, + const std::vector<int>& num_entries_by_type, + const std::vector<int>& num_to_delete_entries_by_type, + sync_pb::SyncEnums::GetUpdatesOrigin get_updates_origin); SyncCycleSnapshot(const SyncCycleSnapshot& other); ~SyncCycleSnapshot(); @@ -63,7 +62,7 @@ base::Time poll_finish_time() const; const std::vector<int>& num_entries_by_type() const; const std::vector<int>& num_to_delete_entries_by_type() const; - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource legacy_updates_source() const; + sync_pb::SyncEnums::GetUpdatesOrigin get_updates_origin() const; // Set iff this snapshot was not built using the default constructor. bool is_initialized() const; @@ -83,10 +82,7 @@ std::vector<int> num_entries_by_type_; std::vector<int> num_to_delete_entries_by_type_; - // This enum value used to be an important part of the sync protocol, but is - // now deprecated. We continue to use it in the snapshot because there is - // still some value in displaying it on the about:sync page. - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource legacy_updates_source_; + sync_pb::SyncEnums::GetUpdatesOrigin get_updates_origin_; bool is_initialized_; };
diff --git a/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc b/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc index 2e7c2b9..ca0f243 100644 --- a/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc +++ b/components/sync/engine/cycle/sync_cycle_snapshot_unittest.cc
@@ -47,7 +47,7 @@ 0, base::Time::Now(), base::Time::Now(), std::vector<int>(MODEL_TYPE_COUNT, 0), std::vector<int>(MODEL_TYPE_COUNT, 0), - sync_pb::GetUpdatesCallerInfo::UNKNOWN); + sync_pb::SyncEnums::UNKNOWN_ORIGIN); std::unique_ptr<base::DictionaryValue> value(snapshot.ToValue()); EXPECT_EQ(16u, value->size()); ExpectDictIntegerValue(model_neutral.num_successful_commits, *value,
diff --git a/components/sync/engine/sync_manager_factory_for_profile_sync_test.cc b/components/sync/engine/sync_manager_factory_for_profile_sync_test.cc index 1911dfb..949d3c02 100644 --- a/components/sync/engine/sync_manager_factory_for_profile_sync_test.cc +++ b/components/sync/engine/sync_manager_factory_for_profile_sync_test.cc
@@ -9,8 +9,8 @@ namespace syncer { SyncManagerFactoryForProfileSyncTest::SyncManagerFactoryForProfileSyncTest( - base::Closure init_callback) - : SyncManagerFactory(), init_callback_(init_callback) {} + base::OnceClosure init_callback) + : SyncManagerFactory(), init_callback_(std::move(init_callback)) {} SyncManagerFactoryForProfileSyncTest::~SyncManagerFactoryForProfileSyncTest() {} @@ -18,7 +18,7 @@ SyncManagerFactoryForProfileSyncTest::CreateSyncManager( const std::string& name) { return std::unique_ptr<SyncManager>( - new SyncManagerForProfileSyncTest(name, init_callback_)); + new SyncManagerForProfileSyncTest(name, std::move(init_callback_))); } } // namespace syncer
diff --git a/components/sync/engine/sync_manager_factory_for_profile_sync_test.h b/components/sync/engine/sync_manager_factory_for_profile_sync_test.h index 2956cb3..c3eee0a 100644 --- a/components/sync/engine/sync_manager_factory_for_profile_sync_test.h +++ b/components/sync/engine/sync_manager_factory_for_profile_sync_test.h
@@ -15,13 +15,14 @@ class SyncManagerFactoryForProfileSyncTest : public SyncManagerFactory { public: - explicit SyncManagerFactoryForProfileSyncTest(base::Closure init_callback); + explicit SyncManagerFactoryForProfileSyncTest( + base::OnceClosure init_callback); ~SyncManagerFactoryForProfileSyncTest() override; std::unique_ptr<SyncManager> CreateSyncManager( const std::string& name) override; private: - base::Closure init_callback_; + base::OnceClosure init_callback_; }; } // namespace syncer
diff --git a/components/sync/engine_impl/conflict_resolver.cc b/components/sync/engine_impl/conflict_resolver.cc index 53236cf..fabcbcc 100644 --- a/components/sync/engine_impl/conflict_resolver.cc +++ b/components/sync/engine_impl/conflict_resolver.cc
@@ -4,7 +4,6 @@ #include "components/sync/engine_impl/conflict_resolver.h" -#include <list> #include <string> #include "base/metrics/histogram_macros.h" @@ -17,7 +16,6 @@ #include "components/sync/syncable/mutable_entry.h" #include "components/sync/syncable/syncable_write_transaction.h" -using std::list; using std::set; namespace syncer { @@ -27,39 +25,6 @@ using syncable::Id; using syncable::MutableEntry; -namespace { - -// Returns true iff the set of attachment ids contained in attachment_metadata -// matches the set of ids contained in server_attachment_metadata. -bool AttachmentMetadataMatches(const MutableEntry& entity) { - const sync_pb::AttachmentMetadata& local = entity.GetAttachmentMetadata(); - const sync_pb::AttachmentMetadata& server = - entity.GetServerAttachmentMetadata(); - if (local.record_size() != server.record_size()) { - return false; - } - - // The order of records in local and server may be different so use a std::set - // to determine if they are equivalent. - std::set<std::string> local_ids; - for (int i = 0; i < local.record_size(); ++i) { - const sync_pb::AttachmentMetadataRecord& record = local.record(i); - DCHECK(record.is_on_server()); - local_ids.insert(record.id().SerializeAsString()); - } - for (int i = 0; i < server.record_size(); ++i) { - const sync_pb::AttachmentMetadataRecord& record = server.record(i); - DCHECK(record.is_on_server()); - if (local_ids.find(record.id().SerializeAsString()) == local_ids.end()) { - return false; - } - } - - return true; -} - -} // namespace - ConflictResolver::ConflictResolver() {} ConflictResolver::~ConflictResolver() {} @@ -181,9 +146,8 @@ base_server_specifics_match = true; } - bool attachment_metadata_matches = AttachmentMetadataMatches(entry); if (!entry_deleted && name_matches && parent_matches && specifics_match && - position_matches && attachment_metadata_matches) { + position_matches) { DVLOG(1) << "Resolving simple conflict, everything matches, ignoring " << "changes for: " << entry; conflict_util::IgnoreConflict(&entry);
diff --git a/components/sync/engine_impl/cycle/nudge_tracker.cc b/components/sync/engine_impl/cycle/nudge_tracker.cc index 40d26e5..8b327e6 100644 --- a/components/sync/engine_impl/cycle/nudge_tracker.cc +++ b/components/sync/engine_impl/cycle/nudge_tracker.cc
@@ -299,53 +299,22 @@ type_trackers_.find(type)->second->SetLegacyNotificationHint(progress); } -sync_pb::GetUpdatesCallerInfo::GetUpdatesSource NudgeTracker::GetLegacySource() - const { - // There's an order to these sources: NOTIFICATION, DATATYPE_REFRESH, LOCAL, - // RETRY. The server makes optimization decisions based on this field, so - // it's important to get this right. Setting it wrong could lead to missed - // updates. - // - // This complexity is part of the reason why we're deprecating 'source' in - // favor of 'origin'. - bool has_invalidation_pending = false; - bool has_refresh_request_pending = false; - bool has_commit_pending = false; - bool is_initial_sync_required = false; - bool has_retry = IsRetryRequired(); - - for (TypeTrackerMap::const_iterator it = type_trackers_.begin(); - it != type_trackers_.end(); ++it) { - const DataTypeTracker& tracker = *it->second; - if (!tracker.IsBlocked() && tracker.HasPendingInvalidation()) { - has_invalidation_pending = true; - } - if (!tracker.IsBlocked() && tracker.HasRefreshRequestPending()) { - has_refresh_request_pending = true; - } - if (!tracker.IsBlocked() && tracker.HasLocalChangePending()) { - has_commit_pending = true; - } - if (!tracker.IsBlocked() && tracker.IsInitialSyncRequired()) { - is_initial_sync_required = true; +sync_pb::SyncEnums::GetUpdatesOrigin NudgeTracker::GetOrigin() const { + for (const auto& type_and_tracker : type_trackers_) { + const DataTypeTracker& tracker = *type_and_tracker.second; + if (!tracker.IsBlocked() && + (tracker.HasPendingInvalidation() || + tracker.HasRefreshRequestPending() || + tracker.HasLocalChangePending() || tracker.IsInitialSyncRequired())) { + return sync_pb::SyncEnums::GU_TRIGGER; } } - if (has_invalidation_pending) { - return sync_pb::GetUpdatesCallerInfo::NOTIFICATION; - } else if (has_refresh_request_pending) { - return sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH; - } else if (is_initial_sync_required) { - // Not quite accurate, but good enough for our purposes. This setting of - // SOURCE is just a backward-compatibility hack anyway. - return sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH; - } else if (has_commit_pending) { - return sync_pb::GetUpdatesCallerInfo::LOCAL; - } else if (has_retry) { - return sync_pb::GetUpdatesCallerInfo::RETRY; - } else { - return sync_pb::GetUpdatesCallerInfo::UNKNOWN; + if (IsRetryRequired()) { + return sync_pb::SyncEnums::RETRY; } + + return sync_pb::SyncEnums::UNKNOWN_ORIGIN; } void NudgeTracker::FillProtoMessage(ModelType type,
diff --git a/components/sync/engine_impl/cycle/nudge_tracker.h b/components/sync/engine_impl/cycle/nudge_tracker.h index f63923e..57fd37c 100644 --- a/components/sync/engine_impl/cycle/nudge_tracker.h +++ b/components/sync/engine_impl/cycle/nudge_tracker.h
@@ -117,15 +117,8 @@ // Returns the set of types that have pending refresh requests. ModelTypeSet GetRefreshRequestedTypes() const; - // Returns the 'source' of the GetUpdate request. - // - // This flag is deprecated, but still used by the server. There can be more - // than one reason to perform a particular sync cycle. The GetUpdatesTrigger - // message will contain more reliable information about the reasons for - // performing a sync. - // - // See the implementation for important information about the coalesce logic. - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource GetLegacySource() const; + // Returns the 'origin' of the GetUpdate request. + sync_pb::SyncEnums::GetUpdatesOrigin GetOrigin() const; // Fills a GetUpdatesTrigger message for the next GetUpdates request. This is // used by the DownloadUpdatesCommand to dump lots of useful per-type state
diff --git a/components/sync/engine_impl/cycle/nudge_tracker_unittest.cc b/components/sync/engine_impl/cycle/nudge_tracker_unittest.cc index f3dbf35..cab1d19 100644 --- a/components/sync/engine_impl/cycle/nudge_tracker_unittest.cc +++ b/components/sync/engine_impl/cycle/nudge_tracker_unittest.cc
@@ -97,76 +97,43 @@ // Now we're at the normal, "idle" state. EXPECT_FALSE(nudge_tracker_.IsSyncRequired()); EXPECT_FALSE(nudge_tracker_.IsGetUpdatesRequired()); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN, - nudge_tracker_.GetLegacySource()); sync_pb::GetUpdateTriggers gu_trigger; nudge_tracker_.FillProtoMessage(BOOKMARKS, &gu_trigger); - - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::UNKNOWN, - nudge_tracker_.GetLegacySource()); } // Verify that nudges override each other based on a priority order. -// RETRY < LOCAL < DATATYPE_REFRESH < NOTIFICATION +// RETRY < all variants of GU_TRIGGER TEST_F(NudgeTrackerTest, SourcePriorities) { // Start with a retry request. const base::TimeTicks t0 = base::TimeTicks::FromInternalValue(1234); const base::TimeTicks t1 = t0 + base::TimeDelta::FromSeconds(10); nudge_tracker_.SetNextRetryTime(t0); nudge_tracker_.SetSyncCycleStartTime(t1); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RETRY, - nudge_tracker_.GetLegacySource()); + EXPECT_EQ(sync_pb::SyncEnums::RETRY, nudge_tracker_.GetOrigin()); // Track a local nudge. nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::LOCAL, - nudge_tracker_.GetLegacySource()); + EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, nudge_tracker_.GetOrigin()); // A refresh request will override it. nudge_tracker_.RecordLocalRefreshRequest(ModelTypeSet(TYPED_URLS)); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH, - nudge_tracker_.GetLegacySource()); + EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, nudge_tracker_.GetOrigin()); // Another local nudge will not be enough to change it. nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH, - nudge_tracker_.GetLegacySource()); + EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, nudge_tracker_.GetOrigin()); // An invalidation will override the refresh request source. nudge_tracker_.RecordRemoteInvalidation(PREFERENCES, BuildInvalidation(1, "hint")); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, - nudge_tracker_.GetLegacySource()); + EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, nudge_tracker_.GetOrigin()); // Neither local nudges nor refresh requests will override it. nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, - nudge_tracker_.GetLegacySource()); + EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, nudge_tracker_.GetOrigin()); nudge_tracker_.RecordLocalRefreshRequest(ModelTypeSet(TYPED_URLS)); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, - nudge_tracker_.GetLegacySource()); -} - -TEST_F(NudgeTrackerTest, SourcePriority_InitialSyncRequest) { - nudge_tracker_.RecordInitialSyncRequired(BOOKMARKS); - - // For lack of a better source, we describe an initial sync request as having - // source DATATYPE_REFRESH. - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH, - nudge_tracker_.GetLegacySource()); - - // This should never happen in practice. But, if it did, we'd want the - // initial sync required to keep the source set to DATATYPE_REFRESH. - nudge_tracker_.RecordLocalChange(ModelTypeSet(BOOKMARKS)); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH, - nudge_tracker_.GetLegacySource()); - - // It should be safe to let NOTIFICATIONs override it. - nudge_tracker_.RecordRemoteInvalidation(BOOKMARKS, - BuildInvalidation(1, "hint")); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, - nudge_tracker_.GetLegacySource()); + EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, nudge_tracker_.GetOrigin()); } // Verifies the management of invalidation hints and GU trigger fields.
diff --git a/components/sync/engine_impl/cycle/sync_cycle.cc b/components/sync/engine_impl/cycle/sync_cycle.cc index fd30097..7127f036 100644 --- a/components/sync/engine_impl/cycle/sync_cycle.cc +++ b/components/sync/engine_impl/cycle/sync_cycle.cc
@@ -20,12 +20,11 @@ SyncCycle::~SyncCycle() {} SyncCycleSnapshot SyncCycle::TakeSnapshot() const { - return TakeSnapshotWithSource(sync_pb::GetUpdatesCallerInfo::UNKNOWN); + return TakeSnapshotWithOrigin(sync_pb::SyncEnums::UNKNOWN_ORIGIN); } -SyncCycleSnapshot SyncCycle::TakeSnapshotWithSource( - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource legacy_updates_source) - const { +SyncCycleSnapshot SyncCycle::TakeSnapshotWithOrigin( + sync_pb::SyncEnums::GetUpdatesOrigin get_updates_origin) const { syncable::Directory* dir = context_->directory(); ProgressMarkerMap download_progress_markers; @@ -48,15 +47,15 @@ context_->notifications_enabled(), dir->GetEntriesCount(), status_controller_->sync_start_time(), status_controller_->poll_finish_time(), num_entries_by_type, - num_to_delete_entries_by_type, legacy_updates_source); + num_to_delete_entries_by_type, get_updates_origin); return snapshot; } void SyncCycle::SendSyncCycleEndEventNotification( - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source) { + sync_pb::SyncEnums::GetUpdatesOrigin get_updates_origin) { SyncCycleEvent event(SyncCycleEvent::SYNC_CYCLE_ENDED); - event.snapshot = TakeSnapshotWithSource(source); + event.snapshot = TakeSnapshotWithOrigin(get_updates_origin); DVLOG(1) << "Sending cycle end event with snapshot: " << event.snapshot.ToString();
diff --git a/components/sync/engine_impl/cycle/sync_cycle.h b/components/sync/engine_impl/cycle/sync_cycle.h index 11201dd..b41478d 100644 --- a/components/sync/engine_impl/cycle/sync_cycle.h +++ b/components/sync/engine_impl/cycle/sync_cycle.h
@@ -93,13 +93,12 @@ // Builds a thread-safe and read-only copy of the current cycle state. SyncCycleSnapshot TakeSnapshot() const; - SyncCycleSnapshot TakeSnapshotWithSource( - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource legacy_updates_source) - const; + SyncCycleSnapshot TakeSnapshotWithOrigin( + sync_pb::SyncEnums::GetUpdatesOrigin get_updates_origin) const; // Builds and sends a snapshot to the cycle context's listeners. void SendSyncCycleEndEventNotification( - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source); + sync_pb::SyncEnums::GetUpdatesOrigin get_updates_origin); void SendEventNotification(SyncCycleEvent::EventCause cause); void SendProtocolEvent(const ProtocolEvent& event);
diff --git a/components/sync/engine_impl/cycle/test_util.cc b/components/sync/engine_impl/cycle/test_util.cc index 92947fde3..5c8939b 100644 --- a/components/sync/engine_impl/cycle/test_util.cc +++ b/components/sync/engine_impl/cycle/test_util.cc
@@ -7,29 +7,26 @@ namespace syncer { namespace test_util { -void SimulateGetEncryptionKeyFailed( - ModelTypeSet requsted_types, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, - SyncCycle* cycle) { +void SimulateGetEncryptionKeyFailed(ModelTypeSet requsted_types, + sync_pb::SyncEnums::GetUpdatesOrigin origin, + SyncCycle* cycle) { cycle->mutable_status_controller()->set_last_get_key_result( SERVER_RESPONSE_VALIDATION_FAILED); cycle->mutable_status_controller()->set_last_download_updates_result( SYNCER_OK); } -void SimulateConfigureSuccess( - ModelTypeSet requsted_types, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, - SyncCycle* cycle) { +void SimulateConfigureSuccess(ModelTypeSet requsted_types, + sync_pb::SyncEnums::GetUpdatesOrigin origin, + SyncCycle* cycle) { cycle->mutable_status_controller()->set_last_get_key_result(SYNCER_OK); cycle->mutable_status_controller()->set_last_download_updates_result( SYNCER_OK); } -void SimulateConfigureFailed( - ModelTypeSet requsted_types, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, - SyncCycle* cycle) { +void SimulateConfigureFailed(ModelTypeSet requsted_types, + sync_pb::SyncEnums::GetUpdatesOrigin origin, + SyncCycle* cycle) { cycle->mutable_status_controller()->set_last_get_key_result(SYNCER_OK); cycle->mutable_status_controller()->set_last_download_updates_result( SERVER_RETURN_TRANSIENT_ERROR); @@ -37,7 +34,7 @@ void SimulateConfigureConnectionFailure( ModelTypeSet requsted_types, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, + sync_pb::SyncEnums::GetUpdatesOrigin origin, SyncCycle* cycle) { cycle->mutable_status_controller()->set_last_get_key_result(SYNCER_OK); cycle->mutable_status_controller()->set_last_download_updates_result(
diff --git a/components/sync/engine_impl/cycle/test_util.h b/components/sync/engine_impl/cycle/test_util.h index 77b111d..2f17712b 100644 --- a/components/sync/engine_impl/cycle/test_util.h +++ b/components/sync/engine_impl/cycle/test_util.h
@@ -16,21 +16,18 @@ // Utils to simulate various outcomes of a sync cycle. // Configure sync cycle successes and failures. -void SimulateGetEncryptionKeyFailed( - ModelTypeSet requested_types, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, - SyncCycle* cycle); -void SimulateConfigureSuccess( - ModelTypeSet requested_types, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, - SyncCycle* cycle); -void SimulateConfigureFailed( - ModelTypeSet requested_types, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, - SyncCycle* cycle); +void SimulateGetEncryptionKeyFailed(ModelTypeSet requested_types, + sync_pb::SyncEnums::GetUpdatesOrigin origin, + SyncCycle* cycle); +void SimulateConfigureSuccess(ModelTypeSet requested_types, + sync_pb::SyncEnums::GetUpdatesOrigin origin, + SyncCycle* cycle); +void SimulateConfigureFailed(ModelTypeSet requested_types, + sync_pb::SyncEnums::GetUpdatesOrigin origin, + SyncCycle* cycle); void SimulateConfigureConnectionFailure( ModelTypeSet requested_types, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, + sync_pb::SyncEnums::GetUpdatesOrigin origin, SyncCycle* cycle); // Normal mode sync cycle successes and failures.
diff --git a/components/sync/engine_impl/debug_info_event_listener.cc b/components/sync/engine_impl/debug_info_event_listener.cc index 511e584..820f08b 100644 --- a/components/sync/engine_impl/debug_info_event_listener.cc +++ b/components/sync/engine_impl/debug_info_event_listener.cc
@@ -36,11 +36,16 @@ snapshot.model_neutral_state().num_updates_downloaded_total); sync_completed_event_info->set_num_reflected_updates_downloaded( snapshot.model_neutral_state().num_reflected_updates_downloaded_total); - sync_completed_event_info->mutable_caller_info()->set_source( - snapshot.legacy_updates_source()); + sync_completed_event_info->set_get_updates_origin( + snapshot.get_updates_origin()); sync_completed_event_info->mutable_caller_info()->set_notifications_enabled( snapshot.notifications_enabled()); + // Fill the legacy GetUpdatesSource field. This is not used anymore, but it's + // a required field so we still have to fill it with something. + sync_completed_event_info->mutable_caller_info()->set_source( + sync_pb::GetUpdatesCallerInfo::UNKNOWN); + AddEventToQueue(event_info); }
diff --git a/components/sync/engine_impl/get_commit_ids.cc b/components/sync/engine_impl/get_commit_ids.cc index 1835cf5..f8a9557 100644 --- a/components/sync/engine_impl/get_commit_ids.cc +++ b/components/sync/engine_impl/get_commit_ids.cc
@@ -34,18 +34,6 @@ return false; } -// Return true if this entry has any attachments that haven't yet been uploaded -// to the server. -bool HasAttachmentNotOnServer(const Entry& entry) { - const sync_pb::AttachmentMetadata& metadata = entry.GetAttachmentMetadata(); - for (int i = 0; i < metadata.record_size(); ++i) { - if (!metadata.record(i).is_on_server()) { - return true; - } - } - return false; -} - // An entry may not commit if any are true: // 1. It requires encryption (either the type is encrypted but a passphrase // is missing from the cryptographer, or the entry itself wasn't properly @@ -99,13 +87,6 @@ return false; } - if (HasAttachmentNotOnServer(entry)) { - // This entry is not ready to be sent to the server because it has one or - // more attachments that have not yet been uploaded to the server. The idea - // here is avoid propagating an entry with dangling attachment references. - return false; - } - DVLOG(2) << "Entry is ready for commit: " << entry; return true; } @@ -463,9 +444,7 @@ Entry entry(trans, syncable::GET_BY_HANDLE, handle); // TODO(maniscalco): While we check if entry is ready to be committed, we // also need to check that all of its ancestors (parents, transitive) are - // ready to be committed. Once attachments can prevent an entry from being - // committable, this method must ensure all ancestors are ready for commit - // (crbug.com/356273). + // ready to be committed. if (MayEntryCommit(requested_types, encrypted_types, passphrase_missing, entry)) { if (IsEntryInConflict(entry)) {
diff --git a/components/sync/engine_impl/get_updates_delegate.cc b/components/sync/engine_impl/get_updates_delegate.cc index 2e54b54..c5d493be 100644 --- a/components/sync/engine_impl/get_updates_delegate.cc +++ b/components/sync/engine_impl/get_updates_delegate.cc
@@ -49,17 +49,18 @@ // This function assumes the progress markers have already been populated. void NormalGetUpdatesDelegate::HelpPopulateGuMessage( sync_pb::GetUpdatesMessage* get_updates) const { - // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. + // Fill the legacy GetUpdatesSource field. This is not used anymore, but it's + // a required field so we still have to fill it with something. get_updates->mutable_caller_info()->set_source( - nudge_tracker_.GetLegacySource()); + sync_pb::GetUpdatesCallerInfo::UNKNOWN); - // Set the new and improved version of source, too. + // Set the origin. get_updates->set_get_updates_origin(sync_pb::SyncEnums::GU_TRIGGER); get_updates->set_is_retry(nudge_tracker_.IsRetryRequired()); // Special case: A GU performed for no other reason than retry will have its // origin set to RETRY. - if (nudge_tracker_.GetLegacySource() == sync_pb::GetUpdatesCallerInfo::RETRY) + if (nudge_tracker_.GetOrigin() == sync_pb::SyncEnums::RETRY) get_updates->set_get_updates_origin(sync_pb::SyncEnums::RETRY); // Fill in the notification hints. @@ -93,15 +94,19 @@ } ConfigureGetUpdatesDelegate::ConfigureGetUpdatesDelegate( - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source) - : source_(source) {} + sync_pb::SyncEnums::GetUpdatesOrigin origin) + : origin_(origin) {} ConfigureGetUpdatesDelegate::~ConfigureGetUpdatesDelegate() {} void ConfigureGetUpdatesDelegate::HelpPopulateGuMessage( sync_pb::GetUpdatesMessage* get_updates) const { - get_updates->mutable_caller_info()->set_source(source_); - get_updates->set_get_updates_origin(ConvertConfigureSourceToOrigin(source_)); + // Fill the legacy GetUpdatesSource field. This is not used anymore, but it's + // a required field so we still have to fill it with something. + get_updates->mutable_caller_info()->set_source( + sync_pb::GetUpdatesCallerInfo::UNKNOWN); + + get_updates->set_get_updates_origin(origin_); } void ConfigureGetUpdatesDelegate::ApplyUpdates( @@ -115,29 +120,8 @@ ConfigureGetUpdatesDelegate::GetNetworkRequestEvent( base::Time timestamp, const sync_pb::ClientToServerMessage& request) const { - return std::unique_ptr<ProtocolEvent>(new ConfigureGetUpdatesRequestEvent( - timestamp, ConvertConfigureSourceToOrigin(source_), request)); -} - -sync_pb::SyncEnums::GetUpdatesOrigin -ConfigureGetUpdatesDelegate::ConvertConfigureSourceToOrigin( - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source) { - switch (source) { - // Configurations: - case sync_pb::GetUpdatesCallerInfo::NEWLY_SUPPORTED_DATATYPE: - return sync_pb::SyncEnums::NEWLY_SUPPORTED_DATATYPE; - case sync_pb::GetUpdatesCallerInfo::MIGRATION: - return sync_pb::SyncEnums::MIGRATION; - case sync_pb::GetUpdatesCallerInfo::RECONFIGURATION: - return sync_pb::SyncEnums::RECONFIGURATION; - case sync_pb::GetUpdatesCallerInfo::NEW_CLIENT: - return sync_pb::SyncEnums::NEW_CLIENT; - case sync_pb::GetUpdatesCallerInfo::PROGRAMMATIC: - return sync_pb::SyncEnums::PROGRAMMATIC; - default: - NOTREACHED(); - return sync_pb::SyncEnums::UNKNOWN_ORIGIN; - } + return std::unique_ptr<ProtocolEvent>( + new ConfigureGetUpdatesRequestEvent(timestamp, origin_, request)); } PollGetUpdatesDelegate::PollGetUpdatesDelegate() {} @@ -146,11 +130,11 @@ void PollGetUpdatesDelegate::HelpPopulateGuMessage( sync_pb::GetUpdatesMessage* get_updates) const { - // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. + // Fill the legacy GetUpdatesSource field. This is not used anymore, but it's + // a required field so we still have to fill it with something. get_updates->mutable_caller_info()->set_source( - sync_pb::GetUpdatesCallerInfo::PERIODIC); + sync_pb::GetUpdatesCallerInfo::UNKNOWN); - // Set the new and improved version of source, too. get_updates->set_get_updates_origin(sync_pb::SyncEnums::PERIODIC); }
diff --git a/components/sync/engine_impl/get_updates_delegate.h b/components/sync/engine_impl/get_updates_delegate.h index f02829e..88e3d601 100644 --- a/components/sync/engine_impl/get_updates_delegate.h +++ b/components/sync/engine_impl/get_updates_delegate.h
@@ -69,8 +69,8 @@ // Functionality specific to the configure GetUpdate request. class ConfigureGetUpdatesDelegate : public GetUpdatesDelegate { public: - ConfigureGetUpdatesDelegate( - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source); + explicit ConfigureGetUpdatesDelegate( + sync_pb::SyncEnums::GetUpdatesOrigin origin); ~ConfigureGetUpdatesDelegate() override; // Sets the 'source' and 'origin' fields for this request. @@ -90,10 +90,7 @@ const sync_pb::ClientToServerMessage& request) const override; private: - static sync_pb::SyncEnums::GetUpdatesOrigin ConvertConfigureSourceToOrigin( - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source); - - const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source_; + const sync_pb::SyncEnums::GetUpdatesOrigin origin_; DISALLOW_COPY_AND_ASSIGN(ConfigureGetUpdatesDelegate); };
diff --git a/components/sync/engine_impl/get_updates_processor.cc b/components/sync/engine_impl/get_updates_processor.cc index 85e4542..5ac5d88 100644 --- a/components/sync/engine_impl/get_updates_processor.cc +++ b/components/sync/engine_impl/get_updates_processor.cc
@@ -152,7 +152,6 @@ bool need_encryption_key = ShouldRequestEncryptionKey(cycle->context()); get_updates->set_need_encryption_key(need_encryption_key); - // Set legacy GetUpdatesMessage.GetUpdatesCallerInfo information. get_updates->mutable_caller_info()->set_notifications_enabled( cycle->context()->notifications_enabled()); }
diff --git a/components/sync/engine_impl/get_updates_processor_unittest.cc b/components/sync/engine_impl/get_updates_processor_unittest.cc index e45eb3f..34fe0b4 100644 --- a/components/sync/engine_impl/get_updates_processor_unittest.cc +++ b/components/sync/engine_impl/get_updates_processor_unittest.cc
@@ -108,8 +108,6 @@ processor->PrepareGetUpdates(enabled_types(), &message); const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates(); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::LOCAL, - gu_msg.caller_info().source()); EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin()); for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { ModelType type = GetModelTypeFromSpecificsFieldNumber( @@ -156,8 +154,6 @@ processor->PrepareGetUpdates(enabled_types(), &message); const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates(); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::NOTIFICATION, - gu_msg.caller_info().source()); EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin()); for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { ModelType type = GetModelTypeFromSpecificsFieldNumber( @@ -196,8 +192,6 @@ processor->PrepareGetUpdates(enabled_types(), &message); const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates(); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::DATATYPE_REFRESH, - gu_msg.caller_info().source()); EXPECT_EQ(sync_pb::SyncEnums::GU_TRIGGER, gu_msg.get_updates_origin()); for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { ModelType type = GetModelTypeFromSpecificsFieldNumber( @@ -222,15 +216,13 @@ TEST_F(GetUpdatesProcessorTest, ConfigureTest) { sync_pb::ClientToServerMessage message; ConfigureGetUpdatesDelegate configure_delegate( - sync_pb::GetUpdatesCallerInfo::RECONFIGURATION); + sync_pb::SyncEnums::RECONFIGURATION); std::unique_ptr<GetUpdatesProcessor> processor( BuildGetUpdatesProcessor(configure_delegate)); processor->PrepareGetUpdates(enabled_types(), &message); const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates(); EXPECT_EQ(sync_pb::SyncEnums::RECONFIGURATION, gu_msg.get_updates_origin()); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, - gu_msg.caller_info().source()); ModelTypeSet progress_types; for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { @@ -250,8 +242,6 @@ const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates(); EXPECT_EQ(sync_pb::SyncEnums::PERIODIC, gu_msg.get_updates_origin()); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC, - gu_msg.caller_info().source()); ModelTypeSet progress_types; for (int i = 0; i < gu_msg.from_progress_marker_size(); ++i) { @@ -280,8 +270,6 @@ const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates(); EXPECT_EQ(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin()); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RETRY, - gu_msg.caller_info().source()); EXPECT_TRUE(gu_msg.is_retry()); ModelTypeSet progress_types; @@ -314,8 +302,6 @@ const sync_pb::GetUpdatesMessage& gu_msg = message.get_updates(); EXPECT_NE(sync_pb::SyncEnums::RETRY, gu_msg.get_updates_origin()); - EXPECT_NE(sync_pb::GetUpdatesCallerInfo::RETRY, - gu_msg.caller_info().source()); EXPECT_TRUE(gu_msg.is_retry()); } @@ -423,7 +409,7 @@ // types. TEST_F(GetUpdatesProcessorApplyUpdatesTest, Configure) { ConfigureGetUpdatesDelegate configure_delegate( - sync_pb::GetUpdatesCallerInfo::RECONFIGURATION); + sync_pb::SyncEnums::RECONFIGURATION); std::unique_ptr<GetUpdatesProcessor> processor( BuildGetUpdatesProcessor(configure_delegate));
diff --git a/components/sync/engine_impl/js_sync_manager_observer_unittest.cc b/components/sync/engine_impl/js_sync_manager_observer_unittest.cc index 52774eeb..8dc6370f 100644 --- a/components/sync/engine_impl/js_sync_manager_observer_unittest.cc +++ b/components/sync/engine_impl/js_sync_manager_observer_unittest.cc
@@ -66,7 +66,7 @@ base::Time::Now(), std::vector<int>(MODEL_TYPE_COUNT, 0), std::vector<int>(MODEL_TYPE_COUNT, 0), - sync_pb::GetUpdatesCallerInfo::UNKNOWN); + sync_pb::SyncEnums::UNKNOWN_ORIGIN); base::DictionaryValue expected_details; expected_details.Set("snapshot", snapshot.ToValue());
diff --git a/components/sync/engine_impl/sync_manager_for_profile_sync_test.cc b/components/sync/engine_impl/sync_manager_for_profile_sync_test.cc index 2d946e3e..3af98e71 100644 --- a/components/sync/engine_impl/sync_manager_for_profile_sync_test.cc +++ b/components/sync/engine_impl/sync_manager_for_profile_sync_test.cc
@@ -12,8 +12,8 @@ SyncManagerForProfileSyncTest::SyncManagerForProfileSyncTest( std::string name, - base::Closure init_callback) - : SyncManagerImpl(name), init_callback_(init_callback) {} + base::OnceClosure init_callback) + : SyncManagerImpl(name), init_callback_(std::move(init_callback)) {} SyncManagerForProfileSyncTest::~SyncManagerForProfileSyncTest() {} @@ -22,7 +22,7 @@ syncable::Directory* directory = user_share->directory.get(); if (!init_callback_.is_null()) - init_callback_.Run(); + std::move(init_callback_).Run(); ModelTypeSet early_download_types; early_download_types.PutAll(ControlTypes());
diff --git a/components/sync/engine_impl/sync_manager_for_profile_sync_test.h b/components/sync/engine_impl/sync_manager_for_profile_sync_test.h index 3292d87..f1399f8 100644 --- a/components/sync/engine_impl/sync_manager_for_profile_sync_test.h +++ b/components/sync/engine_impl/sync_manager_for_profile_sync_test.h
@@ -17,12 +17,13 @@ // Those tests try to test sync without instantiating a real backend. class SyncManagerForProfileSyncTest : public SyncManagerImpl { public: - SyncManagerForProfileSyncTest(std::string name, base::Closure init_callback); + SyncManagerForProfileSyncTest(std::string name, + base::OnceClosure init_callback); ~SyncManagerForProfileSyncTest() override; void NotifyInitializationSuccess() override; private: - base::Closure init_callback_; + base::OnceClosure init_callback_; }; } // namespace syncer
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc index 80ad5e1..2f3a289 100644 --- a/components/sync/engine_impl/sync_manager_impl.cc +++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -49,7 +49,6 @@ using base::TimeDelta; -using sync_pb::GetUpdatesCallerInfo; class GURL; @@ -61,25 +60,25 @@ namespace { -GetUpdatesCallerInfo::GetUpdatesSource GetSourceFromReason( +sync_pb::SyncEnums::GetUpdatesOrigin GetOriginFromReason( ConfigureReason reason) { switch (reason) { case CONFIGURE_REASON_RECONFIGURATION: - return GetUpdatesCallerInfo::RECONFIGURATION; + return sync_pb::SyncEnums::RECONFIGURATION; case CONFIGURE_REASON_MIGRATION: - return GetUpdatesCallerInfo::MIGRATION; + return sync_pb::SyncEnums::MIGRATION; case CONFIGURE_REASON_NEW_CLIENT: - return GetUpdatesCallerInfo::NEW_CLIENT; + return sync_pb::SyncEnums::NEW_CLIENT; case CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE: case CONFIGURE_REASON_CRYPTO: case CONFIGURE_REASON_CATCH_UP: - return GetUpdatesCallerInfo::NEWLY_SUPPORTED_DATATYPE; + return sync_pb::SyncEnums::NEWLY_SUPPORTED_DATATYPE; case CONFIGURE_REASON_PROGRAMMATIC: - return GetUpdatesCallerInfo::PROGRAMMATIC; + return sync_pb::SyncEnums::PROGRAMMATIC; case CONFIGURE_REASON_UNKNOWN: NOTREACHED(); } - return GetUpdatesCallerInfo::UNKNOWN; + return sync_pb::SyncEnums::UNKNOWN_ORIGIN; } } // namespace @@ -190,7 +189,7 @@ DVLOG(1) << "Configuring -" << "\n\t" << "types to download: " << ModelTypeSetToString(to_download); - ConfigurationParams params(GetSourceFromReason(reason), to_download, + ConfigurationParams params(GetOriginFromReason(reason), to_download, ready_task, retry_task); scheduler_->Start(SyncScheduler::CONFIGURATION_MODE, base::Time());
diff --git a/components/sync/engine_impl/sync_manager_impl_unittest.cc b/components/sync/engine_impl/sync_manager_impl_unittest.cc index d349dd9..ef1a524 100644 --- a/components/sync/engine_impl/sync_manager_impl_unittest.cc +++ b/components/sync/engine_impl/sync_manager_impl_unittest.cc
@@ -2710,7 +2710,7 @@ base::Unretained(&retry_task_counter))); EXPECT_EQ(0, ready_task_counter.times_called()); EXPECT_EQ(0, retry_task_counter.times_called()); - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, params.source); + EXPECT_EQ(sync_pb::SyncEnums::RECONFIGURATION, params.origin); EXPECT_EQ(types_to_download, params.types_to_download); }
diff --git a/components/sync/engine_impl/sync_scheduler.h b/components/sync/engine_impl/sync_scheduler.h index d3229e1..423bec9 100644 --- a/components/sync/engine_impl/sync_scheduler.h +++ b/components/sync/engine_impl/sync_scheduler.h
@@ -24,16 +24,15 @@ struct ConfigurationParams { ConfigurationParams(); - ConfigurationParams( - const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, - ModelTypeSet types_to_download, - const base::Closure& ready_task, - const base::Closure& retry_task); + ConfigurationParams(sync_pb::SyncEnums::GetUpdatesOrigin origin, + ModelTypeSet types_to_download, + const base::Closure& ready_task, + const base::Closure& retry_task); ConfigurationParams(const ConfigurationParams& other); ~ConfigurationParams(); - // Source for the configuration. - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source; + // Origin for the configuration. + sync_pb::SyncEnums::GetUpdatesOrigin origin; // The types that should be downloaded. ModelTypeSet types_to_download; // Callback to invoke on configuration completion.
diff --git a/components/sync/engine_impl/sync_scheduler_impl.cc b/components/sync/engine_impl/sync_scheduler_impl.cc index 935fc8ac..e5e45d47 100644 --- a/components/sync/engine_impl/sync_scheduler_impl.cc +++ b/components/sync/engine_impl/sync_scheduler_impl.cc
@@ -23,20 +23,19 @@ using base::TimeDelta; using base::TimeTicks; -using sync_pb::GetUpdatesCallerInfo; namespace syncer { namespace { -bool IsConfigRelatedUpdateSourceValue( - GetUpdatesCallerInfo::GetUpdatesSource source) { - switch (source) { - case GetUpdatesCallerInfo::RECONFIGURATION: - case GetUpdatesCallerInfo::MIGRATION: - case GetUpdatesCallerInfo::NEW_CLIENT: - case GetUpdatesCallerInfo::NEWLY_SUPPORTED_DATATYPE: - case GetUpdatesCallerInfo::PROGRAMMATIC: +bool IsConfigRelatedUpdateOriginValue( + sync_pb::SyncEnums::GetUpdatesOrigin origin) { + switch (origin) { + case sync_pb::SyncEnums::RECONFIGURATION: + case sync_pb::SyncEnums::MIGRATION: + case sync_pb::SyncEnums::NEW_CLIENT: + case sync_pb::SyncEnums::NEWLY_SUPPORTED_DATATYPE: + case sync_pb::SyncEnums::PROGRAMMATIC: return true; default: return false; @@ -94,13 +93,13 @@ } // namespace ConfigurationParams::ConfigurationParams() - : source(GetUpdatesCallerInfo::UNKNOWN) {} + : origin(sync_pb::SyncEnums::UNKNOWN_ORIGIN) {} ConfigurationParams::ConfigurationParams( - const sync_pb::GetUpdatesCallerInfo::GetUpdatesSource& source, + sync_pb::SyncEnums::GetUpdatesOrigin origin, ModelTypeSet types_to_download, const base::Closure& ready_task, const base::Closure& retry_task) - : source(source), + : origin(origin), types_to_download(types_to_download), ready_task(ready_task), retry_task(retry_task) { @@ -254,7 +253,7 @@ void SyncSchedulerImpl::ScheduleConfiguration( const ConfigurationParams& params) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(IsConfigRelatedUpdateSourceValue(params.source)); + DCHECK(IsConfigRelatedUpdateOriginValue(params.origin)); DCHECK_EQ(CONFIGURATION_MODE, mode_); DCHECK(!params.ready_task.is_null()); DCHECK(started_) << "Scheduler must be running to configure."; @@ -473,7 +472,7 @@ SyncCycle cycle(cycle_context_, this); bool success = syncer_->ConfigureSyncShare(pending_configure_params_->types_to_download, - pending_configure_params_->source, &cycle); + pending_configure_params_->origin, &cycle); if (success) { SDVLOG(2) << "Configure succeeded.";
diff --git a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc index 3c9bbc4..d309241 100644 --- a/components/sync/engine_impl/sync_scheduler_impl_unittest.cc +++ b/components/sync/engine_impl/sync_scheduler_impl_unittest.cc
@@ -44,15 +44,13 @@ namespace syncer { -using sync_pb::GetUpdatesCallerInfo; - class MockSyncer : public Syncer { public: MockSyncer(); MOCK_METHOD3(NormalSyncShare, bool(ModelTypeSet, NudgeTracker*, SyncCycle*)); MOCK_METHOD3(ConfigureSyncShare, bool(const ModelTypeSet&, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource, + sync_pb::SyncEnums::GetUpdatesOrigin, SyncCycle*)); MOCK_METHOD2(PollSyncShare, bool(ModelTypeSet, SyncCycle*)); }; @@ -388,7 +386,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, model_types, + sync_pb::SyncEnums::RECONFIGURATION, model_types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -416,7 +414,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, model_types, + sync_pb::SyncEnums::RECONFIGURATION, model_types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -461,7 +459,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, model_types, + sync_pb::SyncEnums::RECONFIGURATION, model_types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -482,7 +480,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, model_types, + sync_pb::SyncEnums::RECONFIGURATION, model_types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -509,7 +507,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, model_types, + sync_pb::SyncEnums::RECONFIGURATION, model_types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -536,7 +534,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, model_types, + sync_pb::SyncEnums::RECONFIGURATION, model_types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -797,7 +795,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, types, + sync_pb::SyncEnums::RECONFIGURATION, types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -881,7 +879,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, types, + sync_pb::SyncEnums::RECONFIGURATION, types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -1214,7 +1212,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, config_types, + sync_pb::SyncEnums::RECONFIGURATION, config_types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -1306,7 +1304,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, types, + sync_pb::SyncEnums::RECONFIGURATION, types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -1355,7 +1353,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, types, + sync_pb::SyncEnums::RECONFIGURATION, types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params); @@ -1614,7 +1612,7 @@ CallbackCounter ready_counter; CallbackCounter retry_counter; ConfigurationParams params( - GetUpdatesCallerInfo::RECONFIGURATION, model_types, + sync_pb::SyncEnums::RECONFIGURATION, model_types, base::Bind(&CallbackCounter::Callback, base::Unretained(&ready_counter)), base::Bind(&CallbackCounter::Callback, base::Unretained(&retry_counter))); scheduler()->ScheduleConfiguration(params);
diff --git a/components/sync/engine_impl/syncer.cc b/components/sync/engine_impl/syncer.cc index 158652ce..6a81698 100644 --- a/components/sync/engine_impl/syncer.cc +++ b/components/sync/engine_impl/syncer.cc
@@ -60,7 +60,7 @@ if (!DownloadAndApplyUpdates(&request_types, cycle, NormalGetUpdatesDelegate(*nudge_tracker), kCreateMobileBookmarksFolder)) { - return HandleCycleEnd(cycle, nudge_tracker->GetLegacySource()); + return HandleCycleEnd(cycle, nudge_tracker->GetOrigin()); } } @@ -70,13 +70,12 @@ cycle, &commit_processor); cycle->mutable_status_controller()->set_commit_result(commit_result); - return HandleCycleEnd(cycle, nudge_tracker->GetLegacySource()); + return HandleCycleEnd(cycle, nudge_tracker->GetOrigin()); } -bool Syncer::ConfigureSyncShare( - const ModelTypeSet& request_types, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, - SyncCycle* cycle) { +bool Syncer::ConfigureSyncShare(const ModelTypeSet& request_types, + sync_pb::SyncEnums::GetUpdatesOrigin origin, + SyncCycle* cycle) { base::AutoReset<bool> is_syncing(&is_syncing_, true); // It is possible during configuration that datatypes get unregistered from @@ -90,9 +89,9 @@ VLOG(1) << "Configuring types " << ModelTypeSetToString(still_enabled_types); HandleCycleBegin(cycle); DownloadAndApplyUpdates(&still_enabled_types, cycle, - ConfigureGetUpdatesDelegate(source), + ConfigureGetUpdatesDelegate(origin), kCreateMobileBookmarksFolder); - return HandleCycleEnd(cycle, source); + return HandleCycleEnd(cycle, origin); } bool Syncer::PollSyncShare(ModelTypeSet request_types, SyncCycle* cycle) { @@ -101,7 +100,7 @@ HandleCycleBegin(cycle); DownloadAndApplyUpdates(&request_types, cycle, PollGetUpdatesDelegate(), kCreateMobileBookmarksFolder); - return HandleCycleEnd(cycle, sync_pb::GetUpdatesCallerInfo::PERIODIC); + return HandleCycleEnd(cycle, sync_pb::SyncEnums::PERIODIC); } bool Syncer::PostClearServerData(SyncCycle* cycle) { @@ -196,16 +195,15 @@ return cancelation_signal_->IsSignalled(); } -bool Syncer::HandleCycleEnd( - SyncCycle* cycle, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source) { +bool Syncer::HandleCycleEnd(SyncCycle* cycle, + sync_pb::SyncEnums::GetUpdatesOrigin origin) { if (ExitRequested()) return false; - cycle->SendSyncCycleEndEventNotification(source); + cycle->SendSyncCycleEndEventNotification(origin); bool success = !HasSyncerError(cycle->status_controller().model_neutral_state()); - if (success && source == sync_pb::GetUpdatesCallerInfo::PERIODIC) { + if (success && origin == sync_pb::SyncEnums::PERIODIC) { cycle->mutable_status_controller()->UpdatePollTime(); }
diff --git a/components/sync/engine_impl/syncer.h b/components/sync/engine_impl/syncer.h index 455c7590..2aac6af 100644 --- a/components/sync/engine_impl/syncer.h +++ b/components/sync/engine_impl/syncer.h
@@ -57,10 +57,9 @@ // purposes. It describes the reson for performing this initial download. // Returns: false if an error occurred and retries should backoff, true // otherwise. - virtual bool ConfigureSyncShare( - const ModelTypeSet& request_types, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source, - SyncCycle* cycle); + virtual bool ConfigureSyncShare(const ModelTypeSet& request_types, + sync_pb::SyncEnums::GetUpdatesOrigin origin, + SyncCycle* cycle); // Requests to download updates for the |request_types|. For a well-behaved // client with a working connection to the invalidations server, this should @@ -94,7 +93,7 @@ bool ExitRequested(); bool HandleCycleEnd(SyncCycle* cycle, - sync_pb::GetUpdatesCallerInfo::GetUpdatesSource source); + sync_pb::SyncEnums::GetUpdatesOrigin origin); CancelationSignal* const cancelation_signal_;
diff --git a/components/sync/engine_impl/syncer_unittest.cc b/components/sync/engine_impl/syncer_unittest.cc index 310abd7d..c95fb2c 100644 --- a/components/sync/engine_impl/syncer_unittest.cc +++ b/components/sync/engine_impl/syncer_unittest.cc
@@ -259,7 +259,7 @@ bool SyncShareConfigureTypes(ModelTypeSet types) { ResetCycle(); return syncer_->ConfigureSyncShare( - types, sync_pb::GetUpdatesCallerInfo::RECONFIGURATION, cycle_.get()); + types, sync_pb::SyncEnums::RECONFIGURATION, cycle_.get()); } void SetUp() override {
diff --git a/components/sync/protocol/attachments.proto b/components/sync/protocol/attachments.proto deleted file mode 100644 index 3f4846b..0000000 --- a/components/sync/protocol/attachments.proto +++ /dev/null
@@ -1,39 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Sync protocol for attachments. - -// Update proto_{value,enum}_conversions{.h,.cc,_unittest.cc} if you change any -// fields in this file. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -package sync_pb; - -// Identifies an attachment. -message AttachmentIdProto { - // Uniquely identifies the attachment. Two attachments with the same unique_id - // are considered equivalent. - optional string unique_id = 1; - // Size of the attachment data in bytes. - optional uint64 size_bytes = 2; - // Crc32c of the attachment data. - optional uint32 crc32c = 3; -} - -// Metadata for a single attachment. -message AttachmentMetadataRecord { - optional AttachmentIdProto id = 1; - // Indicates we know this attachment exists on the server. - optional bool is_on_server = 2; -} - -// A collection of attachment metadata. This proto is part of EntryKernel's "on -// disk" representation. Private to sync. -message AttachmentMetadata { - // One record per attachment. - repeated AttachmentMetadataRecord record = 1; -}
diff --git a/components/sync/protocol/client_debug_info.proto b/components/sync/protocol/client_debug_info.proto index d2446e03..b10cb4e 100644 --- a/components/sync/protocol/client_debug_info.proto +++ b/components/sync/protocol/client_debug_info.proto
@@ -22,14 +22,7 @@ optional bool has_valid_hint = 2; } -// Information about the source that triggered a sync. -message SourceInfo { - // An enum indicating the reason for the nudge. - optional GetUpdatesCallerInfo.GetUpdatesSource source = 1; - - // The per-type hint information associated with the nudge. - repeated TypeHint type_hint = 2; -} +message DeprecatedSourceInfo {} // The additional info here is from the StatusController. They get sent when // the event SYNC_CYCLE_COMPLETED is sent. @@ -55,13 +48,15 @@ // Counts to track the effective usefulness of our GetUpdate requests. optional int32 num_updates_downloaded = 8; optional int32 num_reflected_updates_downloaded = 9; + + // |caller_info| was mostly replaced by |get_updates_origin|; now it only + // contains the |notifications_enabled| flag. optional GetUpdatesCallerInfo caller_info = 10; - // A list of all the sources that were merged into this cycle. - // - // Some scenarios, notably mode switches and canary jobs, can spuriously add - // back-to-back duplicate sources to this list. - repeated SourceInfo source_info = 11; + // |source_info| was unused and marked deprecated in M66. + repeated DeprecatedSourceInfo source_info = 11 [deprecated = true]; + + optional SyncEnums.GetUpdatesOrigin get_updates_origin = 12; } // Datatype specifics statistics gathered at association time.
diff --git a/components/sync/protocol/get_updates_caller_info.proto b/components/sync/protocol/get_updates_caller_info.proto index bfc092d..f035864 100644 --- a/components/sync/protocol/get_updates_caller_info.proto +++ b/components/sync/protocol/get_updates_caller_info.proto
@@ -9,45 +9,15 @@ package sync_pb; message GetUpdatesCallerInfo { - // This message was deprecated in M28. The preferred represenation of this + // This enum was deprecated in M28. The preferred represenation of this // information is now the GetUpdatesOrigin enum, which is defined in - // sync_enums.proto. - enum GetUpdatesSource { - UNKNOWN = 0; // The source was not set by the caller. - FIRST_UPDATE = 1; // First request after browser restart. Not to - // be confused with "NEW_CLIENT". - LOCAL = 2; // The source of the update was a local change. - NOTIFICATION = 3; // The source of the update was a p2p notification. - PERIODIC = 4; // The source of the update was periodic polling. - SYNC_CYCLE_CONTINUATION = 5; // The source of the update was a - // continuation of a previous sync cycle. - // No longer sent as of M24. - - // This value is deprecated and was never used in production. - // CLEAR_PRIVATE_DATA = 6; - - NEWLY_SUPPORTED_DATATYPE = 7; // The client is in configuration mode - // because it's syncing all datatypes, and - // support for a new datatype was recently - // released via a software auto-update. - MIGRATION = 8; // The client is in configuration mode because a - // MIGRATION_DONE error previously returned by the - // server necessitated resynchronization. - NEW_CLIENT = 9; // The client is in configuration mode because the - // user enabled sync for the first time. Not to be - // confused with FIRST_UPDATE. - RECONFIGURATION = 10; // The client is in configuration mode because the - // user opted to sync a different set of datatypes. - DATATYPE_REFRESH = 11; // A datatype has requested a refresh. This is - // typically used when datatype's have custom - // sync UI, e.g. sessions. - RETRY = 13; // A follow-up GU to pick up updates missed by previous GU. - PROGRAMMATIC = 14; // The client is programmatically enabling/disabling - // a type, typically for error handling purposes. - } - - required GetUpdatesSource source = 1; + // sync_enums.proto. However, since |source| is a required field, both the + // field and the enum have to be kept around. + enum GetUpdatesSource { UNKNOWN = 0; } + required GetUpdatesSource source = 1 [deprecated = true]; // True only if notifications were enabled for this GetUpdateMessage. + // TODO(crbug.com/510165): Move this bool out of GetUpdatesCallerInfo so that + // GetUpdatesCallerInfo can be removed. optional bool notifications_enabled = 2; };
diff --git a/components/sync/protocol/proto_enum_conversions.cc b/components/sync/protocol/proto_enum_conversions.cc index 24dc909..0de51225 100644 --- a/components/sync/protocol/proto_enum_conversions.cc +++ b/components/sync/protocol/proto_enum_conversions.cc
@@ -75,24 +75,11 @@ const char* ProtoEnumToString( sync_pb::GetUpdatesCallerInfo::GetUpdatesSource updates_source) { - ASSERT_ENUM_BOUNDS(sync_pb::GetUpdatesCallerInfo, GetUpdatesSource, UNKNOWN, - PROGRAMMATIC); switch (updates_source) { ENUM_CASE(sync_pb::GetUpdatesCallerInfo, UNKNOWN); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, FIRST_UPDATE); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, LOCAL); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, NOTIFICATION); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, PERIODIC); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, SYNC_CYCLE_CONTINUATION); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, NEWLY_SUPPORTED_DATATYPE); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, MIGRATION); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, NEW_CLIENT); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, RECONFIGURATION); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, DATATYPE_REFRESH); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, RETRY); - ENUM_CASE(sync_pb::GetUpdatesCallerInfo, PROGRAMMATIC); } - NOTREACHED(); + // Note: No "NOTREACHED()" here - this enum used to have more entries, but it + // has been deprecated so we don't need to handle them anymore. return ""; }
diff --git a/components/sync/protocol/proto_enum_conversions_unittest.cc b/components/sync/protocol/proto_enum_conversions_unittest.cc index 71370dc..5ce5fe7 100644 --- a/components/sync/protocol/proto_enum_conversions_unittest.cc +++ b/components/sync/protocol/proto_enum_conversions_unittest.cc
@@ -49,11 +49,21 @@ TEST_F(ProtoEnumConversionsTest, GetUpdatesSourceString) { TestEnumStringFunction(sync_pb::GetUpdatesCallerInfo::GetUpdatesSource_MIN, - sync_pb::GetUpdatesCallerInfo::PERIODIC); - TestEnumStringFunction(sync_pb::GetUpdatesCallerInfo::RETRY, sync_pb::GetUpdatesCallerInfo::GetUpdatesSource_MAX); } +TEST_F(ProtoEnumConversionsTest, GetUpdatesOriginString) { + // This enum has rather scattered values, so we need multiple ranges. + TestEnumStringFunction(sync_pb::SyncEnums::GetUpdatesOrigin_MIN, + sync_pb::SyncEnums::UNKNOWN_ORIGIN); + TestEnumStringFunction(sync_pb::SyncEnums::PERIODIC, + sync_pb::SyncEnums::PERIODIC); + TestEnumStringFunction(sync_pb::SyncEnums::NEWLY_SUPPORTED_DATATYPE, + sync_pb::SyncEnums::RECONFIGURATION); + TestEnumStringFunction(sync_pb::SyncEnums::GU_TRIGGER, + sync_pb::SyncEnums::GetUpdatesOrigin_MAX); +} + TEST_F(ProtoEnumConversionsTest, GetResponseTypeString) { TestEnumStringFunction(sync_pb::CommitResponse::ResponseType_MIN, sync_pb::CommitResponse::ResponseType_MAX);
diff --git a/components/sync/protocol/proto_memory_estimations.cc b/components/sync/protocol/proto_memory_estimations.cc index a36c1478..0f66046 100644 --- a/components/sync/protocol/proto_memory_estimations.cc +++ b/components/sync/protocol/proto_memory_estimations.cc
@@ -121,7 +121,6 @@ #define INSTANTIATE(Proto) \ template size_t EstimateMemoryUsage<Proto>(const Proto&); -INSTANTIATE(AttachmentMetadata) INSTANTIATE(DataTypeContext) INSTANTIATE(DataTypeProgressMarker) INSTANTIATE(EntityMetadata)
diff --git a/components/sync/protocol/proto_visitors.h b/components/sync/protocol/proto_visitors.h index ffe266d..97c28db4d 100644 --- a/components/sync/protocol/proto_visitors.h +++ b/components/sync/protocol/proto_visitors.h
@@ -10,7 +10,6 @@ #include "components/sync/protocol/app_setting_specifics.pb.h" #include "components/sync/protocol/app_specifics.pb.h" #include "components/sync/protocol/arc_package_specifics.pb.h" -#include "components/sync/protocol/attachments.pb.h" #include "components/sync/protocol/autofill_specifics.pb.h" #include "components/sync/protocol/bookmark_specifics.pb.h" #include "components/sync/protocol/dictionary_specifics.pb.h" @@ -146,19 +145,6 @@ VISIT_REP(pages); } -VISIT_PROTO_FIELDS(const sync_pb::AttachmentIdProto& proto) { - VISIT(unique_id); -} - -VISIT_PROTO_FIELDS(const sync_pb::AttachmentMetadata& proto) { - VISIT_REP(record); -} - -VISIT_PROTO_FIELDS(const sync_pb::AttachmentMetadataRecord& proto) { - VISIT(id); - VISIT(is_on_server); -} - VISIT_PROTO_FIELDS(const sync_pb::AutofillCullingFlags& proto) { VISIT(enabled); } @@ -758,11 +744,6 @@ VISIT_ENUM(browser_type); } -VISIT_PROTO_FIELDS(const sync_pb::SourceInfo& proto) { - VISIT_ENUM(source); - VISIT_REP(type_hint); -} - VISIT_PROTO_FIELDS(const sync_pb::SyncCycleCompletedEventInfo& proto) { VISIT(num_encryption_conflicts); VISIT(num_hierarchy_conflicts); @@ -770,7 +751,7 @@ VISIT(num_updates_downloaded); VISIT(num_reflected_updates_downloaded); VISIT(caller_info); - VISIT_REP(source_info); + VISIT_ENUM(get_updates_origin); } VISIT_PROTO_FIELDS(const sync_pb::SyncEntity& proto) {
diff --git a/components/sync/protocol/protocol_sources.gni b/components/sync/protocol/protocol_sources.gni index 5b58e1a..3212373 100644 --- a/components/sync/protocol/protocol_sources.gni +++ b/components/sync/protocol/protocol_sources.gni
@@ -9,7 +9,6 @@ "//components/sync/protocol/app_list_specifics.proto", "//components/sync/protocol/arc_package_specifics.proto", "//components/sync/protocol/article_specifics.proto", - "//components/sync/protocol/attachments.proto", "//components/sync/protocol/autofill_specifics.proto", "//components/sync/protocol/bookmark_specifics.proto", "//components/sync/protocol/client_commands.proto",
diff --git a/components/sync/protocol/sync.proto b/components/sync/protocol/sync.proto index 4d3001a..0e0b7bd 100644 --- a/components/sync/protocol/sync.proto +++ b/components/sync/protocol/sync.proto
@@ -618,8 +618,9 @@ optional int64 from_timestamp = 1; // Indicates the reason for the GetUpdatesMessage. - // Deprecated in M29. We should eventually rely on GetUpdatesOrigin instead. - // Newer clients will support both systems during the transition period. + // This was *mostly* deprecated in M29. We now rely on GetUpdatesOrigin + // instead to encode the reason for the GetUpdates request. Now this field + // only contains the "notifications_enabled" flag. optional GetUpdatesCallerInfo caller_info = 2; // Indicates whether related folders should be fetched.
diff --git a/components/sync/syncable/directory_backing_store.cc b/components/sync/syncable/directory_backing_store.cc index 9bc512e..6b681c4b 100644 --- a/components/sync/syncable/directory_backing_store.cc +++ b/components/sync/syncable/directory_backing_store.cc
@@ -82,19 +82,10 @@ ////////////////////////////////////// // Blobs (positions). {"server_unique_position", "blob"}, - {"unique_position", "blob"}, - ////////////////////////////////////// - // AttachmentMetadata is a proto that contains all the metadata associated - // with an entry's attachments. Each entry has only one AttachmentMetadata - // proto. We store a single proto per entry (as opposed to one for each - // attachment) because it simplifies the database schema and implementation - // of - // DirectoryBackingStore. - {"attachment_metadata", "blob"}, - {"server_attachment_metadata", "blob"}}; + {"unique_position", "blob"}}; // Increment this version whenever updating DB tables. -const int32_t kCurrentDBVersion = 91; +const int32_t kCurrentDBVersion = 92; // The current database page size in Kilobytes. const int32_t kCurrentPageSizeKB = 32768; @@ -132,11 +123,6 @@ entry.ref(static_cast<UniquePositionField>(i)).SerializeToString(&temp); statement->BindBlob(index++, temp.data(), temp.length()); } - for (; i < ATTACHMENT_METADATA_FIELDS_END; ++i) { - std::string temp; - entry.ref(static_cast<AttachmentMetadataField>(i)).SerializeToString(&temp); - statement->BindBlob(index++, temp.data(), temp.length()); - } } // Helper function that loads a number of shareable fields of the @@ -220,10 +206,6 @@ kernel->mutable_ref(static_cast<UniquePositionField>(i)) = UniquePosition::FromProto(proto); } - int attachemnt_specifics_counts = 0; - UnpackProtoFields<sync_pb::AttachmentMetadata, AttachmentMetadataField>( - statement, kernel.get(), &i, ATTACHMENT_METADATA_FIELDS_END, - &attachemnt_specifics_counts); // Sanity check on positions. We risk strange and rare crashes if our // assumptions about unique position values are broken. @@ -637,6 +619,12 @@ version_on_disk = 91; } + // Version 92 migration removes attachment metadata from the metas table. + if (version_on_disk == 91) { + if (MigrateVersion91To92()) + version_on_disk = 92; + } + // If one of the migrations requested it, drop columns that aren't current. // It's only safe to do this after migrating all the way to the current // version. @@ -1570,6 +1558,16 @@ return true; } +bool DirectoryBackingStore::MigrateVersion91To92() { + // This change removed 2 columns from metas: + // attachment_metadata + // server_attachment_metadata + // No data migration is necessary, but we should do a column refresh. + SetVersion(92); + needs_metas_column_refresh_ = true; + return true; +} + bool DirectoryBackingStore::CreateTables() { DVLOG(1) << "First run, creating tables";
diff --git a/components/sync/syncable/directory_backing_store.h b/components/sync/syncable/directory_backing_store.h index 149a32f..20b4529 100644 --- a/components/sync/syncable/directory_backing_store.h +++ b/components/sync/syncable/directory_backing_store.h
@@ -188,6 +188,7 @@ bool MigrateVersion88To89(); bool MigrateVersion89To90(); bool MigrateVersion90To91(); + bool MigrateVersion91To92(); // Accessor for needs_column_refresh_. Used in tests. bool needs_column_refresh() const;
diff --git a/components/sync/syncable/directory_backing_store_unittest.cc b/components/sync/syncable/directory_backing_store_unittest.cc index 3093bf9..e9ccac8 100644 --- a/components/sync/syncable/directory_backing_store_unittest.cc +++ b/components/sync/syncable/directory_backing_store_unittest.cc
@@ -98,9 +98,10 @@ void SetUpVersion89Database(sql::Connection* connection); void SetUpVersion90Database(sql::Connection* connection); void SetUpVersion91Database(sql::Connection* connection); + void SetUpVersion92Database(sql::Connection* connection); void SetUpCurrentDatabaseAndCheckVersion(sql::Connection* connection) { - SetUpVersion91Database(connection); // Prepopulates data. + SetUpVersion92Database(connection); // Prepopulates data. std::unique_ptr<TestDirectoryBackingStore> dbs( new TestDirectoryBackingStore(GetUsername(), connection)); ASSERT_EQ(kCurrentDBVersion, dbs->GetVersion()); @@ -3154,6 +3155,119 @@ ASSERT_TRUE(connection->CommitTransaction()); } +void MigrationTest::SetUpVersion92Database(sql::Connection* connection) { + ASSERT_TRUE(connection->is_open()); + ASSERT_TRUE(connection->BeginTransaction()); + // clang-format mangles the below query by indenting each time the + // META_PROTO_TIMES_VALS macro is invoked, making it unreadable. + // clang-format off + ASSERT_TRUE(connection->Execute( + "CREATE TABLE share_version (id VARCHAR(128) primary key, data INT);" + "INSERT INTO 'share_version' VALUES('nick@chromium.org',92);" + "CREATE TABLE models (model_id BLOB primary key, progress_marker BLOB, tr" + "ansaction_version BIGINT default 0, context BLOB);" + "INSERT INTO 'models' VALUES(X'C2881000',X'0888810218B605',1,NULL);" + "CREATE TABLE 'metas'(metahandle bigint primary key ON CONFLICT FAIL,base" + "_version bigint default -1,server_version bigint default 0,local_exte" + "rnal_id bigint default 0,transaction_version bigint default 0,mtime b" + "igint default 0,server_mtime bigint default 0,ctime bigint default 0," + "server_ctime bigint default 0,id varchar(255) default 'r',parent_id v" + "archar(255) default 'r',server_parent_id varchar(255) default 'r',is_" + "unsynced bit default 0,is_unapplied_update bit default 0,is_del bit d" + "efault 0,is_dir bit default 0,server_is_dir bit default 0,server_is_d" + "el bit default 0,non_unique_name varchar,server_non_unique_name varch" + "ar(255),unique_server_tag varchar,unique_client_tag varchar,unique_bo" + "okmark_tag varchar,specifics blob,server_specifics blob,base_server_s" + "pecifics blob,server_unique_position blob,unique_position blob);" + "INSERT INTO 'metas' VALUES(1,-1,0,0,0," + META_PROTO_TIMES_VALS(1) + ",'r','r','r',0,0,0,1,0,0,NULL,NULL,NULL,NULL,X'',X'',X'',NULL,X'2200'" + ",X'2200');" + "INSERT INTO 'metas' VALUES(6,694,694,6,0," + META_PROTO_TIMES_VALS(6) + ",'s_ID_6','s_ID_9','s_ID_9',0,0,0,1,1,0,'The Internet','The Internet'" + ",NULL,NULL,X'6754307476346749735A5734654D653273625336557753582F77673D" + "',X'C2881000',X'C2881000',NULL,X'22247FFFFFFFFFC000006754307476346749" + "735A5734654D653273625336557753582F77673D',X'22247FFFFFFFFFC0000067543" + "07476346749735A5734654D653273625336557753582F77673D');" + "INSERT INTO 'metas' VALUES(7,663,663,0,0," + META_PROTO_TIMES_VALS(7) + ",'s_ID_7','r','r',0,0,0,1,1,0,'Google Chrome','Google Chrome','google" + "_chrome',NULL,X'',NULL,NULL,NULL,X'2200',X'2200');" + "INSERT INTO 'metas' VALUES(8,664,664,0,0," + META_PROTO_TIMES_VALS(8) + ",'s_ID_8','s_ID_7','s_ID_7',0,0,0,1,1,0,'Bookmarks','Bookmarks','goog" + "le_chrome_bookmarks',NULL,X'',X'C2881000',X'C2881000',NULL,X'2200',X'" + "2200');" + "INSERT INTO 'metas' VALUES(9,665,665,1,0," + META_PROTO_TIMES_VALS(9) + ",'s_ID_9','s_ID_8','s_ID_8',0,0,0,1,1,0,'Bookmark Bar','Bookmark Bar'" + ",'bookmark_bar',NULL,X'',X'C2881000',X'C2881000',NULL,X'2200',X'2200'" + ");" + "INSERT INTO 'metas' VALUES(10,666,666,2,0," + META_PROTO_TIMES_VALS(10) + ",'s_ID_10','s_ID_8','s_ID_8',0,0,0,1,1,0,'Other Bookmarks','Other Boo" + "kmarks','other_bookmarks',NULL,X'',X'C2881000',X'C2881000',NULL,X'220" + "0',X'2200');" + "INSERT INTO 'metas' VALUES(11,683,683,8,0," + META_PROTO_TIMES_VALS(11) + ",'s_ID_11','s_ID_6','s_ID_6',0,0,0,0,0,0,'Home (The Chromium Projects" + ")','Home (The Chromium Projects)',NULL,NULL,X'50514C784A456D623579366" + "267644237646A7A2B62314130346E493D',X'C28810220A18687474703A2F2F646576" + "2E6368726F6D69756D2E6F72672F1206414741545741',X'C28810290A1D687474703" + "A2F2F6465762E6368726F6D69756D2E6F72672F6F7468657212084146414756415346" + "',NULL,X'22247FFFFFFFFFF0000050514C784A456D623579366267644237646A7A2B" + "62314130346E493D',X'22247FFFFFFFFFF0000050514C784A456D623579366267644" + "237646A7A2B62314130346E493D');" + "INSERT INTO 'metas' VALUES(12,685,685,9,0," + META_PROTO_TIMES_VALS(12) + ",'s_ID_12','s_ID_6','s_ID_6',0,0,0,1,1,0,'Extra Bookmarks','Extra Boo" + "kmarks',NULL,NULL,X'7867626A704A646134635A6F616C376A49513338734B46324" + "837773D',X'C2881000',X'C2881000',NULL,X'222480000000000000007867626A7" + "04A646134635A6F616C376A49513338734B46324837773D',X'222480000000000000" + "007867626A704A646134635A6F616C376A49513338734B46324837773D');" + "INSERT INTO 'metas' VALUES(13,687,687,10,0," + META_PROTO_TIMES_VALS(13) + ",'s_ID_13','s_ID_6','s_ID_6',0,0,0,0,0,0,'ICANN | Internet Corporatio" + "n for Assigned Names and Numbers','ICANN | Internet Corporation for A" + "ssigned Names and Numbers',NULL,NULL,X'3142756B572F774176695650417967" + "2B304A614A514B3452384A413D',X'C28810240A15687474703A2F2F7777772E69636" + "16E6E2E636F6D2F120B504E474158463041414646',X'C28810200A15687474703A2F" + "2F7777772E6963616E6E2E636F6D2F120744414146415346',NULL,X'22247FFFFFFF" + "FFF200003142756B572F7741766956504179672B304A614A514B3452384A413D',X'2" + "2247FFFFFFFFFF200003142756B572F7741766956504179672B304A614A514B345238" + "4A413D');" + "INSERT INTO 'metas' VALUES(14,692,692,11,0," + META_PROTO_TIMES_VALS(14) + ",'s_ID_14','s_ID_6','s_ID_6',0,0,0,0,0,0,'The WebKit Open Source Proj" + "ect','The WebKit Open Source Project',NULL,NULL,X'5A5678314E797636457" + "9524D3177494F7236563159552F6E644C553D',X'C288101A0A12687474703A2F2F77" + "65626B69742E6F72672F1204504E4758',X'C288101C0A13687474703A2F2F7765626" + "B69742E6F72672F781205504E473259',NULL,X'222480000000001000005A5678314" + "E7976364579524D3177494F7236563159552F6E644C553D',X'222480000000001000" + "005A5678314E7976364579524D3177494F7236563159552F6E644C553D');" + "CREATE TABLE deleted_metas (metahandle bigint primary key ON CONFLICT FA" + "IL,base_version bigint default -1,server_version bigint default 0,loc" + "al_external_id bigint default 0,transaction_version bigint default 0," + "mtime bigint default 0,server_mtime bigint default 0,ctime bigint def" + "ault 0,server_ctime bigint default 0,id varchar(255) default 'r',pare" + "nt_id varchar(255) default 'r',server_parent_id varchar(255) default " + "'r',is_unsynced bit default 0,is_unapplied_update bit default 0,is_de" + "l bit default 0,is_dir bit default 0,server_is_dir bit default 0,serv" + "er_is_del bit default 0,non_unique_name varchar,server_non_unique_nam" + "e varchar(255),unique_server_tag varchar,unique_client_tag varchar,un" + "ique_bookmark_tag varchar,specifics blob,server_specifics blob,base_s" + "erver_specifics blob,server_unique_position blob,unique_position blob" + ");" + "CREATE TABLE 'share_info' (id TEXT primary key, name TEXT, store_birthda" + "y TEXT, cache_guid TEXT, bag_of_chips BLOB);" + "INSERT INTO 'share_info' VALUES('nick@chromium.org','nick@chromium.org'," + "'c27e9f59-08ca-46f8-b0cc-f16a2ed778bb','9010788312004066376x-66092343" + "93368420856x',NULL);")); + // clang-format on + ASSERT_TRUE(connection->CommitTransaction()); +} + TEST_F(DirectoryBackingStoreTest, MigrateVersion67To68) { sql::Connection connection; ASSERT_TRUE(connection.OpenInMemory()); @@ -3682,6 +3796,28 @@ ASSERT_FALSE(dbs->needs_column_refresh()); } +TEST_F(DirectoryBackingStoreTest, MigrateVersion91To92) { + sql::Connection connection; + ASSERT_TRUE(connection.OpenInMemory()); + SetUpVersion91Database(&connection); + ASSERT_TRUE(connection.DoesColumnExist("metas", "attachment_metadata")); + ASSERT_TRUE( + connection.DoesColumnExist("metas", "server_attachment_metadata")); + + std::unique_ptr<TestDirectoryBackingStore> dbs( + new TestDirectoryBackingStore(GetUsername(), &connection)); + ASSERT_TRUE(dbs->MigrateVersion91To92()); + ASSERT_EQ(92, dbs->GetVersion()); + EXPECT_TRUE(dbs->needs_column_refresh()); + + ASSERT_TRUE(dbs->RefreshColumns()); + EXPECT_FALSE(dbs->needs_column_refresh()); + + ASSERT_FALSE(connection.DoesColumnExist("metas", "attachment_metadata")); + ASSERT_FALSE( + connection.DoesColumnExist("metas", "server_attachment_metadata")); +} + // The purpose of this test case is to make it easier to get a dump of the // database so you can implement a SetUpVersionYDatabase method. Here's what // you should do: @@ -3703,13 +3839,13 @@ { sql::Connection connection; ASSERT_TRUE(connection.Open(GetDatabasePath())); - SetUpVersion89Database(&connection); // Update this. + SetUpVersion91Database(&connection); // Update this. std::unique_ptr<TestDirectoryBackingStore> dbs( new TestDirectoryBackingStore(GetUsername(), &connection)); - ASSERT_TRUE(dbs->MigrateVersion90To91()); // Update this. + ASSERT_TRUE(dbs->MigrateVersion91To92()); // Update this. ASSERT_TRUE(LoadAndIgnoreReturnedData(dbs.get())); - EXPECT_EQ(91, dbs->GetVersion()); // Update this. + EXPECT_EQ(92, dbs->GetVersion()); // Update this. ASSERT_FALSE(dbs->needs_column_refresh()); } // Set breakpoint here. @@ -3840,6 +3976,9 @@ case 91: SetUpVersion91Database(&connection); break; + case 92: + SetUpVersion92Database(&connection); + break; default: // If you see this error, it may mean that you've increased the // database version number but you haven't finished adding unit tests @@ -3933,22 +4072,20 @@ ASSERT_FALSE(connection.DoesColumnExist("metas", "prev_id")); ASSERT_FALSE(connection.DoesColumnExist("metas", "server_ordinal_in_parent")); - // Column added in version 87. - ASSERT_TRUE(connection.DoesColumnExist("metas", "attachment_metadata")); - // Column added in version 88. ASSERT_TRUE(connection.DoesColumnExist("models", "context")); - // Column added in version 89. - ASSERT_TRUE( - connection.DoesColumnExist("metas", "server_attachment_metadata")); - // Columns removed in version 90. ASSERT_FALSE(connection.DoesColumnExist("share_info", "db_create_version")); ASSERT_FALSE(connection.DoesColumnExist("share_info", "db_create_time")); ASSERT_FALSE(connection.DoesColumnExist("share_info", "next_id")); ASSERT_FALSE(connection.DoesColumnExist("share_info", "notification_state")); + // Columns removed in version 92. + ASSERT_FALSE(connection.DoesColumnExist("metas", "attachment_metadata")); + ASSERT_FALSE( + connection.DoesColumnExist("metas", "server_attachment_metadata")); + // Check download_progress state (v75 migration) ASSERT_EQ(694, dir_info.kernel_info.download_progress[BOOKMARKS] @@ -3984,8 +4121,6 @@ EXPECT_FALSE(it->second->ref(UNIQUE_POSITION).IsValid()); EXPECT_FALSE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid()); EXPECT_TRUE(it->second->ref(UNIQUE_BOOKMARK_TAG).empty()); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); - EXPECT_TRUE(it->second->ref(SERVER_ATTACHMENT_METADATA).IsInitialized()); // Items 2, 4, and 5 were deleted. it = handles_map.find(2); @@ -4007,8 +4142,6 @@ EXPECT_TRUE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid()); EXPECT_EQ(UniquePosition::kSuffixLength, it->second->ref(UNIQUE_BOOKMARK_TAG).length()); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); - EXPECT_TRUE(it->second->ref(SERVER_ATTACHMENT_METADATA).IsInitialized()); it = handles_map.find(7); ASSERT_EQ(7, it->second->ref(META_HANDLE)); @@ -4019,8 +4152,6 @@ EXPECT_FALSE(it->second->ref(UNIQUE_POSITION).IsValid()); EXPECT_FALSE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid()); EXPECT_TRUE(it->second->ref(UNIQUE_BOOKMARK_TAG).empty()); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); - EXPECT_TRUE(it->second->ref(SERVER_ATTACHMENT_METADATA).IsInitialized()); it = handles_map.find(8); ASSERT_EQ(8, it->second->ref(META_HANDLE)); @@ -4032,8 +4163,6 @@ EXPECT_FALSE(it->second->ref(UNIQUE_POSITION).IsValid()); EXPECT_FALSE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid()); EXPECT_TRUE(it->second->ref(UNIQUE_BOOKMARK_TAG).empty()); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); - EXPECT_TRUE(it->second->ref(SERVER_ATTACHMENT_METADATA).IsInitialized()); it = handles_map.find(9); ASSERT_EQ(9, it->second->ref(META_HANDLE)); @@ -4044,8 +4173,6 @@ EXPECT_FALSE(it->second->ref(UNIQUE_POSITION).IsValid()); EXPECT_FALSE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid()); EXPECT_TRUE(it->second->ref(UNIQUE_BOOKMARK_TAG).empty()); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); - EXPECT_TRUE(it->second->ref(SERVER_ATTACHMENT_METADATA).IsInitialized()); it = handles_map.find(10); ASSERT_EQ(10, it->second->ref(META_HANDLE)); @@ -4060,14 +4187,10 @@ EXPECT_EQ("Other Bookmarks", it->second->ref(NON_UNIQUE_NAME)); EXPECT_EQ("Other Bookmarks", it->second->ref(SERVER_NON_UNIQUE_NAME)); ASSERT_EQ(it->second->ref(ID).value(), "s_ID_10"); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); - EXPECT_TRUE(it->second->ref(SERVER_ATTACHMENT_METADATA).IsInitialized()); // Make sure we didn't assign positions to server-created folders, either. EXPECT_FALSE(it->second->ref(UNIQUE_POSITION).IsValid()); EXPECT_FALSE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid()); EXPECT_TRUE(it->second->ref(UNIQUE_BOOKMARK_TAG).empty()); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); - EXPECT_TRUE(it->second->ref(SERVER_ATTACHMENT_METADATA).IsInitialized()); it = handles_map.find(11); ASSERT_EQ(11, it->second->ref(META_HANDLE)); @@ -4089,7 +4212,6 @@ EXPECT_TRUE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid()); EXPECT_EQ(UniquePosition::kSuffixLength, it->second->ref(UNIQUE_BOOKMARK_TAG).length()); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); it = handles_map.find(12); ASSERT_EQ(12, it->second->ref(META_HANDLE)); @@ -4107,8 +4229,6 @@ EXPECT_TRUE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid()); EXPECT_EQ(UniquePosition::kSuffixLength, it->second->ref(UNIQUE_BOOKMARK_TAG).length()); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); - EXPECT_TRUE(it->second->ref(SERVER_ATTACHMENT_METADATA).IsInitialized()); it = handles_map.find(13); ASSERT_EQ(13, it->second->ref(META_HANDLE)); @@ -4116,8 +4236,6 @@ EXPECT_TRUE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid()); EXPECT_EQ(UniquePosition::kSuffixLength, it->second->ref(UNIQUE_BOOKMARK_TAG).length()); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); - EXPECT_TRUE(it->second->ref(SERVER_ATTACHMENT_METADATA).IsInitialized()); it = handles_map.find(14); ASSERT_EQ(14, it->second->ref(META_HANDLE)); @@ -4125,8 +4243,6 @@ EXPECT_TRUE(it->second->ref(SERVER_UNIQUE_POSITION).IsValid()); EXPECT_EQ(UniquePosition::kSuffixLength, it->second->ref(UNIQUE_BOOKMARK_TAG).length()); - EXPECT_TRUE(it->second->ref(ATTACHMENT_METADATA).IsInitialized()); - EXPECT_TRUE(it->second->ref(SERVER_ATTACHMENT_METADATA).IsInitialized()); ASSERT_EQ(static_cast<size_t>(10), handles_map.size());
diff --git a/components/sync/syncable/entry.h b/components/sync/syncable/entry.h index 7669eba..352a06d 100644 --- a/components/sync/syncable/entry.h +++ b/components/sync/syncable/entry.h
@@ -206,16 +206,6 @@ return kernel_->ref(UNIQUE_POSITION); } - const sync_pb::AttachmentMetadata& GetAttachmentMetadata() const { - DCHECK(kernel_); - return kernel_->ref(ATTACHMENT_METADATA); - } - - const sync_pb::AttachmentMetadata& GetServerAttachmentMetadata() const { - DCHECK(kernel_); - return kernel_->ref(SERVER_ATTACHMENT_METADATA); - } - bool GetSyncing() const; bool GetDirtySync() const;
diff --git a/components/sync/syncable/entry_kernel.cc b/components/sync/syncable/entry_kernel.cc index e984a48..938b5ac0 100644 --- a/components/sync/syncable/entry_kernel.cc +++ b/components/sync/syncable/entry_kernel.cc
@@ -145,11 +145,6 @@ return std::make_unique<base::Value>(pos.ToDebugString()); } -std::unique_ptr<base::Value> AttachmentMetadataToValue( - const sync_pb::AttachmentMetadata& a) { - return std::make_unique<base::Value>(a.SerializeAsString()); -} - // Estimates memory usage of ProtoValuePtr<T> arrays where consecutive // elements can share the same value. template <class T, size_t N> @@ -216,11 +211,6 @@ &UniquePositionToValue, UNIQUE_POSITION_FIELDS_BEGIN, UNIQUE_POSITION_FIELDS_END - 1); - // AttachmentMetadata fields - SetFieldValues(*this, kernel_info.get(), &GetAttachmentMetadataFieldString, - &AttachmentMetadataToValue, ATTACHMENT_METADATA_FIELDS_BEGIN, - ATTACHMENT_METADATA_FIELDS_END - 1); - // Bit temps. SetFieldValues(*this, kernel_info.get(), &GetBitTempString, &BooleanToValue, BIT_TEMPS_BEGIN, BIT_TEMPS_END - 1); @@ -234,8 +224,7 @@ memory_usage_ = EstimateMemoryUsage(string_fields) + EstimateSharedMemoryUsage(specifics_fields) + EstimateMemoryUsage(id_fields) + - EstimateMemoryUsage(unique_position_fields) + - EstimateSharedMemoryUsage(attachment_metadata_fields); + EstimateMemoryUsage(unique_position_fields); } return memory_usage_; } @@ -292,13 +281,6 @@ << kernel->ref(static_cast<UniquePositionField>(i)).ToDebugString() << ", "; } - for (; i < ATTACHMENT_METADATA_FIELDS_END; ++i) { - std::string escaped_str = base::EscapeBytesAsInvalidJSONString( - kernel->ref(static_cast<AttachmentMetadataField>(i)) - .SerializeAsString(), - false); - os << g_metas_columns[i].name << ": " << escaped_str << ", "; - } os << "TempFlags: "; for (; i < BIT_TEMPS_END; ++i) { if (kernel->ref(static_cast<BitTemp>(i)))
diff --git a/components/sync/syncable/entry_kernel.h b/components/sync/syncable/entry_kernel.h index fbaac41..97e89bb 100644 --- a/components/sync/syncable/entry_kernel.h +++ b/components/sync/syncable/entry_kernel.h
@@ -20,7 +20,6 @@ #include "components/sync/base/proto_value_ptr.h" #include "components/sync/base/time.h" #include "components/sync/base/unique_position.h" -#include "components/sync/protocol/attachments.pb.h" #include "components/sync/protocol/sync.pb.h" #include "components/sync/syncable/metahandle_set.h" #include "components/sync/syncable/syncable_id.h" @@ -161,23 +160,14 @@ enum { UNIQUE_POSITION_FIELDS_COUNT = - UNIQUE_POSITION_FIELDS_END - UNIQUE_POSITION_FIELDS_BEGIN, - ATTACHMENT_METADATA_FIELDS_BEGIN = UNIQUE_POSITION_FIELDS_END -}; - -enum AttachmentMetadataField { - ATTACHMENT_METADATA = ATTACHMENT_METADATA_FIELDS_BEGIN, - SERVER_ATTACHMENT_METADATA, - ATTACHMENT_METADATA_FIELDS_END + UNIQUE_POSITION_FIELDS_END - UNIQUE_POSITION_FIELDS_BEGIN }; enum { - ATTACHMENT_METADATA_FIELDS_COUNT = - ATTACHMENT_METADATA_FIELDS_END - ATTACHMENT_METADATA_FIELDS_BEGIN, // If FIELD_COUNT is changed then g_metas_columns must be updated. - FIELD_COUNT = ATTACHMENT_METADATA_FIELDS_END - BEGIN_FIELDS, + FIELD_COUNT = UNIQUE_POSITION_FIELDS_END - BEGIN_FIELDS, // Past this point we have temporaries, stored in memory only. - BEGIN_TEMPS = ATTACHMENT_METADATA_FIELDS_END, + BEGIN_TEMPS = UNIQUE_POSITION_FIELDS_END, BIT_TEMPS_BEGIN = BEGIN_TEMPS, }; @@ -197,7 +187,6 @@ struct EntryKernel { private: using EntitySpecificsPtr = ProtoValuePtr<sync_pb::EntitySpecifics>; - using AttachmentMetadataPtr = ProtoValuePtr<sync_pb::AttachmentMetadata>; std::string string_fields[STRING_FIELDS_COUNT]; EntitySpecificsPtr specifics_fields[PROTO_FIELDS_COUNT]; @@ -205,8 +194,6 @@ base::Time time_fields[TIME_FIELDS_COUNT]; Id id_fields[ID_FIELDS_COUNT]; UniquePosition unique_position_fields[UNIQUE_POSITION_FIELDS_COUNT]; - AttachmentMetadataPtr - attachment_metadata_fields[ATTACHMENT_METADATA_FIELDS_COUNT]; std::bitset<BIT_FIELDS_COUNT> bit_fields; std::bitset<BIT_TEMPS_COUNT> bit_temps; @@ -279,11 +266,6 @@ inline void put(UniquePositionField field, const UniquePosition& value) { unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN] = value; } - inline void put(AttachmentMetadataField field, - const sync_pb::AttachmentMetadata& value) { - attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN] - .set_value(value); - } inline void put(BitTemp field, bool value) { bit_temps[field - BIT_TEMPS_BEGIN] = value; } @@ -322,11 +304,6 @@ inline const UniquePosition& ref(UniquePositionField field) const { return unique_position_fields[field - UNIQUE_POSITION_FIELDS_BEGIN]; } - inline const sync_pb::AttachmentMetadata& ref( - AttachmentMetadataField field) const { - return attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN] - .value(); - } inline bool ref(BitTemp field) const { return bit_temps[field - BIT_TEMPS_BEGIN]; } @@ -347,13 +324,6 @@ specifics_fields[field - PROTO_FIELDS_BEGIN].load(blob, length); } - inline void load(AttachmentMetadataField field, - const void* blob, - int length) { - attachment_metadata_fields[field - ATTACHMENT_METADATA_FIELDS_BEGIN].load( - blob, length); - } - // Sharing data methods for ::google::protobuf::MessageLite derived types. inline void copy(ProtoField src, ProtoField dest) { DCHECK_NE(src, dest); @@ -361,12 +331,6 @@ specifics_fields[src - PROTO_FIELDS_BEGIN]; } - inline void copy(AttachmentMetadataField src, AttachmentMetadataField dest) { - DCHECK_NE(src, dest); - attachment_metadata_fields[dest - ATTACHMENT_METADATA_FIELDS_BEGIN] = - attachment_metadata_fields[src - ATTACHMENT_METADATA_FIELDS_BEGIN]; - } - ModelType GetModelType() const; ModelType GetServerModelType() const; bool ShouldMaintainPosition() const;
diff --git a/components/sync/syncable/syncable_enum_conversions.cc b/components/sync/syncable/syncable_enum_conversions.cc index db64a81..4bd65df 100644 --- a/components/sync/syncable/syncable_enum_conversions.cc +++ b/components/sync/syncable/syncable_enum_conversions.cc
@@ -156,21 +156,6 @@ return ""; } -const char* GetAttachmentMetadataFieldString( - AttachmentMetadataField attachment_metadata_field) { - ASSERT_ENUM_BOUNDS(ATTACHMENT_METADATA, SERVER_ATTACHMENT_METADATA, - ATTACHMENT_METADATA_FIELDS_BEGIN, - ATTACHMENT_METADATA_FIELDS_END - 1); - switch (attachment_metadata_field) { - ENUM_CASE(ATTACHMENT_METADATA); - ENUM_CASE(SERVER_ATTACHMENT_METADATA); - case ATTACHMENT_METADATA_FIELDS_END: - break; - } - NOTREACHED(); - return ""; -} - const char* GetBitTempString(BitTemp bit_temp) { ASSERT_ENUM_BOUNDS(SYNCING, DIRTY_SYNC, BIT_TEMPS_BEGIN, BIT_TEMPS_END - 1); switch (bit_temp) {
diff --git a/components/sync/syncable/syncable_enum_conversions.h b/components/sync/syncable/syncable_enum_conversions.h index 49e288c1..365ab5f 100644 --- a/components/sync/syncable/syncable_enum_conversions.h +++ b/components/sync/syncable/syncable_enum_conversions.h
@@ -40,9 +40,6 @@ const char* GetUniquePositionFieldString(UniquePositionField position_field); -const char* GetAttachmentMetadataFieldString( - AttachmentMetadataField attachment_metadata_field); - const char* GetBitTempString(BitTemp bit_temp); } // namespace syncable
diff --git a/components/sync/syncable/syncable_enum_conversions_unittest.cc b/components/sync/syncable/syncable_enum_conversions_unittest.cc index 3711a13..f439197 100644 --- a/components/sync/syncable/syncable_enum_conversions_unittest.cc +++ b/components/sync/syncable/syncable_enum_conversions_unittest.cc
@@ -78,12 +78,6 @@ UNIQUE_POSITION_FIELDS_END - 1); } -TEST_F(SyncableEnumConversionsTest, GetAttachmentMetadataFieldString) { - TestEnumStringFunction(GetAttachmentMetadataFieldString, - ATTACHMENT_METADATA_FIELDS_BEGIN, - ATTACHMENT_METADATA_FIELDS_END - 1); -} - TEST_F(SyncableEnumConversionsTest, GetBitTempString) { TestEnumStringFunction(GetBitTempString, BIT_TEMPS_BEGIN, BIT_TEMPS_END - 1); }
diff --git a/components/sync/test/engine/mock_connection_manager.cc b/components/sync/test/engine/mock_connection_manager.cc index 02e29ba..753f89b 100644 --- a/components/sync/test/engine/mock_connection_manager.cc +++ b/components/sync/test/engine/mock_connection_manager.cc
@@ -547,8 +547,7 @@ EXPECT_FALSE(gu.has_requested_types()); if (fail_non_periodic_get_updates_) { - EXPECT_EQ(sync_pb::GetUpdatesCallerInfo::PERIODIC, - gu.caller_info().source()); + EXPECT_EQ(sync_pb::SyncEnums::PERIODIC, gu.get_updates_origin()); } // Verify that the items we're about to send back to the client are of
diff --git a/components/sync/test/test_directory_backing_store.h b/components/sync/test/test_directory_backing_store.h index e275080..0cf23ec 100644 --- a/components/sync/test/test_directory_backing_store.h +++ b/components/sync/test/test_directory_backing_store.h
@@ -56,6 +56,7 @@ FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion88To89); FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion89To90); FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion90To91); + FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, MigrateVersion91To92); FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, DetectInvalidPosition); FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, ModelTypeIds); FRIEND_TEST_ALL_PREFIXES(DirectoryBackingStoreTest, Corruption);
diff --git a/components/sync/tools/testserver/chromiumsync.py b/components/sync/tools/testserver/chromiumsync.py index e6f1991..fe1c0ff 100644 --- a/components/sync/tools/testserver/chromiumsync.py +++ b/components/sync/tools/testserver/chromiumsync.py
@@ -33,7 +33,6 @@ import bookmark_specifics_pb2 import client_commands_pb2 import dictionary_specifics_pb2 -import get_updates_caller_info_pb2 import extension_setting_specifics_pb2 import extension_specifics_pb2 import favicon_image_specifics_pb2 @@ -302,11 +301,10 @@ return SYNC_TYPE_TO_DESCRIPTOR[data_type].name -def CallerInfoToString(caller_info_source): - """Formats a GetUpdatesSource enum value to a readable string.""" - return get_updates_caller_info_pb2.GetUpdatesCallerInfo \ - .DESCRIPTOR.enum_types_by_name['GetUpdatesSource'] \ - .values_by_number[caller_info_source].name +def GetUpdatesOriginToString(origin): + """Formats a GetUpdatesOrigin enum value to a readable string.""" + return sync_enums_pb2.SyncEnums.DESCRIPTOR \ + .enum_types_by_name['GetUpdatesOrigin'].values_by_number[origin].name def ShortDatatypeListSummary(data_types): @@ -1581,7 +1579,7 @@ update_response.SetInParent() update_sieve = UpdateSieve(update_request, self.account.migration_history) - print CallerInfoToString(update_request.caller_info.source), + print GetUpdatesOriginToString(update_request.get_updates_origin), print update_sieve.SummarizeRequest() update_sieve.CheckMigrationState()
diff --git a/components/sync_sessions/local_session_event_handler_impl.cc b/components/sync_sessions/local_session_event_handler_impl.cc index 01e5e84..cce4816 100644 --- a/components/sync_sessions/local_session_event_handler_impl.cc +++ b/components/sync_sessions/local_session_event_handler_impl.cc
@@ -13,7 +13,6 @@ #include "base/strings/stringprintf.h" #include "components/sync/model/sync_change.h" #include "components/sync/protocol/sync.pb.h" -#include "components/sync_sessions/sessions_global_id_mapper.h" #include "components/sync_sessions/sync_sessions_client.h" #include "components/sync_sessions/synced_session_tracker.h" #include "components/sync_sessions/synced_tab_delegate.h" @@ -105,36 +104,24 @@ LocalSessionEventHandlerImpl::LocalSessionEventHandlerImpl( Delegate* delegate, SyncSessionsClient* sessions_client, - SyncedSessionTracker* session_tracker) + SyncedSessionTracker* session_tracker, + WriteBatch* initial_batch) : delegate_(delegate), sessions_client_(sessions_client), session_tracker_(session_tracker) { DCHECK(delegate); DCHECK(sessions_client); DCHECK(session_tracker); + DCHECK(initial_batch); + + current_session_tag_ = session_tracker_->GetLocalSessionTag(); + DCHECK(!current_session_tag_.empty()); + + AssociateWindows(RELOAD_TABS, ScanForTabbedWindow(), initial_batch); } LocalSessionEventHandlerImpl::~LocalSessionEventHandlerImpl() {} -void LocalSessionEventHandlerImpl::AssociateWindowsAndTabs( - const std::string& session_tag, - const std::string& session_name, - sync_pb::SyncEnums::DeviceType device_type, - WriteBatch* change_output) { - SyncedSession* current_session = session_tracker_->GetSession(session_tag); - current_session->session_name = session_name; - current_session->device_type = device_type; - current_session->session_tag = session_tag; - - current_session_tag_ = session_tag; - - AssociateWindows(RELOAD_TABS, ScanForTabbedWindow(), change_output); -} - -SessionsGlobalIdMapper* LocalSessionEventHandlerImpl::GetGlobalIdMapper() { - return &global_id_mapper_; -} - void LocalSessionEventHandlerImpl::SetSessionTabFromDelegateForTest( const SyncedTabDelegate& tab_delegate, base::Time mtime, @@ -144,7 +131,7 @@ void LocalSessionEventHandlerImpl::AssociateWindows(ReloadTabsOption option, bool has_tabbed_window, - WriteBatch* change_output) { + WriteBatch* batch) { // Note that |current_session| is a pointer owned by |session_tracker_|. // |session_tracker_| will continue to update |current_session| under // the hood so care must be taken accessing it. In particular, invoking @@ -190,7 +177,7 @@ } DVLOG(1) << "Rewriting tab node " << sync_id << " with tab id " << tab->tab_id.id(); - AppendChangeForExistingTab(sync_id, *tab, change_output); + AppendChangeForExistingTab(sync_id, *tab, batch); } } } @@ -253,12 +240,12 @@ // as it could have changed after a session restore. if (synced_tab->GetSyncId() > TabNodePool::kInvalidTabNodeID) { AssociateRestoredPlaceholderTab(*synced_tab, tab_id, window_id, - change_output); + batch); } else { DVLOG(1) << "Placeholder tab " << tab_id << " has no sync id."; } } else if (RELOAD_TABS == option) { - AssociateTab(synced_tab, has_tabbed_window, change_output); + AssociateTab(synced_tab, has_tabbed_window, batch); } // If the tab was syncable, it would have been added to the tracker @@ -302,7 +289,7 @@ std::set<int> deleted_tab_node_ids; session_tracker_->CleanupLocalTabs(&deleted_tab_node_ids); for (int tab_node_id : deleted_tab_node_ids) { - change_output->Delete(tab_node_id); + batch->Delete(tab_node_id); } // Always update the header. Sync takes care of dropping this update @@ -311,13 +298,13 @@ auto specifics = std::make_unique<sync_pb::SessionSpecifics>(); specifics->set_session_tag(current_session_tag_); current_session->ToSessionHeaderProto().Swap(specifics->mutable_header()); - change_output->Update(std::move(specifics)); + batch->Update(std::move(specifics)); } void LocalSessionEventHandlerImpl::AssociateTab( SyncedTabDelegate* const tab_delegate, bool has_tabbed_window, - WriteBatch* change_output) { + WriteBatch* batch) { DCHECK(!tab_delegate->IsPlaceholderTab()); if (tab_delegate->IsBeingDestroyed()) { @@ -379,9 +366,9 @@ .Swap(specifics.get()); WriteTasksIntoSpecifics(specifics->mutable_tab()); if (existing_tab_node) { - change_output->Update(std::move(specifics)); + batch->Update(std::move(specifics)); } else { - change_output->Add(std::move(specifics)); + batch->Add(std::move(specifics)); } int current_index = tab_delegate->GetCurrentEntryIndex(); @@ -446,8 +433,7 @@ sessions::SerializedNavigationEntry current; modified_tab->GetSerializedNavigationAtIndex( modified_tab->GetCurrentEntryIndex(), ¤t); - global_id_mapper_.TrackNavigationIds(current.timestamp(), - current.unique_id()); + delegate_->TrackLocalNavigationId(current.timestamp(), current.unique_id()); bool found_tabbed_window = ScanForTabbedWindow(); std::unique_ptr<WriteBatch> batch = delegate_->CreateLocalSessionWriteBatch(); @@ -474,7 +460,7 @@ const SyncedTabDelegate& tab_delegate, SessionID::id_type new_tab_id, SessionID::id_type new_window_id, - WriteBatch* change_output) { + WriteBatch* batch) { DCHECK_NE(tab_delegate.GetSyncId(), TabNodePool::kInvalidTabNodeID); // It's possible the placeholder tab is associated with a tab node that's @@ -495,20 +481,19 @@ session_tracker_->GetTab(current_session_tag_, new_tab_id); local_tab->window_id.set_id(new_window_id); - AppendChangeForExistingTab(tab_delegate.GetSyncId(), *local_tab, - change_output); + AppendChangeForExistingTab(tab_delegate.GetSyncId(), *local_tab, batch); } void LocalSessionEventHandlerImpl::AppendChangeForExistingTab( int sync_id, const sessions::SessionTab& tab, - WriteBatch* change_output) const { + WriteBatch* batch) const { // Rewrite the specifics based on the reassociated SessionTab to preserve // the new tab and window ids. auto specifics = std::make_unique<sync_pb::SessionSpecifics>(); SessionTabToSpecifics(tab, current_session_tag_, sync_id) .Swap(specifics.get()); - change_output->Update(std::move(specifics)); + batch->Update(std::move(specifics)); } void LocalSessionEventHandlerImpl::SetSessionTabFromDelegate(
diff --git a/components/sync_sessions/local_session_event_handler_impl.h b/components/sync_sessions/local_session_event_handler_impl.h index 95346b1..3f03490 100644 --- a/components/sync_sessions/local_session_event_handler_impl.h +++ b/components/sync_sessions/local_session_event_handler_impl.h
@@ -14,7 +14,6 @@ #include "components/sessions/core/session_id.h" #include "components/sessions/core/session_types.h" #include "components/sync_sessions/local_session_event_router.h" -#include "components/sync_sessions/sessions_global_id_mapper.h" #include "components/sync_sessions/synced_session.h" #include "components/sync_sessions/task_tracker.h" @@ -51,33 +50,26 @@ public: virtual ~Delegate(); virtual std::unique_ptr<WriteBatch> CreateLocalSessionWriteBatch() = 0; + // Analogous to SessionsGlobalIdMapper. + virtual void TrackLocalNavigationId(base::Time timestamp, + int unique_id) = 0; // Analogous to the functions in FaviconCache. virtual void OnPageFaviconUpdated(const GURL& page_url) = 0; virtual void OnFaviconVisited(const GURL& page_url, const GURL& favicon_url) = 0; }; + // Raw pointers must not be null and all pointees except |*initial_batch| must + // outlive this object. |*initial_batch| may or may not be initially empty + // (depending on whether the caller wants to bundle together other writes). + // This constructor populates |*initial_batch| to resync local window and tab + // information, but does *not* Commit() the batch. LocalSessionEventHandlerImpl(Delegate* delegate, SyncSessionsClient* sessions_client, - SyncedSessionTracker* session_tracker); + SyncedSessionTracker* session_tracker, + WriteBatch* initial_batch); ~LocalSessionEventHandlerImpl() override; - SessionsGlobalIdMapper* GetGlobalIdMapper(); - - // Resync local window and tab information. Updates the local sessions header - // node with the status of open windows and the order of tabs they contain. - // |change_output| must not be nullptr. - // - // Must be called before routing events to this class (typically a call to - // the router's StartRoutingTo()), that is, before using this object as - // LocalSessionEventHandler. - // TODO(crbug.com/681921): Revisit if this function can be merged with the - // constructor, since it's essentially a two-step initialization. - void AssociateWindowsAndTabs(const std::string& session_tag, - const std::string& session_name, - sync_pb::SyncEnums::DeviceType device_type, - WriteBatch* change_output); - // LocalSessionEventHandler implementation. void OnLocalTabModified(SyncedTabDelegate* modified_tab) override; void OnFaviconsChanged(const std::set<GURL>& page_urls, @@ -93,16 +85,15 @@ enum ReloadTabsOption { RELOAD_TABS, DONT_RELOAD_TABS }; void AssociateWindows(ReloadTabsOption option, bool has_tabbed_window, - WriteBatch* change_output); + WriteBatch* batch); // Loads and reassociates the local tab referenced in |tab|. - // |change_output| *must* be provided as a link to the SyncChange pipeline - // that exists in the caller's context. This function will append necessary + // |batch| must not be null. This function will append necessary // changes for processing later. Will only assign a new sync id if there is // a tabbed window, which results in failure for tabs without sync ids yet. void AssociateTab(SyncedTabDelegate* const tab, bool has_tabbed_window, - WriteBatch* change_output); + WriteBatch* batch); // It's possible that when we associate windows, tabs aren't all loaded // into memory yet (e.g on android) and we don't have a WebContents. In this @@ -113,13 +104,13 @@ void AssociateRestoredPlaceholderTab(const SyncedTabDelegate& tab_delegate, SessionID::id_type new_tab_id, SessionID::id_type new_window_id, - WriteBatch* change_output); + WriteBatch* batch); - // Appends an ACTION_UPDATE for a sync tab entity onto |change_output| to + // Appends an ACTION_UPDATE for a sync tab entity onto |batch| to // reflect the contents of |tab|, given the tab node id |sync_id|. void AppendChangeForExistingTab(int sync_id, const sessions::SessionTab& tab, - WriteBatch* change_output) const; + WriteBatch* batch) const; // Set |session_tab| from |tab_delegate| and |mtime|. void SetSessionTabFromDelegate(const SyncedTabDelegate& tab_delegate, @@ -143,8 +134,6 @@ SyncSessionsClient* const sessions_client_; SyncedSessionTracker* const session_tracker_; - SessionsGlobalIdMapper global_id_mapper_; - // Tracks Chrome Tasks, which associates navigations, with tab and navigation // changes of current session. TaskTracker task_tracker_;
diff --git a/components/sync_sessions/local_session_event_handler_impl_unittest.cc b/components/sync_sessions/local_session_event_handler_impl_unittest.cc index 63e60be..80defe3 100644 --- a/components/sync_sessions/local_session_event_handler_impl_unittest.cc +++ b/components/sync_sessions/local_session_event_handler_impl_unittest.cc
@@ -150,6 +150,8 @@ MOCK_METHOD0(CreateLocalSessionWriteBatch, std::unique_ptr<LocalSessionEventHandlerImpl::WriteBatch>()); + MOCK_METHOD2(TrackLocalNavigationId, + void(base::Time timestamp, int unique_id)); MOCK_METHOD1(OnPageFaviconUpdated, void(const GURL& page_url)); MOCK_METHOD2(OnFaviconVisited, void(const GURL& page_url, const GURL& favicon_url)); @@ -158,14 +160,24 @@ class LocalSessionEventHandlerImplTest : public testing::Test { public: LocalSessionEventHandlerImplTest() - : session_tracker_(&mock_sync_sessions_client_), - handler_(&mock_delegate_, - &mock_sync_sessions_client_, - &session_tracker_) { + : session_tracker_(&mock_sync_sessions_client_) { ON_CALL(mock_sync_sessions_client_, GetSyncedWindowDelegatesGetter()) .WillByDefault(testing::Return(&window_getter_)); - session_tracker_.SetLocalSessionTag(kSessionTag); + session_tracker_.InitLocalSession(kSessionTag, kSessionName, + sync_pb::SyncEnums_DeviceType_TYPE_PHONE); + } + + void InitHandler(LocalSessionEventHandlerImpl::WriteBatch* initial_batch) { + handler_ = std::make_unique<LocalSessionEventHandlerImpl>( + &mock_delegate_, &mock_sync_sessions_client_, &session_tracker_, + initial_batch); + window_getter_.router()->StartRoutingTo(handler_.get()); + } + + void InitHandler() { + NiceMock<MockWriteBatch> initial_batch; + InitHandler(&initial_batch); } TestSyncedWindowDelegate* AddWindow( @@ -194,7 +206,7 @@ testing::NiceMock<MockSyncSessionsClient> mock_sync_sessions_client_; SyncedSessionTracker session_tracker_; TestSyncedWindowDelegatesGetter window_getter_; - LocalSessionEventHandlerImpl handler_; + std::unique_ptr<LocalSessionEventHandlerImpl> handler_; }; // Populate the mock tab delegate with some data and navigation @@ -220,7 +232,9 @@ SerializedNavigationEntryTestHelper::CreateNavigation( "http://www.example.com", "Example")); session_tab.session_storage_persistent_id = "persistent id"; - handler_.SetSessionTabFromDelegateForTest(*tab, kTime4, &session_tab); + + InitHandler(); + handler_->SetSessionTabFromDelegateForTest(*tab, kTime4, &session_tab); EXPECT_EQ(tab->GetWindowId(), session_tab.window_id.id()); EXPECT_EQ(tab->GetSessionId(), session_tab.tab_id.id()); @@ -260,8 +274,10 @@ } tab->set_current_entry_index(kNavs - 2); + InitHandler(); + sessions::SessionTab session_tab; - handler_.SetSessionTabFromDelegateForTest(*tab, kTime6, &session_tab); + handler_->SetSessionTabFromDelegateForTest(*tab, kTime6, &session_tab); EXPECT_EQ(6, session_tab.current_navigation_index); ASSERT_EQ(8u, session_tab.navigations.size()); @@ -281,8 +297,10 @@ tab->Navigate(kBar2, kTime3); tab->set_current_entry_index(1); + InitHandler(); + sessions::SessionTab session_tab; - handler_.SetSessionTabFromDelegateForTest(*tab, kTime6, &session_tab); + handler_->SetSessionTabFromDelegateForTest(*tab, kTime6, &session_tab); EXPECT_EQ(2, session_tab.current_navigation_index); ASSERT_EQ(3u, session_tab.navigations.size()); @@ -325,7 +343,9 @@ SerializedNavigationEntryTestHelper::CreateNavigation( "http://www.example.com", "Example")); session_tab.session_storage_persistent_id = "persistent id"; - handler_.SetSessionTabFromDelegateForTest(*tab, kTime4, &session_tab); + + InitHandler(); + handler_->SetSessionTabFromDelegateForTest(*tab, kTime4, &session_tab); EXPECT_EQ(tab->GetWindowId(), session_tab.window_id.id()); EXPECT_EQ(tab->GetSessionId(), session_tab.tab_id.id()); @@ -362,9 +382,7 @@ EXPECT_CALL(mock_batch, DoUpdate(MatchesHeader(kSessionTag, /*num_windows=*/0, /*num_tabs=*/0))); - handler_.AssociateWindowsAndTabs(kSessionTag, kSessionName, - sync_pb::SyncEnums_DeviceType_TYPE_PHONE, - &mock_batch); + InitHandler(&mock_batch); } // Tests that calling AssociateWindowsAndTabs() reflects the open tabs in a) the @@ -395,20 +413,14 @@ DoAdd(MatchesTab(kSessionTag, kWindowId2, kTabId3, std::vector<std::string>{kBar2, kBaz1}))); - handler_.AssociateWindowsAndTabs(kSessionTag, kSessionName, - sync_pb::SyncEnums_DeviceType_TYPE_PHONE, - &mock_batch); + InitHandler(&mock_batch); } TEST_F(LocalSessionEventHandlerImplTest, PropagateNewNavigation) { AddWindow(kWindowId1); TestSyncedTabDelegate* tab = AddTab(kWindowId1, kFoo1, kTabId1); - NiceMock<MockWriteBatch> initial_mock_batch; - handler_.AssociateWindowsAndTabs(kSessionTag, kSessionName, - sync_pb::SyncEnums_DeviceType_TYPE_PHONE, - &initial_mock_batch); - window_getter_.router()->StartRoutingTo(&handler_); + InitHandler(); auto update_mock_batch = std::make_unique<StrictMock<MockWriteBatch>>(); // Note that the header is reported again, although it hasn't changed. This is @@ -431,11 +443,7 @@ AddWindow(kWindowId1); AddTab(kWindowId1, kFoo1, kTabId1); - NiceMock<MockWriteBatch> initial_mock_batch; - handler_.AssociateWindowsAndTabs(kSessionTag, kSessionName, - sync_pb::SyncEnums_DeviceType_TYPE_PHONE, - &initial_mock_batch); - window_getter_.router()->StartRoutingTo(&handler_); + InitHandler(); // Tab creation triggers an update event due to the tab parented notification, // so the event handler issues two commits as well (one for tab creation, one @@ -468,11 +476,7 @@ AddTab(kWindowId1, kFoo1, kTabId1); AddTab(kWindowId1, kBar1, kTabId2); - NiceMock<MockWriteBatch> initial_mock_batch; - handler_.AssociateWindowsAndTabs(kSessionTag, kSessionName, - sync_pb::SyncEnums_DeviceType_TYPE_PHONE, - &initial_mock_batch); - window_getter_.router()->StartRoutingTo(&handler_); + InitHandler(); // Window creation triggers an update event due to the tab parented // notification, so the event handler issues two commits as well (one for
diff --git a/components/sync_sessions/sessions_global_id_mapper.cc b/components/sync_sessions/sessions_global_id_mapper.cc index 3b467ed6..6eff6b8 100644 --- a/components/sync_sessions/sessions_global_id_mapper.cc +++ b/components/sync_sessions/sessions_global_id_mapper.cc
@@ -48,8 +48,8 @@ return global_id; } -void SessionsGlobalIdMapper::TrackNavigationIds(const base::Time& timestamp, - int unique_id) { +void SessionsGlobalIdMapper::TrackNavigationId(const base::Time& timestamp, + int unique_id) { // The expectation is that global_id will update for a given unique_id, which // should accurately and uniquely represent a single navigation. It is // theoretically possible for two unique_ids to map to the same global_id, but
diff --git a/components/sync_sessions/sessions_global_id_mapper.h b/components/sync_sessions/sessions_global_id_mapper.h index 907cca3..58b5b391 100644 --- a/components/sync_sessions/sessions_global_id_mapper.h +++ b/components/sync_sessions/sessions_global_id_mapper.h
@@ -23,7 +23,7 @@ void AddGlobalIdChangeObserver(syncer::GlobalIdChange callback) override; int64_t GetLatestGlobalId(int64_t global_id) override; - void TrackNavigationIds(const base::Time& timestamp, int unique_id); + void TrackNavigationId(const base::Time& timestamp, int unique_id); private: void CleanupNavigationTracking();
diff --git a/components/sync_sessions/sessions_global_id_mapper_unittest.cc b/components/sync_sessions/sessions_global_id_mapper_unittest.cc index 566b32c..23fa251 100644 --- a/components/sync_sessions/sessions_global_id_mapper_unittest.cc +++ b/components/sync_sessions/sessions_global_id_mapper_unittest.cc
@@ -23,10 +23,10 @@ TEST(SessionsGlobalIdMapperTest, GetLatestGlobalId) { SessionsGlobalIdMapper mapper; - mapper.TrackNavigationIds(kTime1, /*unique_id=*/1); - mapper.TrackNavigationIds(kTime2, /*unique_id=*/2); - mapper.TrackNavigationIds(kTime3, /*unique_id=*/2); - mapper.TrackNavigationIds(kTime4, /*unique_id=*/2); + mapper.TrackNavigationId(kTime1, /*unique_id=*/1); + mapper.TrackNavigationId(kTime2, /*unique_id=*/2); + mapper.TrackNavigationId(kTime3, /*unique_id=*/2); + mapper.TrackNavigationId(kTime4, /*unique_id=*/2); EXPECT_EQ(kTime1.ToInternalValue(), mapper.GetLatestGlobalId(kTime1.ToInternalValue())); @@ -47,12 +47,12 @@ SessionsGlobalIdMapper mapper; base::Time current_time = kTime1; - mapper.TrackNavigationIds(current_time, /*unique_id=*/1); + mapper.TrackNavigationId(current_time, /*unique_id=*/1); for (int i = 0; i < 105; i++) { current_time = base::Time::FromInternalValue(current_time.ToInternalValue() + 1); - mapper.TrackNavigationIds(current_time, /*unique_id=*/1); + mapper.TrackNavigationId(current_time, /*unique_id=*/1); } // Threshold is 100, kTime1 should be dropped, kTime1+10 should not. @@ -67,7 +67,7 @@ TEST(SessionsGlobalIdMapperTest, AddObserver) { SessionsGlobalIdMapper mapper; - mapper.TrackNavigationIds(kTime1, /*unique_id=*/1); + mapper.TrackNavigationId(kTime1, /*unique_id=*/1); base::MockCallback<syncer::GlobalIdChange> mock_callback; EXPECT_CALL(mock_callback, Run(_, _)).Times(0);
diff --git a/components/sync_sessions/sessions_sync_manager.cc b/components/sync_sessions/sessions_sync_manager.cc index 144fe07..13727dc8d 100644 --- a/components/sync_sessions/sessions_sync_manager.cc +++ b/components/sync_sessions/sessions_sync_manager.cc
@@ -150,13 +150,9 @@ &favicon_cache_, base::BindRepeating(&SessionsSyncManager::DeleteForeignSessionFromUI, base::Unretained(this))), - local_session_event_handler_(/*delegate=*/this, - sessions_client, - &session_tracker_), local_tab_pool_out_of_sync_(true), sync_prefs_(sync_prefs), local_device_(local_device), - current_device_type_(sync_pb::SyncEnums_DeviceType_TYPE_OTHER), local_session_header_node_id_(TabNodePool::kInvalidTabNodeID), stale_session_threshold_days_(kDefaultStaleSessionThresholdDays), local_event_router_(router), @@ -179,6 +175,7 @@ std::unique_ptr<syncer::SyncErrorFactory> error_handler) { syncer::SyncMergeResult merge_result(type); DCHECK(session_tracker_.Empty()); + DCHECK(!local_session_event_handler_); error_handler_ = std::move(error_handler); sync_processor_ = std::move(sync_processor); @@ -194,7 +191,6 @@ } current_session_name_ = local_device_info->client_name(); - current_device_type_ = local_device_info->device_type(); // It's possible(via RebuildAssociations) for lost_navigations_recorder_ to // persist between sync being stopped and started. If it did persist, it's @@ -214,7 +210,8 @@ InitializeCurrentMachineTag(local_device_->GetLocalSyncCacheGUID()); } - session_tracker_.SetLocalSessionTag(current_machine_tag()); + session_tracker_.InitLocalSession(current_machine_tag_, current_session_name_, + local_device_info->device_type()); // TODO(crbug.com/681921): Revisit the somewhat ugly use below of // SyncChangeListWriteBatch. Ideally InitFromSyncModel() could use the @@ -229,7 +226,7 @@ specifics->set_session_tag(current_machine_tag()); sync_pb::SessionHeader* header_s = specifics->mutable_header(); header_s->set_client_name(current_session_name_); - header_s->set_device_type(current_device_type_); + header_s->set_device_type(local_device_info->device_type()); batch.Add(std::move(specifics)); } @@ -241,15 +238,14 @@ #endif // Check if anything has changed on the local client side. - local_session_event_handler_.AssociateWindowsAndTabs( - current_machine_tag_, current_session_name_, current_device_type_, - &batch); + local_session_event_handler_ = std::make_unique<LocalSessionEventHandlerImpl>( + /*delegate=*/this, sessions_client_, &session_tracker_, &batch); local_tab_pool_out_of_sync_ = false; merge_result.set_error(sync_processor_->ProcessSyncChanges( FROM_HERE, *batch.sync_change_list())); - local_event_router_->StartRoutingTo(&local_session_event_handler_); + local_event_router_->StartRoutingTo(local_session_event_handler_.get()); return merge_result; } @@ -268,6 +264,7 @@ void SessionsSyncManager::StopSyncing(syncer::ModelType type) { local_event_router_->Stop(); + local_session_event_handler_.reset(); if (sync_processor_.get() && lost_navigations_recorder_.get()) { sync_processor_->RemoveLocalChangeObserver( lost_navigations_recorder_.get()); @@ -604,6 +601,11 @@ base::AsWeakPtr(this))); } +void SessionsSyncManager::TrackLocalNavigationId(base::Time timestamp, + int unique_id) { + global_id_mapper_.TrackNavigationId(timestamp, unique_id); +} + void SessionsSyncManager::OnPageFaviconUpdated(const GURL& page_url) { favicon_cache_.OnPageFaviconUpdated(page_url, base::Time::Now()); } @@ -618,7 +620,7 @@ } SessionsGlobalIdMapper* SessionsSyncManager::GetGlobalIdMapper() { - return local_session_event_handler_.GetGlobalIdMapper(); + return &global_id_mapper_; } OpenTabsUIDelegate* SessionsSyncManager::GetOpenTabsUIDelegate() {
diff --git a/components/sync_sessions/sessions_sync_manager.h b/components/sync_sessions/sessions_sync_manager.h index 94929cf..5c4377b 100644 --- a/components/sync_sessions/sessions_sync_manager.h +++ b/components/sync_sessions/sessions_sync_manager.h
@@ -29,6 +29,7 @@ #include "components/sync_sessions/local_session_event_router.h" #include "components/sync_sessions/lost_navigations_recorder.h" #include "components/sync_sessions/open_tabs_ui_delegate_impl.h" +#include "components/sync_sessions/sessions_global_id_mapper.h" #include "components/sync_sessions/synced_session.h" #include "components/sync_sessions/synced_session_tracker.h" @@ -76,6 +77,7 @@ // LocalSessionEventHandlerImpl::Delegate implementation. std::unique_ptr<LocalSessionEventHandlerImpl::WriteBatch> CreateLocalSessionWriteBatch() override; + void TrackLocalNavigationId(base::Time timestamp, int unique_id) override; void OnPageFaviconUpdated(const GURL& page_url) override; void OnFaviconVisited(const GURL& page_url, const GURL& favicon_url) override; @@ -167,9 +169,12 @@ SyncSessionsClient* const sessions_client_; SyncedSessionTracker session_tracker_; + SessionsGlobalIdMapper global_id_mapper_; FaviconCache favicon_cache_; OpenTabsUIDelegateImpl open_tabs_ui_delegate_; - LocalSessionEventHandlerImpl local_session_event_handler_; + + // Instantiated when sync is enabled. + std::unique_ptr<LocalSessionEventHandlerImpl> local_session_event_handler_; // Tracks whether our local representation of which sync nodes map to what // tabs (belonging to the current local session) is inconsistent. This can @@ -191,9 +196,8 @@ // Unique client tag. std::string current_machine_tag_; - // User-visible machine name and device type to populate header. + // User-visible machine name to populate header. std::string current_session_name_; - sync_pb::SyncEnums::DeviceType current_device_type_; // SyncID for the sync node containing all the window information for this // client.
diff --git a/components/sync_sessions/synced_session_tracker.cc b/components/sync_sessions/synced_session_tracker.cc index 6d9566e..173ebd16 100644 --- a/components/sync_sessions/synced_session_tracker.cc +++ b/components/sync_sessions/synced_session_tracker.cc
@@ -132,11 +132,22 @@ Clear(); } -void SyncedSessionTracker::SetLocalSessionTag( - const std::string& local_session_tag) { +void SyncedSessionTracker::InitLocalSession( + const std::string& local_session_tag, + const std::string& local_session_name, + sync_pb::SyncEnums::DeviceType local_device_type) { DCHECK(local_session_tag_.empty()); DCHECK(!local_session_tag.empty()); local_session_tag_ = local_session_tag; + + SyncedSession* local_session = GetSession(local_session_tag); + local_session->session_name = local_session_name; + local_session->device_type = local_device_type; + local_session->session_tag = local_session_tag; +} + +const std::string& SyncedSessionTracker::GetLocalSessionTag() const { + return local_session_tag_; } bool SyncedSessionTracker::LookupAllForeignSessions(
diff --git a/components/sync_sessions/synced_session_tracker.h b/components/sync_sessions/synced_session_tracker.h index 8510dfb..86c988bd2 100644 --- a/components/sync_sessions/synced_session_tracker.h +++ b/components/sync_sessions/synced_session_tracker.h
@@ -156,9 +156,14 @@ // **** Methods specific to the local session. **** - // Set the local session tag. Must be called before any other local session - // methods are invoked. - void SetLocalSessionTag(const std::string& local_session_tag); + // Set the local session information. Must be called before any other local + // session methods are invoked. + void InitLocalSession(const std::string& local_session_tag, + const std::string& local_session_name, + sync_pb::SyncEnums::DeviceType local_device_type); + + // Gets the session tag previously set with InitLocalSession(). + const std::string& GetLocalSessionTag() const; // Similar to CleanupForeignSession, but also marks any unmapped tabs as free // in the tab node pool and fills |deleted_node_ids| with the set of locally
diff --git a/components/sync_sessions/synced_session_tracker_unittest.cc b/components/sync_sessions/synced_session_tracker_unittest.cc index 60102cb..69d99a5 100644 --- a/components/sync_sessions/synced_session_tracker_unittest.cc +++ b/components/sync_sessions/synced_session_tracker_unittest.cc
@@ -21,6 +21,9 @@ namespace { const char kValidUrl[] = "http://www.example.com"; +const char kSessionName[] = "sessionname"; +const sync_pb::SyncEnums::DeviceType kDeviceType = + sync_pb::SyncEnums_DeviceType_TYPE_PHONE; const char kTag[] = "tag"; const char kTag2[] = "tag2"; const char kTag3[] = "tag3"; @@ -442,7 +445,7 @@ std::set<int> free_node_ids; int tab_node_id = TabNodePool::kInvalidTabNodeID; - GetTracker()->SetLocalSessionTag(kTag); + GetTracker()->InitLocalSession(kTag, kSessionName, kDeviceType); // Start with two restored tab nodes. GetTracker()->ReassociateLocalTab(kTabNode1, kTab1); @@ -500,7 +503,7 @@ std::set<int> free_node_ids; // First create the tab normally. - GetTracker()->SetLocalSessionTag(kTag); + GetTracker()->InitLocalSession(kTag, kSessionName, kDeviceType); EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1)); GetTracker()->ReassociateLocalTab(kTabNode1, kTab1); ASSERT_TRUE(VerifyTabIntegrity(kTag)); @@ -551,7 +554,7 @@ std::set<int> free_node_ids; // First create the tab normally. - GetTracker()->SetLocalSessionTag(kTag); + GetTracker()->InitLocalSession(kTag, kSessionName, kDeviceType); EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1)); GetTracker()->ReassociateLocalTab(kTabNode1, kTab1); ASSERT_TRUE(VerifyTabIntegrity(kTag)); @@ -616,7 +619,7 @@ std::set<int> free_node_ids; // First create the old tab in an unmapped state. - GetTracker()->SetLocalSessionTag(kTag); + GetTracker()->InitLocalSession(kTag, kSessionName, kDeviceType); EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1)); GetTracker()->ReassociateLocalTab(kTabNode1, kTab1); ASSERT_TRUE(VerifyTabIntegrity(kTag)); @@ -652,7 +655,7 @@ std::set<int> free_node_ids; // First create the old tab in an unmapped state. - GetTracker()->SetLocalSessionTag(kTag); + GetTracker()->InitLocalSession(kTag, kSessionName, kDeviceType); EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1)); GetTracker()->ReassociateLocalTab(kTabNode1, kTab1); ASSERT_TRUE(VerifyTabIntegrity(kTag)); @@ -690,7 +693,7 @@ std::set<int> free_node_ids; // First create the tab normally. - GetTracker()->SetLocalSessionTag(kTag); + GetTracker()->InitLocalSession(kTag, kSessionName, kDeviceType); EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1)); GetTracker()->ReassociateLocalTab(kTabNode1, kTab1); ASSERT_TRUE(VerifyTabIntegrity(kTag)); @@ -740,7 +743,7 @@ std::set<int> free_node_ids; // First create an unmapped tab. - GetTracker()->SetLocalSessionTag(kTag); + GetTracker()->InitLocalSession(kTag, kSessionName, kDeviceType); EXPECT_FALSE(GetTracker()->IsLocalTabNodeAssociated(kTabNode1)); GetTracker()->ReassociateLocalTab(kTabNode1, kTab1); ASSERT_TRUE(VerifyTabIntegrity(kTag));
diff --git a/components/tracing/child/child_trace_message_filter.cc b/components/tracing/child/child_trace_message_filter.cc index c772518..99de2f65 100644 --- a/components/tracing/child/child_trace_message_filter.cc +++ b/components/tracing/child/child_trace_message_filter.cc
@@ -88,10 +88,10 @@ base::Time computed_next_allowed_time = histogram_last_changed_ + base::TimeDelta::FromSeconds(kMinTimeBetweenHistogramChangesInSeconds); - if (computed_next_allowed_time > base::Time::Now()) + if (computed_next_allowed_time > TRACE_TIME_NOW()) return; } - histogram_last_changed_ = base::Time::Now(); + histogram_last_changed_ = TRACE_TIME_NOW(); if (sender_) sender_->Send(new TracingHostMsg_TriggerBackgroundTrace(histogram_name));
diff --git a/components/unzip_service/public/cpp/unzip.cc b/components/unzip_service/public/cpp/unzip.cc index b5f2986..a8ab1f5 100644 --- a/components/unzip_service/public/cpp/unzip.cc +++ b/components/unzip_service/public/cpp/unzip.cc
@@ -92,6 +92,7 @@ void UnzipDone(scoped_refptr<UnzipParams> params, bool success) { params->InvokeCallback(success); + params->unzipper()->reset(); } void DoUnzipWithFilter(
diff --git a/components/viz/service/display/gl_renderer.cc b/components/viz/service/display/gl_renderer.cc index 3db30fc..7b96160 100644 --- a/components/viz/service/display/gl_renderer.cc +++ b/components/viz/service/display/gl_renderer.cc
@@ -1469,7 +1469,7 @@ } } - SetShaderOpacity(params->quad); + SetShaderOpacity(params->quad->shared_quad_state->opacity); SetShaderQuadF(params->surface_quad); } @@ -1964,7 +1964,7 @@ // Blending is required for antialiasing. SetBlendEnabled(true); - SetShaderOpacity(quad); + SetShaderOpacity(quad->shared_quad_state->opacity); // Draw the quad with antialiasing. DrawQuadGeometryWithAA(quad, &local_quad, tile_rect); @@ -2001,11 +2001,9 @@ // the way to the edge and are using bilinear filtering. gfx::Size texture_size = quad->texture_size; bool fills_right_edge = - quad->shared_quad_state->quad_layer_rect.right() != quad->rect.right() || - texture_size.width() == tex_coord_rect.right(); - bool fills_bottom_edge = quad->shared_quad_state->quad_layer_rect.bottom() != - quad->rect.bottom() || - texture_size.height() == tex_coord_rect.bottom(); + !quad->IsRightEdge() || texture_size.width() == tex_coord_rect.right(); + bool fills_bottom_edge = + !quad->IsBottomEdge() || texture_size.height() == tex_coord_rect.bottom(); bool has_tex_clamp_rect = filter == GL_LINEAR && (!fills_right_edge || !fills_bottom_edge); gfx::SizeF tex_clamp_size(texture_size); @@ -2052,7 +2050,7 @@ SetBlendEnabled(quad->ShouldDrawWithBlending()); - SetShaderOpacity(quad); + SetShaderOpacity(quad->shared_quad_state->opacity); // Pass quad coordinates to the uniform in the same order as GeometryBinding // does, then vertices will match the texture mapping in the vertex buffer. @@ -2236,7 +2234,7 @@ // it. This is why this centered rect is used and not the original quad_rect. auto tile_rect = gfx::RectF(quad->rect); - SetShaderOpacity(quad); + SetShaderOpacity(quad->shared_quad_state->opacity); if (!clip_region) { DrawQuadGeometry(current_frame()->projection_matrix, quad->shared_quad_state->quad_to_target_transform, @@ -2280,7 +2278,7 @@ gl_->UniformMatrix4fvStreamTextureMatrixCHROMIUM( current_program_->tex_matrix_location(), false, gl_matrix); - SetShaderOpacity(quad); + SetShaderOpacity(quad->shared_quad_state->opacity); gfx::Size texture_size = lock.size(); gfx::Vector2dF uv = quad->matrix.Scale2d(); gfx::RectF uv_visible_rect(0, 0, uv.x(), uv.y()); @@ -2620,11 +2618,10 @@ gl_->Uniform2fv(current_program_->quad_location(), 4, gl_quad); } -void GLRenderer::SetShaderOpacity(const DrawQuad* quad) { +void GLRenderer::SetShaderOpacity(float opacity) { if (!current_program_ || current_program_->alpha_location() == -1) return; - gl_->Uniform1f(current_program_->alpha_location(), - quad->shared_quad_state->opacity); + gl_->Uniform1f(current_program_->alpha_location(), opacity); } void GLRenderer::SetShaderMatrix(const gfx::Transform& transform) {
diff --git a/components/viz/service/display/gl_renderer.h b/components/viz/service/display/gl_renderer.h index d0e4761..4e897a68 100644 --- a/components/viz/service/display/gl_renderer.h +++ b/components/viz/service/display/gl_renderer.h
@@ -244,7 +244,7 @@ const gfx::QuadF* clip_region); void DrawOverlayCandidateQuadBorder(float* gl_matrix); - void SetShaderOpacity(const DrawQuad* quad); + void SetShaderOpacity(float opacity); void SetShaderQuadF(const gfx::QuadF& quad); void SetShaderMatrix(const gfx::Transform& transform); void SetShaderColor(SkColor color, float opacity);
diff --git a/content/app/content_main_runner.cc b/content/app/content_main_runner.cc index 00864253..1b41368 100644 --- a/content/app/content_main_runner.cc +++ b/content/app/content_main_runner.cc
@@ -52,7 +52,7 @@ #include "content/public/common/content_switches.h" #include "content/public/common/main_function_params.h" #include "content/public/common/sandbox_init.h" -#include "content/public/common/zygote_features.h" +#include "content/public/common/zygote_buildflags.h" #include "gin/v8_initializer.h" #include "media/base/media.h" #include "media/media_features.h"
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index d967c234..603d414 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -79,10 +79,10 @@ "//content/browser/service_worker:service_worker_proto", "//content/browser/speech/proto", "//content/common", - "//content/common:features", + "//content/common:buildflags", "//content/common:mojo_bindings", "//content/public/common:common_sources", - "//content/public/common:zygote_features", + "//content/public/common:zygote_buildflags", "//crypto", "//device/bluetooth", "//device/fido", @@ -203,7 +203,7 @@ ] public_deps = [ - ":accessibility_flags", + ":accessibility_buildflags", "//ipc", "//media/mojo/interfaces:remoting", "//third_party/WebKit/public:media_devices_mojo_bindings", @@ -2366,8 +2366,8 @@ } } -buildflag_header("accessibility_flags") { - header = "accessibility_flags.h" +buildflag_header("accessibility_buildflags") { + header = "accessibility_buildflags.h" header_dir = "content/browser/accessibility" flags = [ "USE_ATK=$use_atk" ] }
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h index a0bb8dd..55db6d1c0 100644 --- a/content/browser/accessibility/browser_accessibility.h +++ b/content/browser/accessibility/browser_accessibility.h
@@ -15,7 +15,7 @@ #include "base/strings/string16.h" #include "base/strings/string_split.h" #include "build/build_config.h" -#include "content/browser/accessibility/accessibility_flags.h" +#include "content/browser/accessibility/accessibility_buildflags.h" #include "content/browser/accessibility/browser_accessibility_position.h" #include "content/common/content_export.h" #include "third_party/WebKit/public/web/WebAXEnums.h"
diff --git a/content/browser/accessibility/browser_accessibility_manager.h b/content/browser/accessibility/browser_accessibility_manager.h index 17912e34..08df1b42 100644 --- a/content/browser/accessibility/browser_accessibility_manager.h +++ b/content/browser/accessibility/browser_accessibility_manager.h
@@ -14,7 +14,7 @@ #include "base/containers/hash_tables.h" #include "base/macros.h" #include "build/build_config.h" -#include "content/browser/accessibility/accessibility_flags.h" +#include "content/browser/accessibility/accessibility_buildflags.h" #include "content/browser/accessibility/browser_accessibility_position.h" #include "content/common/content_export.h" #include "content/public/browser/ax_event_notification_details.h"
diff --git a/content/browser/accessibility/browser_accessibility_position.cc b/content/browser/accessibility/browser_accessibility_position.cc index b7f02796..74ba663 100644 --- a/content/browser/accessibility/browser_accessibility_position.cc +++ b/content/browser/accessibility/browser_accessibility_position.cc
@@ -6,7 +6,7 @@ #include "base/strings/string_util.h" #include "build/build_config.h" -#include "content/browser/accessibility/accessibility_flags.h" +#include "content/browser/accessibility/accessibility_buildflags.h" #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" #include "ui/accessibility/ax_enums.mojom.h"
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index e903e78..6300f92 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -106,7 +106,7 @@ #include "content/public/common/main_function_params.h" #include "content/public/common/result_codes.h" #include "content/public/common/service_names.mojom.h" -#include "content/public/common/zygote_features.h" +#include "content/public/common/zygote_buildflags.h" #include "device/gamepad/gamepad_service.h" #include "gpu/vulkan/features.h" #include "media/audio/audio_manager.h"
diff --git a/content/browser/child_process_launcher_helper.h b/content/browser/child_process_launcher_helper.h index 30d314f3..b9b7a82 100644 --- a/content/browser/child_process_launcher_helper.h +++ b/content/browser/child_process_launcher_helper.h
@@ -14,7 +14,7 @@ #include "build/build_config.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/result_codes.h" -#include "content/public/common/zygote_features.h" +#include "content/public/common/zygote_buildflags.h" #include "mojo/edk/embedder/embedder.h" #include "mojo/edk/embedder/outgoing_broker_client_invitation.h" #include "mojo/edk/embedder/scoped_platform_handle.h"
diff --git a/content/browser/devtools/devtools_http_handler.cc b/content/browser/devtools/devtools_http_handler.cc index 1a93ba9..77e0d258 100644 --- a/content/browser/devtools/devtools_http_handler.cc +++ b/content/browser/devtools/devtools_http_handler.cc
@@ -551,8 +551,9 @@ kTargetWebSocketDebuggerUrlField, base::StringPrintf("ws://%s%s", host.c_str(), browser_guid_.c_str())); #if defined(OS_ANDROID) - version.SetString("Android-Package", - base::android::BuildInfo::GetInstance()->package_name()); + version.SetString( + "Android-Package", + base::android::BuildInfo::GetInstance()->host_package_name()); #endif SendJson(connection_id, net::HTTP_OK, &version, std::string()); return;
diff --git a/content/browser/fileapi/DEPS b/content/browser/fileapi/DEPS index 87b83c0..743a2f3b 100644 --- a/content/browser/fileapi/DEPS +++ b/content/browser/fileapi/DEPS
@@ -1,3 +1,3 @@ include_rules = [ - "+third_party/leveldatabase/src/include/leveldb", + "+third_party/leveldatabase", ]
diff --git a/content/browser/fileapi/browser_file_system_helper.cc b/content/browser/fileapi/browser_file_system_helper.cc index fb3533d5..4d8ecc2b 100644 --- a/content/browser/fileapi/browser_file_system_helper.cc +++ b/content/browser/fileapi/browser_file_system_helper.cc
@@ -33,6 +33,7 @@ #include "storage/browser/fileapi/file_system_url.h" #include "storage/browser/fileapi/isolated_context.h" #include "storage/browser/quota/quota_manager.h" +#include "third_party/leveldatabase/leveldb_chrome.h" #include "url/gurl.h" #include "url/url_constants.h" @@ -61,7 +62,11 @@ switches::kAllowFileAccessFromFiles)) { additional_allowed_schemes.push_back(url::kFileScheme); } - return FileSystemOptions(profile_mode, additional_allowed_schemes, nullptr); + leveldb::Env* env_override = nullptr; + if (is_incognito) + env_override = leveldb_chrome::NewMemEnv(leveldb::Env::Default()); + return FileSystemOptions(profile_mode, additional_allowed_schemes, + env_override); } } // namespace
diff --git a/content/browser/frame_host/interstitial_page_impl.cc b/content/browser/frame_host/interstitial_page_impl.cc index 7c83d2a6..c34ab5d1d 100644 --- a/content/browser/frame_host/interstitial_page_impl.cc +++ b/content/browser/frame_host/interstitial_page_impl.cc
@@ -38,7 +38,7 @@ #include "content/browser/site_instance_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/browser/web_contents/web_contents_view.h" -#include "content/common/features.h" +#include "content/common/buildflags.h" #include "content/common/frame_messages.h" #include "content/common/input_messages.h" #include "content/common/view_messages.h"
diff --git a/content/browser/frame_host/navigator_impl.cc b/content/browser/frame_host/navigator_impl.cc index b5c2160..a7a55bf 100644 --- a/content/browser/frame_host/navigator_impl.cc +++ b/content/browser/frame_host/navigator_impl.cc
@@ -312,9 +312,10 @@ // "Open link in new tab"). We need to keep it above RFHM::Navigate() call to // capture the time needed for the RenderFrameHost initialization. base::TimeTicks navigation_start = base::TimeTicks::Now(); + base::TimeTicks tracing_navigation_start = TRACE_TIME_TICKS_NOW(); TRACE_EVENT_INSTANT_WITH_TIMESTAMP0( "navigation,rail", "NavigationTiming navigationStart", - TRACE_EVENT_SCOPE_GLOBAL, navigation_start); + TRACE_EVENT_SCOPE_GLOBAL, tracing_navigation_start); // Determine if Previews should be used for the navigation. PreviewsState previews_state = PREVIEWS_UNSPECIFIED; @@ -349,7 +350,7 @@ TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1( "navigation", "Navigation timeToNetworkStack", frame_tree_node->navigation_request()->navigation_handle(), - navigation_start, "FrameTreeNode id", + tracing_navigation_start, "FrameTreeNode id", frame_tree_node->frame_tree_node_id()); }
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 72b5266..2f94378 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -36,10 +36,10 @@ #include "content/browser/site_instance_impl.h" #include "content/browser/webui/web_ui_impl.h" #include "content/common/ax_content_node_data.h" +#include "content/common/buildflags.h" #include "content/common/content_export.h" #include "content/common/content_security_policy/csp_context.h" #include "content/common/download/mhtml_save_status.h" -#include "content/common/features.h" #include "content/common/frame.mojom.h" #include "content/common/frame_message_enums.h" #include "content/common/frame_replication_state.h"
diff --git a/content/browser/gpu/compositor_util.cc b/content/browser/gpu/compositor_util.cc index 4479fa5..63705c8f 100644 --- a/content/browser/gpu/compositor_util.cc +++ b/content/browser/gpu/compositor_util.cc
@@ -19,6 +19,7 @@ #include "base/sys_info.h" #include "build/build_config.h" #include "cc/base/switches.h" +#include "components/viz/common/features.h" #include "content/browser/gpu/gpu_data_manager_impl.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" @@ -117,6 +118,11 @@ "Native GpuMemoryBuffers have been disabled, either via about:flags" " or command line.", true}, + {"surface_synchronization", gpu::kGpuFeatureStatusEnabled, + !features::IsSurfaceSynchronizationEnabled(), + "Surface synchronization has been disabled by Finch trial or command " + "line.", + false}, {"webgl2", manager->GetFeatureStatus(gpu::GPU_FEATURE_TYPE_ACCELERATED_WEBGL2), (command_line.HasSwitch(switches::kDisableWebGL) || @@ -318,6 +324,10 @@ status += "_force"; status += "_on"; } + if (gpu_feature_data.name == "surface_synchronization") { + if (features::IsSurfaceSynchronizationEnabled()) + status += "_on"; + } } feature_status_dict->SetString(gpu_feature_data.name, status); }
diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc index ff3d4c4..456dc18 100644 --- a/content/browser/ppapi_plugin_process_host.cc +++ b/content/browser/ppapi_plugin_process_host.cc
@@ -31,7 +31,7 @@ #include "content/public/common/process_type.h" #include "content/public/common/sandboxed_process_launcher_delegate.h" #include "content/public/common/service_names.mojom.h" -#include "content/public/common/zygote_features.h" +#include "content/public/common/zygote_buildflags.h" #include "mojo/edk/embedder/embedder.h" #include "net/base/network_change_notifier.h" #include "ppapi/proxy/ppapi_messages.h"
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 5379142..d9b5be1 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -166,7 +166,7 @@ #include "content/public/common/sandboxed_process_launcher_delegate.h" #include "content/public/common/service_names.mojom.h" #include "content/public/common/url_constants.h" -#include "content/public/common/zygote_features.h" +#include "content/public/common/zygote_buildflags.h" #include "device/gamepad/gamepad_haptics_manager.h" #include "device/gamepad/gamepad_monitor.h" #include "gpu/GLES2/gl2extchromium.h"
diff --git a/content/browser/renderer_host/render_view_host_delegate_view.h b/content/browser/renderer_host/render_view_host_delegate_view.h index 2576982a..5b30fd8 100644 --- a/content/browser/renderer_host/render_view_host_delegate_view.h +++ b/content/browser/renderer_host/render_view_host_delegate_view.h
@@ -9,9 +9,9 @@ #include "base/callback.h" #include "build/build_config.h" +#include "content/common/buildflags.h" #include "content/common/content_export.h" #include "content/common/drag_event_source_info.h" -#include "content/common/features.h" #include "content/public/common/input_event_ack_state.h" #include "third_party/WebKit/public/platform/WebDragOperation.h"
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index a016a43..f4f6c45 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -148,14 +148,8 @@ // is obscured by the on screen keyboard. class WinScreenKeyboardObserver : public ui::OnScreenKeyboardObserver { public: - WinScreenKeyboardObserver(RenderWidgetHostViewAura* host_view, - const gfx::Point& location_in_screen, - float scale_factor, - aura::Window* window) - : host_view_(host_view), - location_in_screen_(location_in_screen), - device_scale_factor_(scale_factor), - window_(window) { + WinScreenKeyboardObserver(RenderWidgetHostViewAura* host_view) + : host_view_(host_view) { host_view_->SetInsets(gfx::Insets()); } @@ -165,65 +159,18 @@ } // base::win::OnScreenKeyboardObserver overrides. - void OnKeyboardVisible(const gfx::Rect& keyboard_rect_pixels) override { - gfx::Point location_in_pixels = - gfx::ConvertPointToPixel(device_scale_factor_, location_in_screen_); - - // Restore the viewport. - host_view_->SetInsets(gfx::Insets()); - - if (keyboard_rect_pixels.Contains(location_in_pixels)) { - aura::client::ScreenPositionClient* screen_position_client = - aura::client::GetScreenPositionClient(window_->GetRootWindow()); - if (!screen_position_client) - return; - - DVLOG(1) << "OSK covering focus point."; - gfx::Rect keyboard_rect = - gfx::ConvertRectToDIP(device_scale_factor_, keyboard_rect_pixels); - gfx::Rect bounds_in_screen = window_->GetBoundsInScreen(); - - DCHECK(bounds_in_screen.bottom() > keyboard_rect.y()); - - // Set the viewport of the window to be just above the on screen - // keyboard. - int viewport_bottom = bounds_in_screen.bottom() - keyboard_rect.y(); - - // If the viewport is bigger than the view, then we cannot handle it - // with the current approach. Moving the window above the OSK is one way. - // That for a later patchset. - if (viewport_bottom > bounds_in_screen.height()) - return; - - host_view_->SetInsets(gfx::Insets(0, 0, viewport_bottom, 0)); - - gfx::Point origin(location_in_screen_); - screen_position_client->ConvertPointFromScreen(window_, &origin); - - // TODO(ekaramad): We should support the case where the focused node is - // inside an OOPIF (https://crbug.com/676037). - // We want to scroll the node into a rectangle which originates from - // the touch point and a small offset (10) in either direction. - gfx::Rect node_rect(origin.x(), origin.y(), 10, 10); - - host_view_->ScrollFocusedEditableNodeIntoRect(node_rect); - } + void OnKeyboardVisible(const gfx::Rect& keyboard_rect) override { + host_view_->SetInsets(gfx::Insets( + 0, 0, keyboard_rect.IsEmpty() ? 0 : keyboard_rect.height(), 0)); } - void OnKeyboardHidden(const gfx::Rect& keyboard_rect_pixels) override { + void OnKeyboardHidden() override { // Restore the viewport. host_view_->SetInsets(gfx::Insets()); } private: RenderWidgetHostViewAura* host_view_; - // The location in DIPs where the touch occurred. - gfx::Point location_in_screen_; - // The current device scale factor. - float device_scale_factor_; - - // The content Window. - aura::Window* window_; DISALLOW_COPY_AND_ASSIGN(WinScreenKeyboardObserver); }; @@ -811,15 +758,13 @@ } void RenderWidgetHostViewAura::FocusedNodeTouched( - const gfx::Point& location_dips_screen, bool editable) { #if defined(OS_WIN) ui::OnScreenKeyboardDisplayManager* osk_display_manager = ui::OnScreenKeyboardDisplayManager::GetInstance(); DCHECK(osk_display_manager); if (editable && host_->GetView() && host_->delegate()) { - keyboard_observer_.reset(new WinScreenKeyboardObserver( - this, location_dips_screen, device_scale_factor_, window_)); + keyboard_observer_.reset(new WinScreenKeyboardObserver(this)); if (!osk_display_manager->DisplayVirtualKeyboard(keyboard_observer_.get())) keyboard_observer_.reset(nullptr); virtual_keyboard_requested_ = keyboard_observer_.get();
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index 54b286d1..de586d9 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -121,8 +121,7 @@ bool IsMouseLocked() override; gfx::Size GetVisibleViewportSize() const override; void SetInsets(const gfx::Insets& insets) override; - void FocusedNodeTouched(const gfx::Point& location_dips_screen, - bool editable) override; + void FocusedNodeTouched(bool editable) override; void SetNeedsBeginFrames(bool needs_begin_frames) override; void SetWantsAnimateOnlyBeginFrames() override; TouchSelectionControllerClientManager*
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc index 10cc19e..c6b83be 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.cc +++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -308,7 +308,6 @@ } void RenderWidgetHostViewBase::FocusedNodeTouched( - const gfx::Point& location_dips_screen, bool editable) { DVLOG(1) << "FocusedNodeTouched: " << editable; }
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index a88faed..9b8f8ad 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -119,8 +119,7 @@ const gfx::Rect& src_rect, const gfx::Size& output_size, base::OnceCallback<void(const SkBitmap&)> callback) override; - void FocusedNodeTouched(const gfx::Point& location_dips_screen, - bool editable) override; + void FocusedNodeTouched(bool editable) override; void GetScreenInfo(ScreenInfo* screen_info) const override; float GetDeviceScaleFactor() const final; TouchSelectionControllerClientManager*
diff --git a/content/browser/resources/gpu/info_view.js b/content/browser/resources/gpu/info_view.js index 219c2e8..c9fb6bcf 100644 --- a/content/browser/resources/gpu/info_view.js +++ b/content/browser/resources/gpu/info_view.js
@@ -113,6 +113,7 @@ 'rasterization': 'Rasterization', 'multiple_raster_threads': 'Multiple Raster Threads', 'native_gpu_memory_buffers': 'Native GpuMemoryBuffers', + 'surface_synchronization': 'Surface Synchronization', 'vpx_decode': 'VPx Video Decode', 'webgl2': 'WebGL2', 'checker_imaging': 'CheckerImaging',
diff --git a/content/browser/streams/stream.cc b/content/browser/streams/stream.cc index 5cb066a..8a018a7 100644 --- a/content/browser/streams/stream.cc +++ b/content/browser/streams/stream.cc
@@ -87,15 +87,7 @@ void Stream::OnResponseStarted(const net::HttpResponseInfo& response_info) { DCHECK(!metadata_); - if (response_info.headers) { - metadata_.reset(new StreamMetadata(response_info)); - return; - } - // Assume request wasn't backed by HTTP and produce fake "200 OK" response, - // as some consumers expect it for, say, data urls. - net::HttpResponseInfo fake_response_info = response_info; - fake_response_info.headers = new net::HttpResponseHeaders("HTTP/1.1 200 OK"); - metadata_ = std::make_unique<StreamMetadata>(fake_response_info); + metadata_ = std::make_unique<StreamMetadata>(response_info); } void Stream::UpdateNetworkStats(int64_t raw_body_bytes, int64_t total_bytes) {
diff --git a/content/browser/tracing/etw_tracing_agent_win.cc b/content/browser/tracing/etw_tracing_agent_win.cc index 7b9a956..adc428b 100644 --- a/content/browser/tracing/etw_tracing_agent_win.cc +++ b/content/browser/tracing/etw_tracing_agent_win.cc
@@ -166,8 +166,8 @@ void EtwTracingAgent::AddSyncEventToBuffer() { // Sync the clocks. - base::Time walltime = base::Time::NowFromSystemTime(); - base::TimeTicks now = base::TimeTicks::Now(); + base::Time walltime = base::subtle::TimeNowFromSystemTimeIgnoringOverride(); + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); LARGE_INTEGER walltime_in_us; walltime_in_us.QuadPart = walltime.ToInternalValue();
diff --git a/content/browser/tracing/power_tracing_agent.cc b/content/browser/tracing/power_tracing_agent.cc index 515144b6..af496fb 100644 --- a/content/browser/tracing/power_tracing_agent.cc +++ b/content/browser/tracing/power_tracing_agent.cc
@@ -158,7 +158,7 @@ } request_clock_sync_marker_callback_ = callback; - request_clock_sync_marker_start_time_ = base::TimeTicks::Now(); + request_clock_sync_marker_start_time_ = TRACE_TIME_TICKS_NOW(); battor_agent_->RecordClockSyncMarker(sync_id); } @@ -167,7 +167,7 @@ DCHECK_CURRENTLY_ON(BrowserThread::IO); base::TimeTicks issue_start_ts = request_clock_sync_marker_start_time_; - base::TimeTicks issue_end_ts = base::TimeTicks::Now(); + base::TimeTicks issue_end_ts = TRACE_TIME_TICKS_NOW(); if (error != battor::BATTOR_ERROR_NONE) issue_start_ts = issue_end_ts = base::TimeTicks();
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc index 568e011..a336ae6 100644 --- a/content/browser/tracing/tracing_controller_impl.cc +++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -239,7 +239,7 @@ base::CommandLine::ForCurrentProcess()->GetCommandLineString()); base::Time::Exploded ctime; - base::Time::Now().UTCExplode(&ctime); + TRACE_TIME_NOW().UTCExplode(&ctime); std::string time_string = base::StringPrintf( "%u-%u-%u %d:%d:%d", ctime.year, ctime.month, ctime.day_of_month, ctime.hour, ctime.minute, ctime.second);
diff --git a/content/browser/utility_process_host_impl.cc b/content/browser/utility_process_host_impl.cc index 51f997c2..229bcde 100644 --- a/content/browser/utility_process_host_impl.cc +++ b/content/browser/utility_process_host_impl.cc
@@ -30,7 +30,7 @@ #include "content/public/common/sandboxed_process_launcher_delegate.h" #include "content/public/common/service_manager_connection.h" #include "content/public/common/service_names.mojom.h" -#include "content/public/common/zygote_features.h" +#include "content/public/common/zygote_buildflags.h" #include "media/base/media_switches.h" #include "services/network/public/cpp/network_switches.h" #include "services/service_manager/public/cpp/interface_provider.h"
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 44764ef9..13c64464 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -6093,16 +6093,10 @@ void WebContentsImpl::FocusedNodeTouched(bool editable) { #if defined(OS_WIN) - // We use the cursor position to determine where the touch occurred. RenderWidgetHostView* view = GetRenderWidgetHostView(); if (!view) return; - POINT cursor_pos = {}; - ::GetCursorPos(&cursor_pos); - float scale = GetScaleFactorForView(view); - gfx::Point location_dips_screen = - gfx::ConvertPointToDIP(scale, gfx::Point(cursor_pos)); - view->FocusedNodeTouched(location_dips_screen, editable); + view->FocusedNodeTouched(editable); #endif }
diff --git a/content/browser/web_contents/web_contents_view_aura.h b/content/browser/web_contents/web_contents_view_aura.h index 50c22b1..4aa7af32 100644 --- a/content/browser/web_contents/web_contents_view_aura.h +++ b/content/browser/web_contents/web_contents_view_aura.h
@@ -16,8 +16,8 @@ #include "content/browser/renderer_host/overscroll_controller_delegate.h" #include "content/browser/renderer_host/render_view_host_delegate_view.h" #include "content/browser/web_contents/web_contents_view.h" +#include "content/common/buildflags.h" #include "content/common/content_export.h" -#include "content/common/features.h" #include "ui/aura/client/drag_drop_delegate.h" #include "ui/aura/window_delegate.h" #include "ui/aura/window_observer.h"
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index c8cfb65..d47a0adf 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -17,8 +17,8 @@ # For feature flags internal to content. See content/public/common:features # for feature flags that clients of contents need to know about. -buildflag_header("features") { - header = "features.h" +buildflag_header("buildflags") { + header = "buildflags.h" flags = [ "USE_EXTERNAL_POPUP_MENU=$use_external_popup_menu", @@ -323,7 +323,7 @@ "//ui/accessibility", ] deps = [ - ":features", + ":buildflags", "//base", "//base/third_party/dynamic_annotations", "//build/util:webkit_version", @@ -336,7 +336,7 @@ "//content/app/resources", "//content/public/common:interfaces", "//content/public/common:service_names", - "//content/public/common:zygote_features", + "//content/public/common:zygote_buildflags", "//device/base/synchronization", "//device/bluetooth", "//gpu",
diff --git a/content/common/frame_messages.h b/content/common/frame_messages.h index abc8e643..2799f2aa 100644 --- a/content/common/frame_messages.h +++ b/content/common/frame_messages.h
@@ -19,12 +19,12 @@ #include "build/build_config.h" #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/common/surfaces/surface_info.h" +#include "content/common/buildflags.h" #include "content/common/content_export.h" #include "content/common/content_param_traits.h" #include "content/common/content_security_policy/csp_context.h" #include "content/common/content_security_policy_header.h" #include "content/common/download/mhtml_save_status.h" -#include "content/common/features.h" #include "content/common/frame_message_enums.h" #include "content/common/frame_message_structs.h" #include "content/common/frame_owner_properties.h"
diff --git a/content/common/native_types.typemap b/content/common/native_types.typemap index 8e2f44e0..0e630441 100644 --- a/content/common/native_types.typemap +++ b/content/common/native_types.typemap
@@ -47,7 +47,7 @@ # transitive allowance, so those targets' own public_deps aren't included in # the set of implied dependencies. "//cc/ipc", - "//content/common:features", + "//content/common:buildflags", "//media", "//media/base/ipc", "//net",
diff --git a/content/public/android/java/src/org/chromium/content/browser/remoteobjects/RemoteObjectImpl.java b/content/public/android/java/src/org/chromium/content/browser/remoteobjects/RemoteObjectImpl.java index 5dcd0f8..af0f1f3 100644 --- a/content/public/android/java/src/org/chromium/content/browser/remoteobjects/RemoteObjectImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/remoteobjects/RemoteObjectImpl.java
@@ -136,6 +136,14 @@ callback.call(makeErrorResult(RemoteInvocationError.OBJECT_GET_CLASS_BLOCKED)); return; } + if (method.getReturnType().isArray()) { + // LIVECONNECT_COMPLIANCE: Existing behavior is to not call methods that + // return arrays. Spec requires calling the method and converting the + // result to a JavaScript array. + RemoteInvocationResult result = new RemoteInvocationResult(); + callback.call(result); + return; + } Class<?>[] parameterTypes = method.getParameterTypes(); Object[] args = new Object[numArguments];
diff --git a/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectImplTest.java b/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectImplTest.java index de91d2c2..e5ac6242 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectImplTest.java +++ b/content/public/android/junit/src/org/chromium/content/browser/remoteobjects/RemoteObjectImplTest.java
@@ -282,6 +282,23 @@ } @Test + public void testMethodReturningArrayIgnored() { + Object target = new Object() { + @TestJavascriptInterface + public int[] returnsIntArray() { + Assert.fail("Method returning array should not be called."); + return null; + } + }; + + RemoteObject remoteObject = new RemoteObjectImpl(target, TestJavascriptInterface.class); + RemoteObject.InvokeMethodResponse response = mock(RemoteObject.InvokeMethodResponse.class); + remoteObject.invokeMethod("returnsIntArray", new RemoteInvocationArgument[] {}, response); + + verify(response).call(resultIsOk()); + } + + @Test public void testInvocationTargetException() { Object target = new Object() { @TestJavascriptInterface
diff --git a/content/public/browser/render_widget_host_view.h b/content/public/browser/render_widget_host_view.h index 71f3b3c..ffcf44f 100644 --- a/content/public/browser/render_widget_host_view.h +++ b/content/public/browser/render_widget_host_view.h
@@ -191,12 +191,9 @@ base::OnceCallback<void(const SkBitmap&)> callback) = 0; // Notification that a node was touched. - // The |location_dips_screen| parameter contains the location where the touch - // occurred in DIPs in screen coordinates. // The |editable| parameter indicates if the node is editable, for e.g. // an input field, etc. - virtual void FocusedNodeTouched(const gfx::Point& location_dips_screen, - bool editable) = 0; + virtual void FocusedNodeTouched(bool editable) = 0; // Informs the view that its associated render widget has frames to draw and // wants to have BeginFrame messages sent to it. This should only be called
diff --git a/content/public/common/BUILD.gn b/content/public/common/BUILD.gn index c92262c7..f2f3d55 100644 --- a/content/public/common/BUILD.gn +++ b/content/public/common/BUILD.gn
@@ -255,6 +255,7 @@ public_deps = [ ":interfaces", ":service_names", + ":zygote_buildflags", "//content/common", "//ipc", "//media/capture:capture_base", @@ -274,7 +275,6 @@ ] deps = [ ":content_descriptor_keys", - ":zygote_features", # This looks needless as we have //content/common in public_deps, but it's # needed because of allow_circular_includes_from. @@ -332,14 +332,14 @@ } } -buildflag_header("features") { - header = "features.h" +buildflag_header("buildflags") { + header = "buildflags.h" flags = [ "RTC_USE_H264=$rtc_use_h264" ] } source_set("feature_h264_with_openh264_ffmpeg") { deps = [ - ":features", + ":buildflags", "//base", "//media:media_features", ] @@ -349,8 +349,8 @@ ] } -buildflag_header("zygote_features") { - header = "zygote_features.h" +buildflag_header("zygote_buildflags") { + header = "zygote_buildflags.h" flags = [ "USE_ZYGOTE_HANDLE=$use_zygote_handle" ] }
diff --git a/content/public/common/feature_h264_with_openh264_ffmpeg.h b/content/public/common/feature_h264_with_openh264_ffmpeg.h index 2ee9bf8..6d81d73 100644 --- a/content/public/common/feature_h264_with_openh264_ffmpeg.h +++ b/content/public/common/feature_h264_with_openh264_ffmpeg.h
@@ -6,7 +6,7 @@ #define CONTENT_PUBLIC_COMMON_FEATURE_H264_WITH_OPENH264_FFMPEG_H_ #include "base/feature_list.h" -#include "content/public/common/features.h" +#include "content/public/common/buildflags.h" #include "media/media_features.h" namespace content {
diff --git a/content/public/common/sandboxed_process_launcher_delegate.cc b/content/public/common/sandboxed_process_launcher_delegate.cc index b7e61e5ed..2574f49 100644 --- a/content/public/common/sandboxed_process_launcher_delegate.cc +++ b/content/public/common/sandboxed_process_launcher_delegate.cc
@@ -5,7 +5,7 @@ #include "content/public/common/sandboxed_process_launcher_delegate.h" #include "build/build_config.h" -#include "content/public/common/zygote_features.h" +#include "content/public/common/zygote_buildflags.h" #if BUILDFLAG(USE_ZYGOTE_HANDLE) #include "content/public/common/zygote_handle.h"
diff --git a/content/public/common/sandboxed_process_launcher_delegate.h b/content/public/common/sandboxed_process_launcher_delegate.h index 6af3c28..80043c8 100644 --- a/content/public/common/sandboxed_process_launcher_delegate.h +++ b/content/public/common/sandboxed_process_launcher_delegate.h
@@ -10,7 +10,7 @@ #include "base/process/process.h" #include "build/build_config.h" #include "content/common/content_export.h" -#include "content/public/common/zygote_features.h" +#include "content/public/common/zygote_buildflags.h" #include "services/service_manager/sandbox/sandbox_delegate.h" #include "services/service_manager/sandbox/sandbox_type.h"
diff --git a/content/public/common/zygote_handle.h b/content/public/common/zygote_handle.h index dfa9628..5c21c883 100644 --- a/content/public/common/zygote_handle.h +++ b/content/public/common/zygote_handle.h
@@ -10,7 +10,7 @@ #include "base/files/scoped_file.h" #include "build/build_config.h" #include "content/common/content_export.h" -#include "content/public/common/zygote_features.h" +#include "content/public/common/zygote_buildflags.h" #if !BUILDFLAG(USE_ZYGOTE_HANDLE) #error "Can not use zygote handles without USE_ZYGOTE_HANDLE"
diff --git a/content/public/renderer/BUILD.gn b/content/public/renderer/BUILD.gn index 1094933..481fb69e 100644 --- a/content/public/renderer/BUILD.gn +++ b/content/public/renderer/BUILD.gn
@@ -128,8 +128,8 @@ "webrtc_log_message_delegate.h", ] deps += [ + "//content/public/common:buildflags", "//content/public/common:feature_h264_with_openh264_ffmpeg", - "//content/public/common:features", "//third_party/webrtc_overrides", ] }
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index b5c90ea4..233d4e1 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -547,11 +547,11 @@ "//content:resources", "//content/child", "//content/common", - "//content/common:features", + "//content/common:buildflags", "//content/gpu:gpu_sources", "//content/public/child:child_sources", + "//content/public/common:buildflags", "//content/public/common:feature_h264_with_openh264_ffmpeg", - "//content/public/common:features", "//content/public/common:service_names", "//crypto:platform", "//device/base/synchronization",
diff --git a/content/renderer/external_popup_menu.h b/content/renderer/external_popup_menu.h index 79b97a1..e8a661a 100644 --- a/content/renderer/external_popup_menu.h +++ b/content/renderer/external_popup_menu.h
@@ -9,7 +9,7 @@ #include "base/macros.h" #include "build/build_config.h" -#include "content/common/features.h" +#include "content/common/buildflags.h" #include "third_party/WebKit/public/web/WebExternalPopupMenu.h" #include "third_party/WebKit/public/web/WebPopupMenuInfo.h" #include "ui/gfx/geometry/point_f.h"
diff --git a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc index 6eb1b5e..087e554 100644 --- a/content/renderer/media/webrtc/peer_connection_dependency_factory.cc +++ b/content/renderer/media/webrtc/peer_connection_dependency_factory.cc
@@ -23,11 +23,11 @@ #include "base/synchronization/waitable_event.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" +#include "content/public/common/buildflags.h" #include "content/public/common/content_client.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" #include "content/public/common/feature_h264_with_openh264_ffmpeg.h" -#include "content/public/common/features.h" #include "content/public/common/renderer_preferences.h" #include "content/public/common/webrtc_ip_handling_policy.h" #include "content/public/renderer/content_renderer_client.h"
diff --git a/content/renderer/media_recorder/h264_encoder.h b/content/renderer/media_recorder/h264_encoder.h index 524dd697..7074ffb3 100644 --- a/content/renderer/media_recorder/h264_encoder.h +++ b/content/renderer/media_recorder/h264_encoder.h
@@ -5,7 +5,7 @@ #ifndef CONTENT_RENDERER_MEDIA_RECORDER_H264_ENCODER_H_ #define CONTENT_RENDERER_MEDIA_RECORDER_H264_ENCODER_H_ -#include "content/public/common/features.h" +#include "content/public/common/buildflags.h" #if !BUILDFLAG(RTC_USE_H264) #error RTC_USE_H264 should be defined.
diff --git a/content/renderer/media_recorder/video_track_recorder.h b/content/renderer/media_recorder/video_track_recorder.h index df288c0f..2eed0e2b 100644 --- a/content/renderer/media_recorder/video_track_recorder.h +++ b/content/renderer/media_recorder/video_track_recorder.h
@@ -12,7 +12,7 @@ #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_checker.h" -#include "content/public/common/features.h" +#include "content/public/common/buildflags.h" #include "content/public/renderer/media_stream_video_sink.h" #include "media/muxers/webm_muxer.h" #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
diff --git a/content/renderer/render_frame_impl.h b/content/renderer/render_frame_impl.h index c67c9882..5bb6141 100644 --- a/content/renderer/render_frame_impl.h +++ b/content/renderer/render_frame_impl.h
@@ -30,8 +30,8 @@ #include "base/unguessable_token.h" #include "build/build_config.h" #include "content/common/associated_interface_registry_impl.h" +#include "content/common/buildflags.h" #include "content/common/download/mhtml_save_status.h" -#include "content/common/features.h" #include "content/common/frame.mojom.h" #include "content/common/frame_message_enums.h" #include "content/common/host_zoom.mojom.h"
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index affc7ad..1d44950 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -60,9 +60,9 @@ #include "content/child/memory/child_memory_coordinator_impl.h" #include "content/child/runtime_features.h" #include "content/child/thread_safe_sender.h" +#include "content/common/buildflags.h" #include "content/common/content_constants_internal.h" #include "content/common/dom_storage/dom_storage_messages.h" -#include "content/common/features.h" #include "content/common/frame_messages.h" #include "content/common/frame_owner_properties.h" #include "content/common/gpu_stream_constants.h"
diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index 3e8c9df5..ed92b75 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h
@@ -26,11 +26,11 @@ #include "cc/input/overscroll_behavior.h" #include "cc/input/touch_action.h" #include "components/viz/common/surfaces/local_surface_id.h" +#include "content/common/buildflags.h" #include "content/common/content_export.h" #include "content/common/cursors/webcursor.h" #include "content/common/drag_event_source_info.h" #include "content/common/edit_command.h" -#include "content/common/features.h" #include "content/common/widget.mojom.h" #include "content/public/common/drop_data.h" #include "content/public/common/screen_info.h"
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 58a44ca..7198af3 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1022,6 +1022,7 @@ ] sources -= [ "../browser/media/session/audio_focus_delegate_default_browsertest.cc", + "../browser/network_service_restart_browsertest.cc", "../browser/pointer_lock_browsertest.cc", "../browser/pointer_lock_browsertest.h", ] @@ -1100,7 +1101,7 @@ "../browser/webrtc/webrtc_webcam_browsertest.h", ] deps += [ - "//content/public/common:features", + "//content/public/common:buildflags", "//testing/perf", ] }
diff --git a/device/vr/android/gvr/gvr_delegate.cc b/device/vr/android/gvr/gvr_delegate.cc index 0418f435..fd331cd 100644 --- a/device/vr/android/gvr/gvr_delegate.cc +++ b/device/vr/android/gvr/gvr_delegate.cc
@@ -81,12 +81,6 @@ return omega_vec; } -void PostRotateZ(gfx::Transform* transform, float degrees) { - gfx::Transform rotate; - rotate.RotateAboutZAxis(degrees); - transform->ConcatTransform(rotate); -} - } // namespace /* static */ @@ -140,7 +134,6 @@ mojom::VRPosePtr GvrDelegate::GetVRPosePtrWithNeckModel( gvr::GvrApi* gvr_api, gfx::Transform* head_mat_out, - int rotate_degrees, int64_t prediction_time) { gvr::ClockTimePoint target_time = gvr::GvrApi::GetTimePointNow(); target_time.monotonic_system_time_nanos += prediction_time; @@ -154,9 +147,6 @@ head_mat_ptr = &head_mat; GvrMatToTransform(gvr_head_mat, head_mat_ptr); - if (rotate_degrees != 0) - PostRotateZ(head_mat_ptr, rotate_degrees); - mojom::VRPosePtr pose = GvrDelegate::VRPosePtrFromGvrPose(*head_mat_ptr); // Get a second pose a bit later to calculate angular velocity. @@ -166,9 +156,6 @@ gfx::Transform head_mat_2; GvrMatToTransform(gvr_head_mat_2, &head_mat_2); - if (rotate_degrees != 0) - PostRotateZ(&head_mat_2, rotate_degrees); - // Add headset angular velocity to the pose. pose->angularVelocity.emplace(3); double epsilon_seconds = kAngularVelocityEpsilonNanos * 1e-9; @@ -184,9 +171,8 @@ /* static */ mojom::VRPosePtr GvrDelegate::GetVRPosePtrWithNeckModel( gvr::GvrApi* gvr_api, - gfx::Transform* head_mat_out, - int rotate_degrees) { - return GetVRPosePtrWithNeckModel(gvr_api, head_mat_out, rotate_degrees, + gfx::Transform* head_mat_out) { + return GetVRPosePtrWithNeckModel(gvr_api, head_mat_out, kPredictionTimeWithoutVsyncNanos); }
diff --git a/device/vr/android/gvr/gvr_delegate.h b/device/vr/android/gvr/gvr_delegate.h index 6baa7c6..efe3c86 100644 --- a/device/vr/android/gvr/gvr_delegate.h +++ b/device/vr/android/gvr/gvr_delegate.h
@@ -33,12 +33,10 @@ static mojom::VRPosePtr GetVRPosePtrWithNeckModel( gvr::GvrApi* gvr_api, gfx::Transform* head_mat_out, - int rotate_degrees, int64_t prediction_time); static mojom::VRPosePtr GetVRPosePtrWithNeckModel( gvr::GvrApi* gvr_api, - gfx::Transform* head_mat_out, - int rotate_degrees); + gfx::Transform* head_mat_out); }; } // namespace device
diff --git a/device/vr/android/gvr/gvr_device.cc b/device/vr/android/gvr/gvr_device.cc index c2963e3..33ad3bd 100644 --- a/device/vr/android/gvr/gvr_device.cc +++ b/device/vr/android/gvr/gvr_device.cc
@@ -188,8 +188,8 @@ void GvrDevice::OnMagicWindowPoseRequest( mojom::VRMagicWindowProvider::GetPoseCallback callback) { - std::move(callback).Run(GvrDelegate::GetVRPosePtrWithNeckModel( - gvr_api_.get(), nullptr, rotation_degrees_)); + std::move(callback).Run( + GvrDelegate::GetVRPosePtrWithNeckModel(gvr_api_.get(), nullptr)); } void GvrDevice::OnListeningForActivate(bool listening) { @@ -201,10 +201,14 @@ void GvrDevice::PauseTracking() { gvr_api_->PauseTracking(); + JNIEnv* env = base::android::AttachCurrentThread(); + Java_NonPresentingGvrContext_pause(env, non_presenting_context_); } void GvrDevice::ResumeTracking() { gvr_api_->ResumeTracking(); + JNIEnv* env = base::android::AttachCurrentThread(); + Java_NonPresentingGvrContext_resume(env, non_presenting_context_); } GvrDelegateProvider* GvrDevice::GetGvrDelegateProvider() { @@ -216,16 +220,11 @@ return delegate_provider; } -void GvrDevice::OnDIPScaleChanged(JNIEnv* env, const JavaRef<jobject>& obj) { +void GvrDevice::OnDisplayConfigurationChanged(JNIEnv* env, + const JavaRef<jobject>& obj) { SetVRDisplayInfo(CreateVRDisplayInfo(gvr_api_.get(), GetId())); } -void GvrDevice::OnRotationChanged(JNIEnv* env, - const JavaRef<jobject>& obj, - jint rotation_degrees) { - rotation_degrees_ = rotation_degrees; -} - void GvrDevice::Activate(mojom::VRDisplayEventReason reason, base::Callback<void(bool)> on_handled) { OnActivate(reason, std::move(on_handled));
diff --git a/device/vr/android/gvr/gvr_device.h b/device/vr/android/gvr/gvr_device.h index e041c2e..e362ce2 100644 --- a/device/vr/android/gvr/gvr_device.h +++ b/device/vr/android/gvr/gvr_device.h
@@ -36,11 +36,9 @@ void PauseTracking() override; void ResumeTracking() override; - void OnDIPScaleChanged(JNIEnv* env, - const base::android::JavaRef<jobject>& obj); - void OnRotationChanged(JNIEnv* env, - const base::android::JavaRef<jobject>& obj, - jint rotation_degrees); + void OnDisplayConfigurationChanged( + JNIEnv* env, + const base::android::JavaRef<jobject>& obj); void Activate(mojom::VRDisplayEventReason reason, base::Callback<void(bool)> on_handled); @@ -62,7 +60,6 @@ base::android::ScopedJavaGlobalRef<jobject> non_presenting_context_; std::unique_ptr<gvr::GvrApi> gvr_api_; - int rotation_degrees_; base::WeakPtrFactory<GvrDevice> weak_ptr_factory_;
diff --git a/device/vr/android/java/src/org/chromium/device/vr/NonPresentingGvrContext.java b/device/vr/android/java/src/org/chromium/device/vr/NonPresentingGvrContext.java index 9e764510..d7ba07e6 100644 --- a/device/vr/android/java/src/org/chromium/device/vr/NonPresentingGvrContext.java +++ b/device/vr/android/java/src/org/chromium/device/vr/NonPresentingGvrContext.java
@@ -7,7 +7,6 @@ import android.content.Context; import android.os.StrictMode; import android.view.Display; -import android.view.Surface; import android.view.WindowManager; import com.google.vr.cardboard.DisplaySynchronizer; @@ -16,7 +15,6 @@ import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import org.chromium.ui.display.DisplayAndroid; /** * Creates an active GvrContext from a GvrApi created from the Application Context. This GvrContext @@ -24,9 +22,10 @@ * parameters. */ @JNINamespace("device") -public class NonPresentingGvrContext implements DisplayAndroid.DisplayAndroidObserver { +public class NonPresentingGvrContext { private GvrApi mGvrApi; - private DisplayAndroid mDisplayAndroid; + private DisplaySynchronizer mDisplaySynchronizer; + private boolean mResumed; private long mNativeGvrDevice; @@ -36,18 +35,22 @@ WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); Display display = windowManager.getDefaultDisplay(); - DisplaySynchronizer synchronizer = new DisplaySynchronizer(context, display); + mDisplaySynchronizer = new DisplaySynchronizer(context, display) { + @Override + public void onConfigurationChanged() { + super.onConfigurationChanged(); + onDisplayConfigurationChanged(); + } + }; // Creating the GvrApi can sometimes create the Daydream config file. StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); try { - mGvrApi = new GvrApi(context, synchronizer); + mGvrApi = new GvrApi(context, mDisplaySynchronizer); } finally { StrictMode.setThreadPolicy(oldPolicy); } - mDisplayAndroid = DisplayAndroid.getNonMultiDisplay(context); - mDisplayAndroid.addObserver(this); - onRotationChanged(mDisplayAndroid.getRotation()); + resume(); } @CalledByNative @@ -65,40 +68,30 @@ } @CalledByNative + private void pause() { + if (!mResumed) return; + mResumed = false; + mDisplaySynchronizer.onPause(); + } + + @CalledByNative + private void resume() { + if (mResumed) return; + mResumed = true; + mDisplaySynchronizer.onResume(); + } + + @CalledByNative private void shutdown() { + mDisplaySynchronizer.shutdown(); mGvrApi.shutdown(); - mDisplayAndroid.removeObserver(this); mNativeGvrDevice = 0; } - private int rotationToDegrees(int rotation) { - switch (rotation) { - case Surface.ROTATION_0: - return 0; - case Surface.ROTATION_90: - return 90; - case Surface.ROTATION_180: - return 180; - case Surface.ROTATION_270: - return 270; - } - assert false; - return 0; - } - - @Override - public void onRotationChanged(int rotation) { - if (mNativeGvrDevice != 0) { - nativeOnRotationChanged(mNativeGvrDevice, rotationToDegrees(rotation)); - } - } - - @Override - public void onDIPScaleChanged(float dipScale) { + public void onDisplayConfigurationChanged() { mGvrApi.refreshDisplayMetrics(); - if (mNativeGvrDevice != 0) nativeOnDIPScaleChanged(mNativeGvrDevice); + if (mNativeGvrDevice != 0) nativeOnDisplayConfigurationChanged(mNativeGvrDevice); } - private native void nativeOnDIPScaleChanged(long nativeGvrDevice); - private native void nativeOnRotationChanged(long nativeGvrDevice, int rotationDegrees); + private native void nativeOnDisplayConfigurationChanged(long nativeGvrDevice); }
diff --git a/docs/ios/coverage.md b/docs/ios/coverage.md deleted file mode 100644 index 7285718..0000000 --- a/docs/ios/coverage.md +++ /dev/null
@@ -1,78 +0,0 @@ -# Generate code coverage data - -1. Build a test target for coverage: - - ``` - ninja -C out/Coverage-iphonesimulator ios_chrome_unittests - ``` - - Targets that support code coverage need to call - `coverage_util::ConfigureCoverageReportPath()`. - If you don't use `setup-gn.py`, you can set the gn argument - `ios_enable_coverage` to `true`. - -1. Run the test target. If using Xcode, don't forget to set `Coverage` in the - target's scheme: - -  - -1. Find the `coverage.profraw` in the `Documents` folder of the app. You can - look in the console output of the instrumented target. For example: - - ``` - Coverage data at /Users/johndoe/Library/Developer/CoreSimulator/Devices/ - 82D642FA-FC18-4EDB-AFE0-A17454804BE4/data/Containers/Data/Application/ - E6B2B898-CE13-4958-93F3-E8B500446381/Documents/coverage.profraw - ``` - -1. Create a `coverage.profdata` file out of the `coverage.profraw` file: - - ``` - xcrun llvm-profdata merge \ - -o out/Coverage-iphonesimulator/coverage.profdata \ - path/to/coverage.profraw - ``` - -1. To see the **line coverage** for *all the instrumented source files*: - - ``` - xcrun llvm-cov show \ - out/Coverage-iphonesimulator/ios_chrome_unittests.app/ios_chrome_unittests \ - -instr-profile=out/Coverage-iphonesimulator/coverage.profdata \ - -arch=x86_64 - ``` - -  - - To see the **line coverage** for a *specific instrumented source - file/folder* (e.g. - `ios/chrome/browser/ui/coordinators/browser_coordinator.mm`): - - ``` - xcrun llvm-cov show \ - out/Coverage-iphonesimulator/ios_chrome_unittests.app/ios_chrome_unittests \ - -instr-profile=out/Coverage-iphonesimulator/coverage.profdata \ - -arch=x86_64 ios/chrome/browser/ui/coordinators/browser_coordinator.mm - ``` - -  - - To see a **complete report**: - - ``` - xcrun llvm-cov report \ - out/Coverage-iphonesimulator/ios_chrome_unittests.app/ios_chrome_unittests \ - -instr-profile=path/to/coverage.profdata -arch=x86_64 - ``` - -  - - To see a **report** for a *folder/file* (e.g. `ios/chrome/browser` folder): - - ``` - xcrun llvm-cov show \ - out/Coverage-iphonesimulator/ios_chrome_unittests.app/ios_chrome_unittests \ - -instr-profile=path/to/coverage.profdata -arch=x86_64 ios/chrome/browser - ``` - - 
diff --git a/docs/ios/images/coverage_xcode.png b/docs/ios/images/coverage_xcode.png deleted file mode 100644 index 73607346..0000000 --- a/docs/ios/images/coverage_xcode.png +++ /dev/null Binary files differ
diff --git a/docs/ios/images/llvm-cov_report.png b/docs/ios/images/llvm-cov_report.png deleted file mode 100644 index aac9e13..0000000 --- a/docs/ios/images/llvm-cov_report.png +++ /dev/null Binary files differ
diff --git a/docs/ios/images/llvm-cov_report_folder.png b/docs/ios/images/llvm-cov_report_folder.png deleted file mode 100644 index 510badd..0000000 --- a/docs/ios/images/llvm-cov_report_folder.png +++ /dev/null Binary files differ
diff --git a/docs/ios/images/llvm-cov_show.png b/docs/ios/images/llvm-cov_show.png deleted file mode 100644 index bf5c9c7..0000000 --- a/docs/ios/images/llvm-cov_show.png +++ /dev/null Binary files differ
diff --git a/docs/ios/images/llvm-cov_show_file.png b/docs/ios/images/llvm-cov_show_file.png deleted file mode 100644 index 45a18a3..0000000 --- a/docs/ios/images/llvm-cov_show_file.png +++ /dev/null Binary files differ
diff --git a/extensions/browser/device_local_account_util.cc b/extensions/browser/device_local_account_util.cc index 4ecc3674..c4f3fe5b 100644 --- a/extensions/browser/device_local_account_util.cc +++ b/extensions/browser/device_local_account_util.cc
@@ -25,6 +25,7 @@ "pmnllmkmjilbojkpgplbdmckghmaocjh", // Scan app by François Beaufort "haeblkpifdemlfnkogkipmghfcbonief", // Charismathics Smart Card Middleware "mpnkhdpphjiihmlmkcamhpogecnnfffa", // Service NSW Kiosk Utility + "npilppbicblkkgjfnbmibmhhgjhobpll", // QwickACCESS // Libraries: "aclofikceldphonlfmghmimkodjdmhck", // Ancoris login component
diff --git a/extensions/browser/extension_web_contents_observer.cc b/extensions/browser/extension_web_contents_observer.cc index 794156e..52be0b4 100644 --- a/extensions/browser/extension_web_contents_observer.cc +++ b/extensions/browser/extension_web_contents_observer.cc
@@ -4,6 +4,7 @@ #include "extensions/browser/extension_web_contents_observer.h" +#include "base/logging.h" #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/render_frame_host.h" @@ -34,14 +35,31 @@ web_contents); } +void ExtensionWebContentsObserver::Initialize() { + if (initialized_) + return; + + initialized_ = true; + for (content::RenderFrameHost* rfh : web_contents()->GetAllFrames()) { + // We only initialize the frame if the renderer counterpart is live; + // otherwise we wait for the RenderFrameCreated notification. + if (!rfh->IsRenderFrameLive()) + continue; + + // Initialize the FrameData for this frame here since we didn't receive the + // RenderFrameCreated notification for it. + ExtensionApiFrameIdMap::Get()->InitializeRenderFrameData(rfh); + + InitializeRenderFrame(rfh); + } +} + ExtensionWebContentsObserver::ExtensionWebContentsObserver( content::WebContents* web_contents) : content::WebContentsObserver(web_contents), browser_context_(web_contents->GetBrowserContext()), - dispatcher_(browser_context_) { - web_contents->ForEachFrame( - base::BindRepeating(&ExtensionWebContentsObserver::InitializeFrameHelper, - base::Unretained(this))); + dispatcher_(browser_context_), + initialized_(false) { dispatcher_.set_delegate(this); } @@ -50,6 +68,7 @@ void ExtensionWebContentsObserver::InitializeRenderFrame( content::RenderFrameHost* render_frame_host) { + DCHECK(initialized_); DCHECK(render_frame_host); DCHECK(render_frame_host->IsRenderFrameLive()); @@ -83,11 +102,13 @@ content::WebContents* ExtensionWebContentsObserver::GetAssociatedWebContents() const { + DCHECK(initialized_); return web_contents(); } void ExtensionWebContentsObserver::RenderFrameCreated( content::RenderFrameHost* render_frame_host) { + DCHECK(initialized_); // Optimization: Look up the extension API frame ID to force the mapping to be // cached. This minimizes the number of IO->UI->IO thread hops when the ID is // looked up again on the IO thread for the webRequest API. @@ -131,6 +152,7 @@ void ExtensionWebContentsObserver::RenderFrameDeleted( content::RenderFrameHost* render_frame_host) { + DCHECK(initialized_); ProcessManager::Get(browser_context_) ->UnregisterRenderFrameHost(render_frame_host); ExtensionApiFrameIdMap::Get()->OnRenderFrameDeleted(render_frame_host); @@ -149,6 +171,7 @@ void ExtensionWebContentsObserver::DidFinishNavigation( content::NavigationHandle* navigation_handle) { + DCHECK(initialized_); if (!navigation_handle->HasCommitted()) return; @@ -171,12 +194,14 @@ content::RenderFrameHost* render_frame_host, const std::string& interface_name, mojo::ScopedMessagePipeHandle* interface_pipe) { + DCHECK(initialized_); registry_.TryBindInterface(interface_name, interface_pipe, render_frame_host); } bool ExtensionWebContentsObserver::OnMessageReceived( const IPC::Message& message, content::RenderFrameHost* render_frame_host) { + DCHECK(initialized_); bool handled = true; IPC_BEGIN_MESSAGE_MAP_WITH_PARAM( ExtensionWebContentsObserver, message, render_frame_host) @@ -187,6 +212,7 @@ } void ExtensionWebContentsObserver::PepperInstanceCreated() { + DCHECK(initialized_); if (GetViewType(web_contents()) == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { ProcessManager* const process_manager = ProcessManager::Get(browser_context_); @@ -198,6 +224,7 @@ } void ExtensionWebContentsObserver::PepperInstanceDeleted() { + DCHECK(initialized_); if (GetViewType(web_contents()) == VIEW_TYPE_EXTENSION_BACKGROUND_PAGE) { ProcessManager* const process_manager = ProcessManager::Get(browser_context_); @@ -210,6 +237,7 @@ std::string ExtensionWebContentsObserver::GetExtensionIdFromFrame( content::RenderFrameHost* render_frame_host) const { + DCHECK(initialized_); const GURL& site = render_frame_host->GetSiteInstance()->GetSiteURL(); if (!site.SchemeIs(kExtensionScheme)) return std::string(); @@ -220,6 +248,7 @@ const Extension* ExtensionWebContentsObserver::GetExtensionFromFrame( content::RenderFrameHost* render_frame_host, bool verify_url) const { + DCHECK(initialized_); std::string extension_id = GetExtensionIdFromFrame(render_frame_host); if (extension_id.empty()) return nullptr; @@ -250,23 +279,9 @@ void ExtensionWebContentsObserver::OnRequest( content::RenderFrameHost* render_frame_host, const ExtensionHostMsg_Request_Params& params) { + DCHECK(initialized_); dispatcher_.Dispatch(params, render_frame_host, render_frame_host->GetProcess()->GetID()); } -void ExtensionWebContentsObserver::InitializeFrameHelper( - content::RenderFrameHost* render_frame_host) { - // Since this is called for all existing RenderFrameHosts during the - // ExtensionWebContentsObserver's creation, it's possible that not all hosts - // are ready. - // We only initialize the frame if the renderer counterpart is live; otherwise - // we wait for the RenderFrameCreated notification. - if (render_frame_host->IsRenderFrameLive()) { - // Initialize the FrameData for this frame here since we didn't receive the - // RenderFrameCreated notification for it. - ExtensionApiFrameIdMap::Get()->InitializeRenderFrameData(render_frame_host); - InitializeRenderFrame(render_frame_host); - } -} - } // namespace extensions
diff --git a/extensions/browser/extension_web_contents_observer.h b/extensions/browser/extension_web_contents_observer.h index 9b76d03..685e4154 100644 --- a/extensions/browser/extension_web_contents_observer.h +++ b/extensions/browser/extension_web_contents_observer.h
@@ -55,6 +55,9 @@ static ExtensionWebContentsObserver* GetForWebContents( content::WebContents* web_contents); + // This must be called by clients directly after the EWCO has been created. + void Initialize(); + ExtensionFunctionDispatcher* dispatcher() { return &dispatcher_; } // Returns the extension associated with the given |render_frame_host|, or @@ -70,6 +73,8 @@ explicit ExtensionWebContentsObserver(content::WebContents* web_contents); ~ExtensionWebContentsObserver() override; + bool initialized() const { return initialized_; } + content::BrowserContext* browser_context() { return browser_context_; } // Initializes a new render frame. Subclasses should invoke this @@ -111,15 +116,14 @@ void OnRequest(content::RenderFrameHost* render_frame_host, const ExtensionHostMsg_Request_Params& params); - // A helper function for initializing render frames at the creation of the - // observer. - void InitializeFrameHelper(content::RenderFrameHost* render_frame_host); - // The BrowserContext associated with the WebContents being observed. content::BrowserContext* browser_context_; ExtensionFunctionDispatcher dispatcher_; + // Whether this object has been initialized. + bool initialized_; + service_manager::BinderRegistryWithArgs<content::RenderFrameHost*> registry_; DISALLOW_COPY_AND_ASSIGN(ExtensionWebContentsObserver);
diff --git a/extensions/shell/browser/shell_extension_web_contents_observer.cc b/extensions/shell/browser/shell_extension_web_contents_observer.cc index 9dc3691..842fc5d 100644 --- a/extensions/shell/browser/shell_extension_web_contents_observer.cc +++ b/extensions/shell/browser/shell_extension_web_contents_observer.cc
@@ -17,4 +17,13 @@ ShellExtensionWebContentsObserver::~ShellExtensionWebContentsObserver() { } +void ShellExtensionWebContentsObserver::CreateForWebContents( + content::WebContents* web_contents) { + content::WebContentsUserData< + ShellExtensionWebContentsObserver>::CreateForWebContents(web_contents); + + // Initialize this instance if necessary. + FromWebContents(web_contents)->Initialize(); +} + } // namespace extensions
diff --git a/extensions/shell/browser/shell_extension_web_contents_observer.h b/extensions/shell/browser/shell_extension_web_contents_observer.h index dc458fd..44a27d1 100644 --- a/extensions/shell/browser/shell_extension_web_contents_observer.h +++ b/extensions/shell/browser/shell_extension_web_contents_observer.h
@@ -18,6 +18,10 @@ public: ~ShellExtensionWebContentsObserver() override; + // Creates and initializes an instance of this class for the given + // |web_contents|, if it doesn't already exist. + static void CreateForWebContents(content::WebContents* web_contents); + private: friend class content::WebContentsUserData<ShellExtensionWebContentsObserver>;
diff --git a/extensions/test/data/api_test/audio/add_nodes/manifest.json b/extensions/test/data/api_test/audio/add_nodes/manifest.json index 587b70a..65fba2f 100644 --- a/extensions/test/data/api_test/audio/add_nodes/manifest.json +++ b/extensions/test/data/api_test/audio/add_nodes/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.audio.OnNodesChangedAddNodes", + "manifest_version": 2, "version": "1.0", "description": "browser test for chrome.audio.OnNodesChanged event", "app": {
diff --git a/extensions/test/data/api_test/audio/input_mute_change/manifest.json b/extensions/test/data/api_test/audio/input_mute_change/manifest.json index 014be98..a2e7f360e 100644 --- a/extensions/test/data/api_test/audio/input_mute_change/manifest.json +++ b/extensions/test/data/api_test/audio/input_mute_change/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.audio.OnInputMuteChanged", + "manifest_version": 2, "version": "1.0", "description": "browser test for chrome.audio.OnInputMuteChanged event", "app": {
diff --git a/extensions/test/data/api_test/audio/output_mute_change/manifest.json b/extensions/test/data/api_test/audio/output_mute_change/manifest.json index d91d3dc8..7ff4896 100644 --- a/extensions/test/data/api_test/audio/output_mute_change/manifest.json +++ b/extensions/test/data/api_test/audio/output_mute_change/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.audio.OnOutputMuteChanged", + "manifest_version": 2, "version": "1.0", "description": "browser test for chrome.audio.OnOutputMuteChanged event", "app": {
diff --git a/extensions/test/data/api_test/audio/remove_nodes/manifest.json b/extensions/test/data/api_test/audio/remove_nodes/manifest.json index d55c69b..93104b1 100644 --- a/extensions/test/data/api_test/audio/remove_nodes/manifest.json +++ b/extensions/test/data/api_test/audio/remove_nodes/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.audio.OnNodesChangedRemoveNodes", + "manifest_version": 2, "version": "1.0", "description": "browser test for chrome.audio.OnNodesChanged event", "app": {
diff --git a/extensions/test/data/api_test/audio/volume_change/manifest.json b/extensions/test/data/api_test/audio/volume_change/manifest.json index a039b942..258bed8 100644 --- a/extensions/test/data/api_test/audio/volume_change/manifest.json +++ b/extensions/test/data/api_test/audio/volume_change/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.audio.OnOutputNodeVolumeChanged", + "manifest_version": 2, "version": "1.0", "description": "browser test for chrome.audio.OnOutputNodeVolumeChanged event", "app": {
diff --git a/extensions/test/data/api_test/display_source/api/manifest.json b/extensions/test/data/api_test/display_source/api/manifest.json index c390d3c..8345dfcd 100644 --- a/extensions/test/data/api_test/display_source/api/manifest.json +++ b/extensions/test/data/api_test/display_source/api/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.displaySource", + "manifest_version": 2, "version": "0.1", "description": "end-to-end browser test for chrome.displaySource API", "app": {
diff --git a/extensions/test/data/api_test/dns/api/manifest.json b/extensions/test/data/api_test/dns/api/manifest.json index ba0677d..36ba8407 100644 --- a/extensions/test/data/api_test/dns/api/manifest.json +++ b/extensions/test/data/api_test/dns/api/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.experimental.dns", + "manifest_version": 2, "version": "0.1", "description": "end-to-end browser test for chrome.experimental.dns API", "app": {
diff --git a/extensions/test/data/api_test/hid/add_event/manifest.json b/extensions/test/data/api_test/hid/add_event/manifest.json index 81ed784..d14fd9b 100644 --- a/extensions/test/data/api_test/hid/add_event/manifest.json +++ b/extensions/test/data/api_test/hid/add_event/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.hid.onDeviceAdded", + "manifest_version": 2, "version": "0.1", "description": "browser test for chrome.hid.onDeviceAdded event", "app": {
diff --git a/extensions/test/data/api_test/hid/api/manifest.json b/extensions/test/data/api_test/hid/api/manifest.json index e17391b5..ca5cbbf 100644 --- a/extensions/test/data/api_test/hid/api/manifest.json +++ b/extensions/test/data/api_test/hid/api/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.hid", + "manifest_version": 2, "version": "0.1", "description": "end-to-end browser tests for chrome.hid API", "app": {
diff --git a/extensions/test/data/api_test/hid/get_user_selected_devices/manifest.json b/extensions/test/data/api_test/hid/get_user_selected_devices/manifest.json index 6245f2d..29816df 100644 --- a/extensions/test/data/api_test/hid/get_user_selected_devices/manifest.json +++ b/extensions/test/data/api_test/hid/get_user_selected_devices/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.hid.getUserSelectedDevices", + "manifest_version": 2, "version": "0.1", "description": "browser test for chrome.hid.getUserSelectedDevices", "app": {
diff --git a/extensions/test/data/api_test/hid/remove_event/manifest.json b/extensions/test/data/api_test/hid/remove_event/manifest.json index 22da39f..f57d024b 100644 --- a/extensions/test/data/api_test/hid/remove_event/manifest.json +++ b/extensions/test/data/api_test/hid/remove_event/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.hid.onDeviceRemoved", + "manifest_version": 2, "version": "0.1", "description": "browser test for chrome.hid.onDeviceRemoved event", "app": {
diff --git a/extensions/test/data/api_test/usb/add_event/manifest.json b/extensions/test/data/api_test/usb/add_event/manifest.json index d5a7d6f0..f511215 100644 --- a/extensions/test/data/api_test/usb/add_event/manifest.json +++ b/extensions/test/data/api_test/usb/add_event/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.usb.onDeviceAdded", + "manifest_version": 2, "version": "0.1", "description": "browser test for chrome.usb.onDeviceAdded event", "app": {
diff --git a/extensions/test/data/api_test/usb/device_handling/manifest.json b/extensions/test/data/api_test/usb/device_handling/manifest.json index ebfaf62..d9a27c8 100644 --- a/extensions/test/data/api_test/usb/device_handling/manifest.json +++ b/extensions/test/data/api_test/usb/device_handling/manifest.json
@@ -1,5 +1,6 @@ { "name": "USB Device Handling", + "manifest_version": 2, "version": "0.1", "app": { "background": {
diff --git a/extensions/test/data/api_test/usb/get_user_selected_devices/manifest.json b/extensions/test/data/api_test/usb/get_user_selected_devices/manifest.json index 11e58c938..bea3b273 100644 --- a/extensions/test/data/api_test/usb/get_user_selected_devices/manifest.json +++ b/extensions/test/data/api_test/usb/get_user_selected_devices/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.usb.getUserSelectedDevices", + "manifest_version": 2, "version": "0.1", "description": "browser test for chrome.usb.getUserSelectedDevices", "app": {
diff --git a/extensions/test/data/api_test/usb/invalid_length_transfer/manifest.json b/extensions/test/data/api_test/usb/invalid_length_transfer/manifest.json index 8f2a53f..a20e02b9 100644 --- a/extensions/test/data/api_test/usb/invalid_length_transfer/manifest.json +++ b/extensions/test/data/api_test/usb/invalid_length_transfer/manifest.json
@@ -1,5 +1,6 @@ { "name": "USB Invalid-Length Transfer", + "manifest_version": 2, "version": "0.1", "app": { "background": {
diff --git a/extensions/test/data/api_test/usb/invalid_timeout/manifest.json b/extensions/test/data/api_test/usb/invalid_timeout/manifest.json index 7695a90..868ad4f 100644 --- a/extensions/test/data/api_test/usb/invalid_timeout/manifest.json +++ b/extensions/test/data/api_test/usb/invalid_timeout/manifest.json
@@ -1,5 +1,6 @@ { "name": "USB Invalid Transfer Timeout", + "manifest_version": 2, "version": "0.1", "app": { "background": {
diff --git a/extensions/test/data/api_test/usb/list_interfaces/manifest.json b/extensions/test/data/api_test/usb/list_interfaces/manifest.json index f1e4722..6b05630c 100644 --- a/extensions/test/data/api_test/usb/list_interfaces/manifest.json +++ b/extensions/test/data/api_test/usb/list_interfaces/manifest.json
@@ -1,5 +1,6 @@ { "name": "USB List Interfaces", + "manifest_version": 2, "version": "0.1", "app": { "background": {
diff --git a/extensions/test/data/api_test/usb/remove_event/manifest.json b/extensions/test/data/api_test/usb/remove_event/manifest.json index 2dce9e8a..6dff021c 100644 --- a/extensions/test/data/api_test/usb/remove_event/manifest.json +++ b/extensions/test/data/api_test/usb/remove_event/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.usb.onDeviceRemoved", + "manifest_version": 2, "version": "0.1", "description": "browser test for chrome.usb.onDeviceRemoved event", "app": {
diff --git a/extensions/test/data/api_test/usb/reset_device/manifest.json b/extensions/test/data/api_test/usb/reset_device/manifest.json index ebfaf62..d9a27c8 100644 --- a/extensions/test/data/api_test/usb/reset_device/manifest.json +++ b/extensions/test/data/api_test/usb/reset_device/manifest.json
@@ -1,5 +1,6 @@ { "name": "USB Device Handling", + "manifest_version": 2, "version": "0.1", "app": { "background": {
diff --git a/extensions/test/data/api_test/usb/set_configuration/manifest.json b/extensions/test/data/api_test/usb/set_configuration/manifest.json index a496ee5..44e57cf 100644 --- a/extensions/test/data/api_test/usb/set_configuration/manifest.json +++ b/extensions/test/data/api_test/usb/set_configuration/manifest.json
@@ -1,5 +1,6 @@ { "name": "USB Set Configuration", + "manifest_version": 2, "version": "0.1", "app": { "background": {
diff --git a/extensions/test/data/api_test/usb/transfer_event/manifest.json b/extensions/test/data/api_test/usb/transfer_event/manifest.json index 44c51151..d6ffa90 100644 --- a/extensions/test/data/api_test/usb/transfer_event/manifest.json +++ b/extensions/test/data/api_test/usb/transfer_event/manifest.json
@@ -1,5 +1,6 @@ { "name": "USB Transfer Events", + "manifest_version": 2, "version": "0.1", "app": { "background": {
diff --git a/extensions/test/data/api_test/usb/transfer_failure/manifest.json b/extensions/test/data/api_test/usb/transfer_failure/manifest.json index fd9e0bf4..732a6cd1 100644 --- a/extensions/test/data/api_test/usb/transfer_failure/manifest.json +++ b/extensions/test/data/api_test/usb/transfer_failure/manifest.json
@@ -1,5 +1,6 @@ { "name": "USB Transfer Failure", + "manifest_version": 2, "version": "0.1", "app": { "background": {
diff --git a/extensions/test/data/api_test/usb/zero_length_transfer/manifest.json b/extensions/test/data/api_test/usb/zero_length_transfer/manifest.json index 31fbb829..a611d31 100644 --- a/extensions/test/data/api_test/usb/zero_length_transfer/manifest.json +++ b/extensions/test/data/api_test/usb/zero_length_transfer/manifest.json
@@ -1,5 +1,6 @@ { "name": "USB Zero-Length Transfer", + "manifest_version": 2, "version": "0.1", "app": { "background": {
diff --git a/extensions/test/data/sockets_tcp/api/manifest.json b/extensions/test/data/sockets_tcp/api/manifest.json index d780cf2..bf1fe89 100644 --- a/extensions/test/data/sockets_tcp/api/manifest.json +++ b/extensions/test/data/sockets_tcp/api/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.sockets.tcp", + "manifest_version": 2, "version": "0.1", "description": "end-to-end browser test for chrome.sockets.tcp API", "app": {
diff --git a/extensions/test/data/sockets_tcp_server/api/manifest.json b/extensions/test/data/sockets_tcp_server/api/manifest.json index 9e2923cf..3d5e3a9 100644 --- a/extensions/test/data/sockets_tcp_server/api/manifest.json +++ b/extensions/test/data/sockets_tcp_server/api/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.sockets.tcpServer extension", + "manifest_version": 2, "version": "0.1", "description": "end-to-end browser test for chrome.sockets.tcpServer API", "app": {
diff --git a/extensions/test/data/sockets_tcp_server/unload/manifest.json b/extensions/test/data/sockets_tcp_server/unload/manifest.json index 3e508ce..f91f64b6 100644 --- a/extensions/test/data/sockets_tcp_server/unload/manifest.json +++ b/extensions/test/data/sockets_tcp_server/unload/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.sockets.tcpServer unload", + "manifest_version": 2, "version": "0.1", "description": "browser test for chrome.sockets.tcpServer API to make sure sockets are free'd when extension is reloaded", "app": {
diff --git a/extensions/test/data/system/cpu/manifest.json b/extensions/test/data/system/cpu/manifest.json index 8ece45ee..f44cc11 100644 --- a/extensions/test/data/system/cpu/manifest.json +++ b/extensions/test/data/system/cpu/manifest.json
@@ -1,5 +1,6 @@ { "name": "system.cpu test", + "manifest_version": 2, "version": "1.0", "description": "Test system.cpu API", "permissions": ["system.cpu"],
diff --git a/extensions/test/data/system/display/info/manifest.json b/extensions/test/data/system/display/info/manifest.json index 11792b6..0150ed3 100644 --- a/extensions/test/data/system/display/info/manifest.json +++ b/extensions/test/data/system/display/info/manifest.json
@@ -1,5 +1,6 @@ { "name": "displayinfo", + "manifest_version": 2, "version": "1.0", "description": "Test system.display API", "permissions": ["system.display"],
diff --git a/extensions/test/data/system/display/overscan/manifest.json b/extensions/test/data/system/display/overscan/manifest.json index 2500bd4..9ea8310 100644 --- a/extensions/test/data/system/display/overscan/manifest.json +++ b/extensions/test/data/system/display/overscan/manifest.json
@@ -1,5 +1,6 @@ { "name": "overscan", + "manifest_version": 2, "version": "1.0", "description": "Test system.display.overscan* API", "permissions": ["system.display"],
diff --git a/extensions/test/data/system/display/overscan_no_complete/manifest.json b/extensions/test/data/system/display/overscan_no_complete/manifest.json index 56f428d8..2c91787 100644 --- a/extensions/test/data/system/display/overscan_no_complete/manifest.json +++ b/extensions/test/data/system/display/overscan_no_complete/manifest.json
@@ -1,5 +1,6 @@ { "name": "overscan", + "manifest_version": 2, "version": "1.0", "description": "Test system.display.overscan* with no complete call", "permissions": ["system.display"],
diff --git a/extensions/test/data/system/memory/manifest.json b/extensions/test/data/system/memory/manifest.json index 50936bd..08bcbc5 100644 --- a/extensions/test/data/system/memory/manifest.json +++ b/extensions/test/data/system/memory/manifest.json
@@ -1,5 +1,6 @@ { "name": "system.memory test", + "manifest_version": 2, "version": "1.0", "description": "Test system.memory API", "permissions": ["system.memory"],
diff --git a/extensions/test/data/system/network/manifest.json b/extensions/test/data/system/network/manifest.json index 3ffb980..b9a42eb 100644 --- a/extensions/test/data/system/network/manifest.json +++ b/extensions/test/data/system/network/manifest.json
@@ -1,5 +1,6 @@ { "name": "chrome.system.network extension", + "manifest_version": 2, "version": "0.1", "description": "end-to-end browser test for chrome.system.network API", "app": {
diff --git a/extensions/test/data/unpacker/empty_default_locale/manifest.json b/extensions/test/data/unpacker/empty_default_locale/manifest.json index 6f43cf249..bfeb7630 100644 --- a/extensions/test/data/unpacker/empty_default_locale/manifest.json +++ b/extensions/test/data/unpacker/empty_default_locale/manifest.json
@@ -1,5 +1,6 @@ { "description": "Default locale can't be empty", + "manifest_version": 2, "name": "empty_default_locale", "default_locale": "", "version": "1.0"
diff --git a/extensions/test/data/unpacker/good_l10n/manifest.json b/extensions/test/data/unpacker/good_l10n/manifest.json index cf2e2a9..0893005 100644 --- a/extensions/test/data/unpacker/good_l10n/manifest.json +++ b/extensions/test/data/unpacker/good_l10n/manifest.json
@@ -1,5 +1,6 @@ { "description": "All is well", + "manifest_version": 2, "name": "good_l10n", "default_locale": "sr", "version": "1.0"
diff --git a/extensions/test/data/unpacker/has_default_missing_locales/manifest.json b/extensions/test/data/unpacker/has_default_missing_locales/manifest.json index e572fc2f..1dbc1307 100644 --- a/extensions/test/data/unpacker/has_default_missing_locales/manifest.json +++ b/extensions/test/data/unpacker/has_default_missing_locales/manifest.json
@@ -1,5 +1,6 @@ { "description": "Cannot have default_locale but skip _locales", + "manifest_version": 2, "name": "has_default_missing_locales", "default_locale": "en_US", "version": "1.0"
diff --git a/extensions/test/data/unpacker/invalid_default_locale/manifest.json b/extensions/test/data/unpacker/invalid_default_locale/manifest.json index ecf7d82..bef2d5c 100644 --- a/extensions/test/data/unpacker/invalid_default_locale/manifest.json +++ b/extensions/test/data/unpacker/invalid_default_locale/manifest.json
@@ -1,5 +1,6 @@ { "description": "Default locale has to be string and can't be empty", + "manifest_version": 2, "name": "invalid_default_locale", "default_locale": 5, "version": "1.0"
diff --git a/extensions/test/data/unpacker/invalid_messages_file/manifest.json b/extensions/test/data/unpacker/invalid_messages_file/manifest.json index 7a4b9efb..7e946e60 100644 --- a/extensions/test/data/unpacker/invalid_messages_file/manifest.json +++ b/extensions/test/data/unpacker/invalid_messages_file/manifest.json
@@ -1,5 +1,6 @@ { "description": "Fail if messages.json is not valid (check JSON syntax only)", + "manifest_version": 2, "name": "invalid_messages_file", "default_locale": "en_US", "version": "1.0"
diff --git a/extensions/test/data/unpacker/missing_default_data/manifest.json b/extensions/test/data/unpacker/missing_default_data/manifest.json index 03ecc4a..a4d2a22 100644 --- a/extensions/test/data/unpacker/missing_default_data/manifest.json +++ b/extensions/test/data/unpacker/missing_default_data/manifest.json
@@ -1,5 +1,6 @@ { "description": "Data for default_locale has to be present", + "manifest_version": 2, "name": "missing_default_data", "default_locale": "sr", "version": "1.0"
diff --git a/extensions/test/data/unpacker/missing_default_has_locales/manifest.json b/extensions/test/data/unpacker/missing_default_has_locales/manifest.json index 13a5d4b2..c84616c 100644 --- a/extensions/test/data/unpacker/missing_default_has_locales/manifest.json +++ b/extensions/test/data/unpacker/missing_default_has_locales/manifest.json
@@ -1,5 +1,6 @@ { "description": "If _locales is present, default_locale has to be defined too.", + "manifest_version": 2, "name": "missing_default_has_locales", "version": "1.0" }
diff --git a/extensions/test/data/unpacker/missing_messages_file/manifest.json b/extensions/test/data/unpacker/missing_messages_file/manifest.json index a3ccf4b..19994e0 100644 --- a/extensions/test/data/unpacker/missing_messages_file/manifest.json +++ b/extensions/test/data/unpacker/missing_messages_file/manifest.json
@@ -1,5 +1,6 @@ { "description": "Each locale has to have messages.json file", + "manifest_version": 2, "name": "missing_messages_file", "default_locale": "en_US", "version": "1.0"
diff --git a/extensions/test/data/unpacker/no_l10n/manifest.json b/extensions/test/data/unpacker/no_l10n/manifest.json index 8ba809fa93..eec831f 100644 --- a/extensions/test/data/unpacker/no_l10n/manifest.json +++ b/extensions/test/data/unpacker/no_l10n/manifest.json
@@ -1,5 +1,6 @@ { "description": "This extension is not localized.", + "manifest_version": 2, "name": "no_l10n", "version": "1.0" }
diff --git a/extensions/test/data/unpacker/no_locale_data/manifest.json b/extensions/test/data/unpacker/no_locale_data/manifest.json index c4d68b4..3c5e5d6 100644 --- a/extensions/test/data/unpacker/no_locale_data/manifest.json +++ b/extensions/test/data/unpacker/no_locale_data/manifest.json
@@ -1,5 +1,6 @@ { "description": "_locales can't be empty", + "manifest_version": 2, "name": "no_locale_data", "default_locale": "en_US", "version": "1.0"
diff --git a/extensions/test/data/web_view/accept_touch_events/manifest.json b/extensions/test/data/web_view/accept_touch_events/manifest.json index 79c79df..457d5de 100644 --- a/extensions/test/data/web_view/accept_touch_events/manifest.json +++ b/extensions/test/data/web_view/accept_touch_events/manifest.json
@@ -1,5 +1,6 @@ { "name": "<webview> touch handler registration test.", + "manifest_version": 2, "version": "1", "permissions": [ "webview"
diff --git a/extensions/test/data/web_view/close_on_loadcommit/manifest.json b/extensions/test/data/web_view/close_on_loadcommit/manifest.json index 944fa0ee6..9441ab3 100644 --- a/extensions/test/data/web_view/close_on_loadcommit/manifest.json +++ b/extensions/test/data/web_view/close_on_loadcommit/manifest.json
@@ -1,5 +1,6 @@ { "name": "<webview> close on loadcommit", + "manifest_version": 2, "version": "1", "permissions": [ "webview"
diff --git a/extensions/test/data/web_view/display_none_set_src/manifest.json b/extensions/test/data/web_view/display_none_set_src/manifest.json index 1413e28b..9e0c096 100644 --- a/extensions/test/data/web_view/display_none_set_src/manifest.json +++ b/extensions/test/data/web_view/display_none_set_src/manifest.json
@@ -1,5 +1,6 @@ { "name": "<webview> check set src multiple times while display: none.", + "manifest_version": 2, "version": "1", "permissions": [ "webview"
diff --git a/extensions/test/data/web_view/inside_iframe/manifest.json b/extensions/test/data/web_view/inside_iframe/manifest.json index d76390bc..7067e2b 100644 --- a/extensions/test/data/web_view/inside_iframe/manifest.json +++ b/extensions/test/data/web_view/inside_iframe/manifest.json
@@ -1,5 +1,6 @@ { "name": "<webview> inside iframe.", + "manifest_version": 2, "version": "1", "permissions": [ "webview"
diff --git a/extensions/test/data/web_view/media_access/check/manifest.json b/extensions/test/data/web_view/media_access/check/manifest.json index d7488e98..092aa68 100644 --- a/extensions/test/data/web_view/media_access/check/manifest.json +++ b/extensions/test/data/web_view/media_access/check/manifest.json
@@ -1,5 +1,6 @@ { "name": "Platform App Test: <webview> media", + "manifest_version": 2, "description": "Loads a guest which requests media sources, this triggers checking existing permission", "version": "1", "permissions": [
diff --git a/extensions/test/data/web_view/media_access/deny/manifest.json b/extensions/test/data/web_view/media_access/deny/manifest.json index ea2ad29..990ff99f 100644 --- a/extensions/test/data/web_view/media_access/deny/manifest.json +++ b/extensions/test/data/web_view/media_access/deny/manifest.json
@@ -1,5 +1,6 @@ { "name": "Platform App Test: <webview> media", + "manifest_version": 2, "description": "Loads a guest which requests media access permission", "version": "1", "permissions": [
diff --git a/extensions/test/data/web_view/visibility_changed/manifest.json b/extensions/test/data/web_view/visibility_changed/manifest.json index 585c11e..c7b11719 100644 --- a/extensions/test/data/web_view/visibility_changed/manifest.json +++ b/extensions/test/data/web_view/visibility_changed/manifest.json
@@ -1,5 +1,6 @@ { "name": "<webview> visibility checking tests.", + "manifest_version": 2, "version": "1", "permissions": [ "webview"
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 0275bf1..98cc319f 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -8950,8 +8950,12 @@ // These formats have been selected because they are very common or are known // to be used by the WebGL backbuffer. If problems are observed with other // color formats they can be added here. + GLenum pixel_format = GL_RGBA; + GLenum pixel_type = GL_UNSIGNED_BYTE; switch (format) { case GL_RGB8: + pixel_format = GL_RGB; + break; case GL_RGBA8: break; default: @@ -8980,7 +8984,8 @@ // Texture only needs to be 1x1. api()->glBindTextureFn(GL_TEXTURE_2D, validation_texture); - api()->glTexStorage2DEXTFn(GL_TEXTURE_2D, 1, format, 1, 1); + api()->glTexImage2DFn(GL_TEXTURE_2D, 0, format, 1, 1, 0, pixel_format, + pixel_type, NULL); } else { validation_texture = iter->second; }
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index bd41580..846d209f 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -2486,6 +2486,11 @@ << " Main coordinator not created when tab switcher needed."; TabGridCoordinator* tabGridCoordinator = base::mac::ObjCCastStrict<TabGridCoordinator>(self.mainCoordinator); + // Call -restoreInternalState so that the grid shows the correct panel. + [tabGridCoordinator.tabSwitcher + restoreInternalStateWithMainTabModel:self.mainTabModel + otrTabModel:self.otrTabModel + activeTabModel:self.currentTabModel]; return tabGridCoordinator.tabSwitcher; } else { if (IsIPadIdiom()) {
diff --git a/ios/chrome/app/tests_fake_hook.mm b/ios/chrome/app/tests_fake_hook.mm index da4a92e59..f0e7c98 100644 --- a/ios/chrome/app/tests_fake_hook.mm +++ b/ios/chrome/app/tests_fake_hook.mm
@@ -31,6 +31,10 @@ bool ForceUIRefreshPhase1() { return false; } +// TODO(crbug.com/818560) : Remove this hook. +bool ForceTabSwitcherTabGrid() { + return false; +} void SetUpTestsIfPresent() {} void RunTestsIfPresent() {}
diff --git a/ios/chrome/app/tests_hook.h b/ios/chrome/app/tests_hook.h index afd241f..49e875c 100644 --- a/ios/chrome/app/tests_hook.h +++ b/ios/chrome/app/tests_hook.h
@@ -36,6 +36,11 @@ // overriding the flag value. bool ForceUIRefreshPhase1(); +// TODO(crbug.com/818560): Removes this hook. +// Returns true if the tab grid will be displayed as the tab switcher, +// overriding the flag value. +bool ForceTabSwitcherTabGrid(); + // Global integration tests setup. This is not used by EarlGrey-based // integration tests. void SetUpTestsIfPresent();
diff --git a/ios/chrome/browser/browser_state/BUILD.gn b/ios/chrome/browser/browser_state/BUILD.gn index 73fa0a2..0a714c9 100644 --- a/ios/chrome/browser/browser_state/BUILD.gn +++ b/ios/chrome/browser/browser_state/BUILD.gn
@@ -81,6 +81,7 @@ "//ios/chrome/browser/bookmarks", "//ios/chrome/browser/browser_state_metrics", "//ios/chrome/browser/browsing_data", + "//ios/chrome/browser/consent_auditor", "//ios/chrome/browser/content_settings", "//ios/chrome/browser/desktop_promotion", "//ios/chrome/browser/dom_distiller",
diff --git a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm index 62631bf..d185b84 100644 --- a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm +++ b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
@@ -12,6 +12,7 @@ #include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" #include "ios/chrome/browser/bookmarks/startup_task_runner_service_factory.h" #include "ios/chrome/browser/browsing_data/browsing_data_remover_factory.h" +#include "ios/chrome/browser/consent_auditor/consent_auditor_factory.h" #include "ios/chrome/browser/content_settings/cookie_settings_factory.h" #include "ios/chrome/browser/desktop_promotion/desktop_promotion_sync_service_factory.h" #include "ios/chrome/browser/dom_distiller/dom_distiller_service_factory.h" @@ -103,6 +104,7 @@ BrowserListFactory::GetInstance(); BrowserListSessionServiceFactory::GetInstance(); BrowsingDataRemoverFactory::GetInstance(); + ConsentAuditorFactory::GetInstance(); DesktopPromotionSyncServiceFactory::GetInstance(); feature_engagement::TrackerFactory::GetInstance(); IOSChromeGCMProfileServiceFactory::GetInstance();
diff --git a/ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.cc b/ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.cc index cf20f4d..007fc3a 100644 --- a/ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.cc +++ b/ios/chrome/browser/browser_state/chrome_browser_state_manager_impl.cc
@@ -40,6 +40,7 @@ #include "ios/chrome/browser/signin/gaia_cookie_manager_service_factory.h" #include "ios/chrome/browser/signin/signin_manager_factory.h" #include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h" +#include "ios/chrome/browser/sync/ios_user_event_service_factory.h" namespace { @@ -223,6 +224,10 @@ ->SetupInvalidationsOnProfileLoad(invalidation_service); ios::AccountReconcilorFactory::GetForBrowserState(browser_state); DesktopPromotionSyncServiceFactory::GetForBrowserState(browser_state); + // TODO(crbug.com/709094), TODO(crbug.com/761485): Remove this following line + // when UserEventService will be initialized synchronously. Until then, the + // service has to be created as early as possible. + IOSUserEventServiceFactory::GetForBrowserState(browser_state); } void ChromeBrowserStateManagerImpl::AddBrowserStateToCache(
diff --git a/ios/chrome/browser/consent_auditor/BUILD.gn b/ios/chrome/browser/consent_auditor/BUILD.gn new file mode 100644 index 0000000..6a1e61d --- /dev/null +++ b/ios/chrome/browser/consent_auditor/BUILD.gn
@@ -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. + +source_set("consent_auditor") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "consent_auditor_factory.cc", + "consent_auditor_factory.h", + ] + deps = [ + "//base", + "//components/consent_auditor", + "//components/keyed_service/ios", + "//components/pref_registry", + "//components/version_info", + "//ios/chrome/browser", + "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/sync", + "//ios/web/public", + ] +}
diff --git a/ios/chrome/browser/consent_auditor/DEPS b/ios/chrome/browser/consent_auditor/DEPS new file mode 100644 index 0000000..f79e7c6 --- /dev/null +++ b/ios/chrome/browser/consent_auditor/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+components/consent_auditor", +]
diff --git a/ios/chrome/browser/consent_auditor/OWNERS b/ios/chrome/browser/consent_auditor/OWNERS new file mode 100644 index 0000000..ed987e2 --- /dev/null +++ b/ios/chrome/browser/consent_auditor/OWNERS
@@ -0,0 +1,5 @@ +jlebel@chromium.org +msarda@chromium.org +msramek@google.com + +# COMPONENT: Privacy
diff --git a/ios/chrome/browser/consent_auditor/consent_auditor_factory.cc b/ios/chrome/browser/consent_auditor/consent_auditor_factory.cc new file mode 100644 index 0000000..5c85778 --- /dev/null +++ b/ios/chrome/browser/consent_auditor/consent_auditor_factory.cc
@@ -0,0 +1,68 @@ +// 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 "ios/chrome/browser/consent_auditor/consent_auditor_factory.h" + +#include "base/memory/ptr_util.h" +#include "base/memory/singleton.h" +#include "components/consent_auditor/consent_auditor.h" +#include "components/keyed_service/ios/browser_state_dependency_manager.h" +#include "components/pref_registry/pref_registry_syncable.h" +#include "components/version_info/version_info.h" +#include "ios/chrome/browser/application_context.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/sync/ios_user_event_service_factory.h" +#include "ios/web/public/browser_state.h" + +// static +consent_auditor::ConsentAuditor* ConsentAuditorFactory::GetForBrowserState( + ios::ChromeBrowserState* browser_state) { + return static_cast<consent_auditor::ConsentAuditor*>( + GetInstance()->GetServiceForBrowserState(browser_state, true)); +} + +// static +consent_auditor::ConsentAuditor* +ConsentAuditorFactory::GetForBrowserStateIfExists( + ios::ChromeBrowserState* browser_state) { + return static_cast<consent_auditor::ConsentAuditor*>( + GetInstance()->GetServiceForBrowserState(browser_state, false)); +} + +// static +ConsentAuditorFactory* ConsentAuditorFactory::GetInstance() { + return base::Singleton<ConsentAuditorFactory>::get(); +} + +ConsentAuditorFactory::ConsentAuditorFactory() + : BrowserStateKeyedServiceFactory( + "ConsentAuditor", + BrowserStateDependencyManager::GetInstance()) { + DependsOn(IOSUserEventServiceFactory::GetInstance()); +} + +ConsentAuditorFactory::~ConsentAuditorFactory() {} + +std::unique_ptr<KeyedService> ConsentAuditorFactory::BuildServiceInstanceFor( + web::BrowserState* browser_state) const { + ios::ChromeBrowserState* ios_browser_state = + ios::ChromeBrowserState::FromBrowserState(browser_state); + syncer::UserEventService* const user_event_service = + IOSUserEventServiceFactory::GetForBrowserState(ios_browser_state); + return std::make_unique<consent_auditor::ConsentAuditor>( + ios_browser_state->GetPrefs(), user_event_service, + // The browser version and locale do not change runtime, so we can pass + // them directly. + version_info::GetVersionNumber(), + GetApplicationContext()->GetApplicationLocale()); +} + +bool ConsentAuditorFactory::ServiceIsNULLWhileTesting() const { + return true; +} + +void ConsentAuditorFactory::RegisterBrowserStatePrefs( + user_prefs::PrefRegistrySyncable* registry) { + consent_auditor::ConsentAuditor::RegisterProfilePrefs(registry); +}
diff --git a/ios/chrome/browser/consent_auditor/consent_auditor_factory.h b/ios/chrome/browser/consent_auditor/consent_auditor_factory.h new file mode 100644 index 0000000..df19cf1 --- /dev/null +++ b/ios/chrome/browser/consent_auditor/consent_auditor_factory.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_CONSENT_AUDITOR_CONSENT_AUDITOR_FACTORY_H_ +#define IOS_CHROME_BROWSER_CONSENT_AUDITOR_CONSENT_AUDITOR_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "components/keyed_service/ios/browser_state_keyed_service_factory.h" + +namespace consent_auditor { +class ConsentAuditor; +} // namespace consent_auditor + +namespace ios { +class ChromeBrowserState; +} // namespace ios + +// Singleton that owns all ConsentAuditors and associates them with +// ios::ChromeBrowserState. +class ConsentAuditorFactory : public BrowserStateKeyedServiceFactory { + public: + static consent_auditor::ConsentAuditor* GetForBrowserState( + ios::ChromeBrowserState* browser_state); + static consent_auditor::ConsentAuditor* GetForBrowserStateIfExists( + ios::ChromeBrowserState* browser_state); + static ConsentAuditorFactory* GetInstance(); + + private: + friend struct base::DefaultSingletonTraits<ConsentAuditorFactory>; + + ConsentAuditorFactory(); + ~ConsentAuditorFactory() override; + + // BrowserStateKeyedServiceFactory implementation. + std::unique_ptr<KeyedService> BuildServiceInstanceFor( + web::BrowserState* context) const override; + bool ServiceIsNULLWhileTesting() const override; + void RegisterBrowserStatePrefs( + user_prefs::PrefRegistrySyncable* registry) override; + + DISALLOW_COPY_AND_ASSIGN(ConsentAuditorFactory); +}; + +#endif // IOS_CHROME_BROWSER_CONSENT_AUDITOR_CONSENT_AUDITOR_FACTORY_H_
diff --git a/ios/chrome/browser/prefs/BUILD.gn b/ios/chrome/browser/prefs/BUILD.gn index 5688c72d..9ad04fe2 100644 --- a/ios/chrome/browser/prefs/BUILD.gn +++ b/ios/chrome/browser/prefs/BUILD.gn
@@ -60,6 +60,7 @@ "//components/web_resource", "//ios/chrome/browser", "//ios/chrome/browser/browser_state", + "//ios/chrome/browser/consent_auditor", "//ios/chrome/browser/desktop_promotion", "//ios/chrome/browser/first_run", "//ios/chrome/browser/geolocation",
diff --git a/ios/chrome/browser/sync/ios_chrome_sync_client.mm b/ios/chrome/browser/sync/ios_chrome_sync_client.mm index d0d6528d..7ecdcde 100644 --- a/ios/chrome/browser/sync/ios_chrome_sync_client.mm +++ b/ios/chrome/browser/sync/ios_chrome_sync_client.mm
@@ -11,7 +11,6 @@ #include "base/logging.h" #include "base/macros.h" #include "components/autofill/core/browser/webdata/autocomplete_sync_bridge.h" -#include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.h" #include "components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h" @@ -271,17 +270,12 @@ return browser_state_->GetSyncablePrefs() ->GetSyncableService(syncer::PRIORITY_PREFERENCES) ->AsWeakPtr(); - case syncer::AUTOFILL: case syncer::AUTOFILL_PROFILE: case syncer::AUTOFILL_WALLET_DATA: case syncer::AUTOFILL_WALLET_METADATA: { if (!web_data_service_) return base::WeakPtr<syncer::SyncableService>(); - if (type == syncer::AUTOFILL) { - return autofill::AutocompleteSyncableService::FromWebDataService( - web_data_service_.get()) - ->AsWeakPtr(); - } else if (type == syncer::AUTOFILL_PROFILE) { + if (type == syncer::AUTOFILL_PROFILE) { return autofill::AutofillProfileSyncableService::FromWebDataService( web_data_service_.get()) ->AsWeakPtr();
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn index e79bde3..b04e255f 100644 --- a/ios/chrome/browser/ui/authentication/BUILD.gn +++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -34,6 +34,7 @@ "resources:signin_confirmation_more", "resources:signin_promo_close_gray", "//base", + "//components/consent_auditor", "//components/google/core/browser", "//components/infobars/core", "//components/prefs", @@ -46,6 +47,7 @@ "//ios/chrome/browser", "//ios/chrome/browser/browser_state", "//ios/chrome/browser/browsing_data", + "//ios/chrome/browser/consent_auditor", "//ios/chrome/browser/infobars", "//ios/chrome/browser/signin", "//ios/chrome/browser/sync",
diff --git a/ios/chrome/browser/ui/authentication/DEPS b/ios/chrome/browser/ui/authentication/DEPS new file mode 100644 index 0000000..f79e7c6 --- /dev/null +++ b/ios/chrome/browser/ui/authentication/DEPS
@@ -0,0 +1,3 @@ +include_rules = [ + "+components/consent_auditor", +]
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm index b6afaab..ad75236 100644 --- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -18,10 +18,12 @@ #import "base/strings/sys_string_conversions.h" #include "base/timer/elapsed_timer.h" #include "base/timer/timer.h" +#include "components/consent_auditor/consent_auditor.h" #include "components/signin/core/browser/signin_metrics.h" #include "components/strings/grit/components_strings.h" #import "ios/chrome/browser/browser_state/chrome_browser_state.h" #include "ios/chrome/browser/chrome_url_constants.h" +#include "ios/chrome/browser/consent_auditor/consent_auditor_factory.h" #import "ios/chrome/browser/signin/authentication_service.h" #import "ios/chrome/browser/signin/authentication_service_factory.h" #import "ios/chrome/browser/signin/chrome_identity_service_observer_bridge.h" @@ -229,6 +231,15 @@ - (void)acceptSignInAndShowAccountsSettings:(BOOL)showAccountsSettings { signin_metrics::LogSigninAccessPointCompleted(_accessPoint, _promoAction); + DCHECK(_confirmationVC); + const std::vector<int>& consent_text_ids = _confirmationVC.consentStringIds; + int consent_confirmation_id = showAccountsSettings + ? _confirmationVC.openSettingsStringId + : [self acceptSigninButtonStringId]; + ConsentAuditorFactory::GetForBrowserState(_browserState) + ->RecordGaiaConsent(consent_auditor::Feature::CHROME_SYNC, + consent_text_ids, consent_confirmation_id, + consent_auditor::ConsentStatus::GIVEN); _didAcceptSignIn = YES; if (!_didFinishSignIn) { _didFinishSignIn = YES; @@ -285,9 +296,12 @@ return l10n_util::GetNSString(IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_TITLE); } +- (int)acceptSigninButtonStringId { + return IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON; +} + - (NSString*)acceptSigninButtonTitle { - return l10n_util::GetNSString( - IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OK_BUTTON); + return l10n_util::GetNSString([self acceptSigninButtonStringId]); } - (NSString*)skipSigninButtonTitle {
diff --git a/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.h b/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.h index 2cdf2c2..51766eb 100644 --- a/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.h +++ b/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.h
@@ -7,6 +7,8 @@ #import <UIKit/UIKit.h> +#include <vector> + #import "ios/chrome/browser/ui/collection_view/collection_view_controller.h" extern NSString* const kSigninConfirmationCollectionViewId; @@ -30,6 +32,12 @@ // Controller of the sign-in confirmation collection view. @interface SigninConfirmationViewController : CollectionViewController +@property(nonatomic, weak) id<SigninConfirmationViewControllerDelegate> + delegate; + +// String id for text to open the settings. +@property(nonatomic, readonly) int openSettingsStringId; + - (instancetype)initWithIdentity:(ChromeIdentity*)identity NS_DESIGNATED_INITIALIZER; @@ -40,8 +48,9 @@ // Scrolls the confirmation view to the bottom of its content. - (void)scrollToBottom; -@property(nonatomic, weak) id<SigninConfirmationViewControllerDelegate> - delegate; +// List of string ids used for the user consent. The string ids order matches +// the way they appear on the screen. +- (const std::vector<int>&)consentStringIds; @end
diff --git a/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.mm b/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.mm index 1c512b5..d1a5dce 100644 --- a/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/signin_confirmation_view_controller.mm
@@ -87,6 +87,9 @@ UIImageView* _imageView; UILabel* _titleLabel; UILabel* _emailLabel; + // List of string ids used for the user consent. The string ids order matches + // the way they appear on the screen. + std::vector<int> _consentStringIds; } @end @@ -113,6 +116,14 @@ [self.collectionView setContentOffset:bottomOffset animated:YES]; } +- (const std::vector<int>&)consentStringIds { + return _consentStringIds; +} + +- (int)openSettingsStringId { + return IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OPEN_SETTINGS; +} + #pragma mark - UIViewController - (void)viewDidLoad { @@ -253,10 +264,11 @@ - (CollectionViewItem*)syncItem { AccountControlItem* item = [[AccountControlItem alloc] initWithType:ItemTypeSync]; - item.text = l10n_util::GetNSString( - IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SYNC_TITLE); - item.detailText = l10n_util::GetNSString( - IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SYNC_DESCRIPTION); + item.text = [self localizedConsentStringWithId: + IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SYNC_TITLE]; + item.detailText = + [self localizedConsentStringWithId: + IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SYNC_DESCRIPTION]; item.image = ios::GetChromeBrowserProvider() ->GetBrandedImageProvider() ->GetSigninConfirmationSyncSettingsImage(); @@ -266,10 +278,12 @@ - (CollectionViewItem*)googleServicesItem { AccountControlItem* item = [[AccountControlItem alloc] initWithType:ItemTypeGoogleServices]; - item.text = l10n_util::GetNSString( - IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SERVICES_TITLE); - item.detailText = l10n_util::GetNSString( - IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SERVICES_DESCRIPTION); + item.text = + [self localizedConsentStringWithId: + IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SERVICES_TITLE]; + item.detailText = + [self localizedConsentStringWithId: + IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_SERVICES_DESCRIPTION]; item.image = ios::GetChromeBrowserProvider() ->GetBrandedImageProvider() ->GetSigninConfirmationPersonalizeServicesImage(); @@ -279,8 +293,7 @@ - (CollectionViewItem*)openSettingsItem { CollectionViewFooterItem* item = [[CollectionViewFooterItem alloc] initWithType:ItemTypeFooter]; - item.text = l10n_util::GetNSString( - IDS_IOS_ACCOUNT_CONSISTENCY_CONFIRMATION_OPEN_SETTINGS); + item.text = [self localizedConsentStringWithId:self.openSettingsStringId]; item.linkURL = google_util::AppendGoogleLocaleParam( GURL("internal://settings-sync"), GetApplicationContext()->GetApplicationLocale()); @@ -304,6 +317,13 @@ return NO; } +// Adds the string id to the list of string for the user consent, and returns +// the NSString related to the string id. +- (NSString*)localizedConsentStringWithId:(int)stringId { + _consentStringIds.push_back(stringId); + return l10n_util::GetNSString(stringId); +} + #pragma mark - ChromeIdentityServiceObserver - (void)profileUpdate:(ChromeIdentity*)identity {
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn index 2085060..fe1f7d8 100644 --- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -115,6 +115,7 @@ ":content_suggestions_ui_util", "resources:content_suggestions_no_image", "resources:content_suggestions_offline", + "resources:ntp_search_icon", "//base", "//components/strings", "//ios/chrome/browser/ui",
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_cell.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_cell.mm index cfdc42f..437e146e 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_cell.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_action_cell.mm
@@ -41,8 +41,9 @@ self = [super initWithFrame:frame]; if (self) { _titleLabel = [[UILabel alloc] init]; - _titleLabel.textColor = [UIColor colorWithWhite:kLabelTextColor alpha:1.0]; - _titleLabel.font = [MDCTypography captionFont]; + _titleLabel.textColor = [UIColor colorWithWhite:0 alpha:kTitleAlpha]; + _titleLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]; _titleLabel.textAlignment = NSTextAlignmentCenter; _titleLabel.preferredMaxLayoutWidth = [[self class] defaultSize].width; _titleLabel.numberOfLines = kLabelNumLines;
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_cell.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_cell.mm index a157c43..9293b38b 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_cell.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_cell.mm
@@ -31,14 +31,26 @@ self = [super initWithFrame:frame]; if (self) { _titleLabel = [[UILabel alloc] init]; - _titleLabel.textColor = [UIColor colorWithWhite:kLabelTextColor alpha:1.0]; - _titleLabel.font = [MDCTypography captionFont]; + if (IsUIRefreshPhase1Enabled()) { + _titleLabel.textColor = [UIColor colorWithWhite:0 alpha:kTitleAlpha]; + _titleLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleCaption1]; + } else { + _titleLabel.textColor = + [UIColor colorWithWhite:kLabelTextColor alpha:1.0]; + _titleLabel.font = [MDCTypography captionFont]; + } _titleLabel.textAlignment = NSTextAlignmentCenter; _titleLabel.preferredMaxLayoutWidth = [[self class] defaultSize].width; _titleLabel.numberOfLines = kLabelNumLines; _faviconView = [[FaviconViewNew alloc] init]; - _faviconView.font = [MDCTypography headlineFont]; + if (IsUIRefreshPhase1Enabled()) { + _faviconView.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleTitle2]; + } else { + _faviconView.font = [MDCTypography headlineFont]; + } _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; _faviconView.translatesAutoresizingMaskIntoConstraints = NO;
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_constants.h b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_constants.h index 30c6651..947ff84 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_constants.h +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_constants.h
@@ -22,4 +22,7 @@ // Size of a Most Visited cell. extern const CGSize kCellSize; +// The alpha value for text. +extern const CGFloat kTitleAlpha; + #endif // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_CELLS_CONTENT_SUGGESTIONS_MOST_VISITED_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_constants.mm b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_constants.mm index 844593cb..8d30ced 100644 --- a/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_constants.mm +++ b/ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_constants.mm
@@ -13,3 +13,4 @@ const NSInteger kLabelNumLines = 2; const CGFloat kSpaceIconTitle = 10; const CGSize kCellSize = {73, 100}; +const CGFloat kTitleAlpha = 0.41;
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h index 7c619504..1763468 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h
@@ -11,6 +11,8 @@ extern const CGFloat kSearchFieldHeight; +extern const int kSearchFieldBackgroundColor; + // Returns the maximum number of tiles fitting in |availableWidth|, limited to // 4. NSUInteger numberOfTilesForWidth(CGFloat availableWidth);
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm index aad5e08..f75ba76 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.mm
@@ -11,6 +11,7 @@ #import "ios/chrome/browser/ui/location_bar/location_bar_constants.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" #include "ios/chrome/browser/ui/ui_util.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" #include "ios/chrome/grit/ios_strings.h" #import "ios/third_party/material_components_ios/src/components/Typography/src/MaterialTypography.h" #include "ui/base/l10n/l10n_util.h" @@ -20,28 +21,53 @@ #endif namespace { + +// Spacing between tiles. const CGFloat kSpacingIPhone = 16; const CGFloat kSpacingIPad = 24; -const CGFloat kMinSearchFieldWidth = 50; +// Width of search field. +const CGFloat kSearchFieldLarge = 432; +const CGFloat kSearchFieldSmall = 343; +const CGFloat kSearchFieldMinMargin = 8; +const CGFloat kMinSearchFieldWidthLegacy = 50; +// Veritcla margin of search hint text. const CGFloat kSearchHintMargin = 3; + // Offset to align the hint of the fake omnibox with the one in the toolbar. const CGFloat kSearchHintVerticalOffset = 0.5; - +// Maximum margin for the search field. const CGFloat kMaxSearchFieldFrameMargin = 200; -const CGFloat kDoodleTopMarginIPad = 82; -const CGFloat kSearchFieldTopMarginIPhone = 32; -const CGFloat kSearchFieldTopMarginIPad = 82; + +// Top margin for the doodle. +const CGFloat kDoodleTopMarginRegularXRegular = 162; +const CGFloat kDoodleTopMarginOther = 48; +const CGFloat kDoodleTopMarginIPadLegacy = 82; + +// Top margin for the search field +const CGFloat kSearchFieldTopMargin = 32; +const CGFloat kSearchFieldTopMarginIPhoneLegacy = 32; +const CGFloat kSearchFieldTopMarginIPadLegacy = 82; + +// Bottom margin for the search field. const CGFloat kNTPSearchFieldBottomPadding = 16; +// Alpha for search hint text. +const CGFloat kHintAlpha = 0.3; + const CGFloat kTopSpacingMaterial = 24; const CGFloat kVoiceSearchButtonWidth = 48; -const CGFloat kGoogleSearchDoodleHeight = 120; +// Height for the doodle frame. +const CGFloat kGoogleSearchDoodleHeightRegularXRegular = 85; +const CGFloat kGoogleSearchDoodleHeightOther = 68; +const CGFloat kGoogleSearchDoodleHeightLegacy = 120; + // Height for the doodle frame when Google is not the default search engine. const CGFloat kNonGoogleSearchDoodleHeight = 60; + // Height for the header view on tablet when Google is not the default search // engine. const CGFloat kNonGoogleSearchHeaderHeightIPad = 10; @@ -57,6 +83,7 @@ namespace content_suggestions { const CGFloat kSearchFieldHeight = 50; +const int kSearchFieldBackgroundColor = 0xF1F3F4; const NSUInteger kMostVisitedItemsPerLine = 4; @@ -100,26 +127,48 @@ CGFloat doodleHeight(BOOL logoIsShowing) { if (!IsIPadIdiom() && !logoIsShowing) return kNonGoogleSearchDoodleHeight; - return kGoogleSearchDoodleHeight; + + if (IsUIRefreshPhase1Enabled()) { + if (!IsCompactWidth() && !IsCompactHeight()) + return kGoogleSearchDoodleHeightRegularXRegular; + return kGoogleSearchDoodleHeightOther; + } + + return kGoogleSearchDoodleHeightLegacy; } CGFloat doodleTopMargin(BOOL toolbarPresent) { + if (IsUIRefreshPhase1Enabled()) { + if (!IsCompactWidth() && !IsCompactHeight()) + return kDoodleTopMarginRegularXRegular; + return kDoodleTopMarginOther; + } if (IsIPadIdiom()) - return kDoodleTopMarginIPad; - return toolbarPresent ? ntp_header::kToolbarHeight : 0; + return kDoodleTopMarginIPadLegacy; + return toolbarPresent ? ntp_header::ToolbarHeight() : 0; } CGFloat searchFieldTopMargin() { + if (IsUIRefreshPhase1Enabled()) { + return kSearchFieldTopMargin; + } if (IsIPadIdiom()) - return kSearchFieldTopMarginIPad; - return kSearchFieldTopMarginIPhone; + return kSearchFieldTopMarginIPadLegacy; + return kSearchFieldTopMarginIPhoneLegacy; } CGFloat searchFieldWidth(CGFloat superviewWidth) { + if (IsUIRefreshPhase1Enabled()) { + if (!IsCompactWidth() && !IsCompactHeight()) + return kSearchFieldLarge; + + // Special case for narrow sizes. + return MIN(kSearchFieldSmall, superviewWidth - kSearchFieldMinMargin * 2); + } CGFloat margin = centeredTilesMarginForWidth(superviewWidth); if (margin > kMaxSearchFieldFrameMargin) margin = kMaxSearchFieldFrameMargin; - return fmax(superviewWidth - 2 * margin, kMinSearchFieldWidth); + return fmax(superviewWidth - 2 * margin, kMinSearchFieldWidthLegacy); } CGFloat heightForLogoHeader(BOOL logoIsShowing, @@ -147,23 +196,37 @@ [searchTapTarget addSubview:searchHintLabel]; - [NSLayoutConstraint activateConstraints:@[ - [searchHintLabel.heightAnchor - constraintEqualToConstant:kSearchFieldHeight - 2 * kSearchHintMargin], - [searchHintLabel.centerYAnchor - constraintEqualToAnchor:searchTapTarget.centerYAnchor - constant:kSearchHintVerticalOffset] - ]]; + if (IsUIRefreshPhase1Enabled()) { + [NSLayoutConstraint activateConstraints:@[ + [searchHintLabel.centerYAnchor + constraintEqualToAnchor:searchTapTarget.centerYAnchor] + ]]; + } else { + [NSLayoutConstraint activateConstraints:@[ + [searchHintLabel.heightAnchor + constraintEqualToConstant:kSearchFieldHeight - 2 * kSearchHintMargin], + [searchHintLabel.centerYAnchor + constraintEqualToAnchor:searchTapTarget.centerYAnchor + constant:kSearchHintVerticalOffset] + ]]; + } [searchHintLabel setText:l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT)]; if (base::i18n::IsRTL()) { [searchHintLabel setTextAlignment:NSTextAlignmentRight]; } - [searchHintLabel - setTextColor: - [UIColor colorWithWhite:kiPhoneLocationBarPlaceholderColorBrightness - alpha:1.0]]; - [searchHintLabel setFont:[MDCTypography subheadFont]]; + if (IsUIRefreshPhase1Enabled()) { + [searchHintLabel setTextColor:[UIColor colorWithWhite:0 alpha:kHintAlpha]]; + searchHintLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleTitle3]; + searchHintLabel.adjustsFontSizeToFitWidth = YES; + } else { + [searchHintLabel + setTextColor: + [UIColor colorWithWhite:kiPhoneLocationBarPlaceholderColorBrightness + alpha:1.0]]; + [searchHintLabel setFont:[MDCTypography subheadFont]]; + } } void configureVoiceSearchButton(UIButton* voiceSearchButton,
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 bb51e62d..04902648 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
@@ -6,6 +6,7 @@ #include <memory> +#include "ios/chrome/browser/ui/ui_util.h" #import "ios/chrome/test/base/scoped_block_swizzler.h" #include "testing/platform_test.h" #import "third_party/ocmock/OCMock/OCMock.h" @@ -84,9 +85,14 @@ CGFloat topMarginNoToolbar = doodleTopMargin(NO); // Test. - EXPECT_EQ(120, height); - EXPECT_EQ(82, topMargin); - EXPECT_EQ(82, topMarginNoToolbar); + if (IsUIRefreshPhase1Enabled()) { + EXPECT_EQ(68, height); + EXPECT_EQ(48, topMargin); + } else { + EXPECT_EQ(120, height); + EXPECT_EQ(82, topMargin); + EXPECT_EQ(82, topMarginNoToolbar); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, doodleFrameIPhonePortrait) { @@ -101,10 +107,16 @@ CGFloat topMarginNoToolbar = doodleTopMargin(NO); // Test. - EXPECT_EQ(120, heightLogo); - EXPECT_EQ(60, heightNoLogo); - EXPECT_EQ(56, topMargin); - EXPECT_EQ(0, topMarginNoToolbar); + if (IsUIRefreshPhase1Enabled()) { + EXPECT_EQ(68, heightLogo); + EXPECT_EQ(60, heightNoLogo); + EXPECT_EQ(48, topMargin); + } else { + EXPECT_EQ(120, heightLogo); + EXPECT_EQ(60, heightNoLogo); + EXPECT_EQ(56, topMargin); + EXPECT_EQ(0, topMarginNoToolbar); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, doodleFrameIPhoneLandscape) { @@ -119,10 +131,16 @@ CGFloat topMarginNoToolbar = doodleTopMargin(NO); // Test. - EXPECT_EQ(120, heightLogo); - EXPECT_EQ(60, heightNoLogo); - EXPECT_EQ(56, topMargin); - EXPECT_EQ(0, topMarginNoToolbar); + if (IsUIRefreshPhase1Enabled()) { + EXPECT_EQ(68, heightLogo); + EXPECT_EQ(60, heightNoLogo); + EXPECT_EQ(48, topMargin); + } else { + EXPECT_EQ(120, heightLogo); + EXPECT_EQ(60, heightNoLogo); + EXPECT_EQ(56, topMargin); + EXPECT_EQ(0, topMarginNoToolbar); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, searchFieldFrameIPad) { @@ -138,9 +156,15 @@ CGFloat topMargin = searchFieldTopMargin(); // Test. - EXPECT_EQ(82, topMargin); - EXPECT_EQ(width - 2 * margin, resultWidth); - EXPECT_EQ(largeIPadWidth - 400, resultWidthLargeIPad); + if (IsUIRefreshPhase1Enabled()) { + EXPECT_EQ(32, topMargin); + EXPECT_EQ(343, resultWidth); + EXPECT_EQ(343, resultWidthLargeIPad); + } else { + EXPECT_EQ(82, topMargin); + EXPECT_EQ(width - 2 * margin, resultWidth); + EXPECT_EQ(largeIPadWidth - 400, resultWidthLargeIPad); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, searchFieldFrameIPhonePortrait) { @@ -155,8 +179,13 @@ CGFloat topMargin = searchFieldTopMargin(); // Test. - EXPECT_EQ(32, topMargin); - EXPECT_EQ(width - 2 * margin, resultWidth); + if (IsUIRefreshPhase1Enabled()) { + EXPECT_EQ(32, topMargin); + EXPECT_EQ(343, resultWidth); + } else { + EXPECT_EQ(32, topMargin); + EXPECT_EQ(width - 2 * margin, resultWidth); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, searchFieldFrameIPhoneLandscape) { @@ -171,8 +200,13 @@ CGFloat topMargin = searchFieldTopMargin(); // Test. - EXPECT_EQ(32, topMargin); - EXPECT_EQ(width - 2 * margin, resultWidth); + if (IsUIRefreshPhase1Enabled()) { + EXPECT_EQ(32, topMargin); + EXPECT_EQ(343, resultWidth); + } else { + EXPECT_EQ(32, topMargin); + EXPECT_EQ(width - 2 * margin, resultWidth); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, heightForLogoHeaderIPad) { @@ -180,10 +214,17 @@ SetAsIPad(); // Action, tests. - EXPECT_EQ(350, heightForLogoHeader(YES, YES, YES)); - EXPECT_EQ(374, heightForLogoHeader(YES, NO, YES)); - EXPECT_EQ(350, heightForLogoHeader(YES, YES, NO)); - EXPECT_EQ(374, heightForLogoHeader(YES, NO, NO)); + 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)); + } else { + EXPECT_EQ(350, heightForLogoHeader(YES, YES, YES)); + EXPECT_EQ(374, heightForLogoHeader(YES, NO, YES)); + EXPECT_EQ(350, heightForLogoHeader(YES, YES, NO)); + EXPECT_EQ(374, heightForLogoHeader(YES, NO, NO)); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, heightForLogoHeaderIPhone) { @@ -191,10 +232,17 @@ SetAsIPhone(); // Action, tests. - EXPECT_EQ(274, heightForLogoHeader(YES, YES, YES)); - EXPECT_EQ(274, heightForLogoHeader(YES, NO, YES)); - EXPECT_EQ(218, heightForLogoHeader(YES, YES, NO)); - EXPECT_EQ(218, heightForLogoHeader(YES, NO, NO)); + 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)); + } else { + EXPECT_EQ(274, heightForLogoHeader(YES, YES, YES)); + EXPECT_EQ(274, heightForLogoHeader(YES, NO, YES)); + EXPECT_EQ(218, heightForLogoHeader(YES, YES, NO)); + EXPECT_EQ(218, heightForLogoHeader(YES, NO, NO)); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, SizeIPhone6) { @@ -210,7 +258,11 @@ SetAsIPhone(); // Test. - EXPECT_EQ(3U, numberOfTilesForWidth(320)); + if (IsUIRefreshPhase1Enabled()) { + EXPECT_EQ(4U, numberOfTilesForWidth(320)); + } else { + EXPECT_EQ(3U, numberOfTilesForWidth(320)); + } } // Test for iPad portrait and iPhone landscape. @@ -224,7 +276,11 @@ SetAsIPad(); // Test. - EXPECT_EQ(3U, numberOfTilesForWidth(360)); + if (IsUIRefreshPhase1Enabled()) { + EXPECT_EQ(4U, numberOfTilesForWidth(360)); + } else { + EXPECT_EQ(3U, numberOfTilesForWidth(360)); + } } TEST_F(ContentSuggestionsCollectionUtilsTest, NearestAncestor) {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm index fb97a24a..4ca63580 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_synchronizer.mm
@@ -168,7 +168,8 @@ } - (void)updateFakeOmniboxOnNewWidth:(CGFloat)width { - if (self.shouldAnimateHeader && !IsIPadIdiom()) { + if (self.shouldAnimateHeader && + (IsUIRefreshPhase1Enabled() || !IsIPadIdiom())) { [self.headerController updateFakeOmniboxForOffset:self.collectionView.contentOffset.y screenWidth:width
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm index b1b53a3..b7d98af 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view.mm
@@ -14,14 +14,23 @@ #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_constants.h" #import "ios/chrome/browser/ui/toolbar/toolbar_snapshot_providing.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/util/constraints_ui_util.h" #import "ios/chrome/browser/ui/util/named_guide.h" +#import "ui/gfx/ios/NSString+CrStringDrawing.h" #import "ui/gfx/ios/uikit_util.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif +namespace { + +// Left margin for search icon. +const CGFloat kSearchIconLeftMargin = 9; + +} // namespace + @interface ContentSuggestionsHeaderView ()<ToolbarSnapshotProviding> // Layout constraints for fake omnibox background image. @@ -82,16 +91,17 @@ UIView* backgroundContainer = [[UIView alloc] init]; backgroundContainer.userInteractionEnabled = NO; backgroundContainer.backgroundColor = - [UIColor colorWithWhite:0 alpha:kAdaptiveLocationBarBackgroundAlpha]; + UIColorFromRGB(content_suggestions::kSearchFieldBackgroundColor); backgroundContainer.layer.cornerRadius = kAdaptiveLocationBarCornerRadius; - [searchField addSubview:backgroundContainer]; + [searchField insertSubview:backgroundContainer atIndex:1]; + backgroundContainer.translatesAutoresizingMaskIntoConstraints = NO; self.backgroundLeadingConstraint = [backgroundContainer.leadingAnchor constraintEqualToAnchor:searchField.leadingAnchor]; self.backgroundTrailingConstraint = [backgroundContainer.trailingAnchor constraintEqualToAnchor:searchField.trailingAnchor]; - self.backgroundHeightConstraint = - [backgroundContainer.heightAnchor constraintEqualToConstant:0]; + self.backgroundHeightConstraint = [backgroundContainer.heightAnchor + constraintEqualToConstant:content_suggestions::kSearchFieldHeight]; [NSLayoutConstraint activateConstraints:@[ [backgroundContainer.centerYAnchor constraintEqualToAnchor:searchField.centerYAnchor], @@ -100,7 +110,17 @@ self.backgroundHeightConstraint, ]]; - // TODO(crbug.com/805644) Update fake omnibox theme. + UIImage* search_icon = [UIImage imageNamed:@"ntp_search_icon"]; + UIImageView* search_view = [[UIImageView alloc] initWithImage:search_icon]; + [searchField addSubview:search_view]; + search_view.translatesAutoresizingMaskIntoConstraints = NO; + [NSLayoutConstraint activateConstraints:@[ + [search_view.centerYAnchor + constraintEqualToAnchor:backgroundContainer.centerYAnchor], + [search_view.leadingAnchor + constraintEqualToAnchor:backgroundContainer.leadingAnchor + constant:kSearchIconLeftMargin], + ]]; } - (CGFloat)searchFieldProgressForOffset:(CGFloat)offset { @@ -121,6 +141,8 @@ - (void)updateSearchFieldWidth:(NSLayoutConstraint*)widthConstraint height:(NSLayoutConstraint*)heightConstraint topMargin:(NSLayoutConstraint*)topMarginConstraint + hintLabel:(UILabel*)hintLabel + hintLabelWidth:(NSLayoutConstraint*)hintLabelWidthConstraint subviewConstraints:(NSArray*)constraints forOffset:(CGFloat)offset screenWidth:(CGFloat)screenWidth @@ -130,22 +152,26 @@ if (screenWidth == 0 || contentWidth == 0) return; - CGFloat percent = [self searchFieldProgressForOffset:offset]; - - if (self.cr_widthSizeClass == REGULAR && self.cr_heightSizeClass == REGULAR) { - self.alpha = 1 - percent; - return; - } - CGFloat searchFieldNormalWidth = content_suggestions::searchFieldWidth(contentWidth); + CGFloat percent = [self searchFieldProgressForOffset:offset]; + if (self.cr_widthSizeClass == REGULAR && self.cr_heightSizeClass == REGULAR) { + self.alpha = 1 - percent; + widthConstraint.constant = searchFieldNormalWidth; + hintLabelWidthConstraint.active = NO; + return; + } else { + hintLabelWidthConstraint.active = YES; + self.alpha = 1; + } + // Calculate the amount to grow the width and height of searchField so that // its frame covers the entire toolbar area. CGFloat maxXInset = ui::AlignValueToUpperPixel((searchFieldNormalWidth - screenWidth) / 2); CGFloat maxHeightDiff = - ntp_header::kToolbarHeight - content_suggestions::kSearchFieldHeight; + ntp_header::ToolbarHeight() - content_suggestions::kSearchFieldHeight; widthConstraint.constant = searchFieldNormalWidth - 2 * maxXInset * percent; topMarginConstraint.constant = -content_suggestions::searchFieldTopMargin() - @@ -157,22 +183,29 @@ // it's where the focused adapative toolbar focuses. self.backgroundLeadingConstraint.constant = (safeAreaInsets.left + kExpandedLocationBarHorizontalMargin) * percent; - // TODO(crbug.com/805636) Placeholder for specifications. For now using hard - // coded size of cancel button of 64pt. - CGFloat kCancelButtonWidth = 64; self.backgroundTrailingConstraint.constant = - -(safeAreaInsets.right + kExpandedLocationBarHorizontalMargin + - kCancelButtonWidth) * - percent; - // TODO(crbug.com/805636) Placeholder for specifications. For now using hard - // coded height of location bar, which is 42 or - // kToolbarHeight - 2 * kLocationBarVerticalMargin - CGFloat kLocationBarHeight = 42; + -(safeAreaInsets.right + kExpandedLocationBarHorizontalMargin) * percent; + // TODO(crbug.com/805645) This should take into account the actual location + // bar height in the toolbar. Update this once that's been updated for the + // refresh and remove |kLocationBarHeight|. + CGFloat kLocationBarHeight = 38; CGFloat minHeightDiff = kLocationBarHeight - content_suggestions::kSearchFieldHeight; self.backgroundHeightConstraint.constant = content_suggestions::kSearchFieldHeight + minHeightDiff * percent; + // TODO(crbug.com/805645) This should take into account the actual label width + // of the toolbar location omnibox box hint text. Update this once that's been + // updated for the refresh and remove |kHintShrinkWidth|. + CGFloat kHintShrinkWidth = 30; + CGFloat hintWidth = + [hintLabel.text + cr_boundingSizeWithSize:CGSizeMake(widthConstraint.constant, INFINITY) + font:hintLabel.font] + .width; + hintLabelWidthConstraint.constant = hintWidth - kHintShrinkWidth * percent; + hintLabelWidthConstraint.active = YES; + // Adjust the position of the search field's subviews by adjusting their // constraint constant value. CGFloat constantDiff =
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm index 27f91fe..38d510d9 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_header_view_controller.mm
@@ -38,7 +38,6 @@ namespace { const UIEdgeInsets kSearchBoxStretchInsets = {3, 3, 3, 3}; -const CGFloat kHintLabelSidePadding = 12; } // namespace @interface ContentSuggestionsHeaderViewController () @@ -65,7 +64,9 @@ @property(nonatomic, strong) UIView<NTPHeaderViewAdapter>* headerView; @property(nonatomic, strong) UIButton* fakeOmnibox; +@property(nonatomic, strong) UILabel* searchHintLabel; @property(nonatomic, strong) NSLayoutConstraint* hintLabelLeadingConstraint; +@property(nonatomic, strong) NSLayoutConstraint* hintLabelWidthConstraint; @property(nonatomic, strong) NSLayoutConstraint* voiceTapTrailingConstraint; @property(nonatomic, strong) NSLayoutConstraint* doodleHeightConstraint; @property(nonatomic, strong) NSLayoutConstraint* doodleTopMarginConstraint; @@ -81,6 +82,7 @@ @synthesize dispatcher = _dispatcher; @synthesize delegate = _delegate; @synthesize commandHandler = _commandHandler; +@synthesize searchHintLabel = _searchHintLabel; @synthesize collectionSynchronizer = _collectionSynchronizer; @synthesize readingListModel = _readingListModel; @synthesize toolbarDelegate = _toolbarDelegate; @@ -95,6 +97,7 @@ @synthesize headerView = _headerView; @synthesize fakeOmnibox = _fakeOmnibox; @synthesize hintLabelLeadingConstraint = _hintLabelLeadingConstraint; +@synthesize hintLabelWidthConstraint = _hintLabelWidthConstraint; @synthesize voiceTapTrailingConstraint = _voiceTapTrailingConstraint; @synthesize doodleHeightConstraint = _doodleHeightConstraint; @synthesize doodleTopMarginConstraint = _doodleTopMarginConstraint; @@ -120,6 +123,29 @@ return self.headerView.toolBarView; } +- (void)willTransitionToTraitCollection:(UITraitCollection*)newCollection + withTransitionCoordinator: + (id<UIViewControllerTransitionCoordinator>)coordinator { + [super willTransitionToTraitCollection:newCollection + withTransitionCoordinator:coordinator]; + if (!IsUIRefreshPhase1Enabled()) + return; + + void (^transition)(id<UIViewControllerTransitionCoordinatorContext>) = + ^(id<UIViewControllerTransitionCoordinatorContext> context) { + // Ensure omnibox is reset when not a regular tablet. + if (IsCompactWidth(self) || IsCompactHeight(self)) { + [self.toolbarDelegate setScrollProgressForTabletOmnibox:1]; + } + + // Update the doodle top margin to the new -doodleTopMargin value. + self.doodleTopMarginConstraint.constant = + content_suggestions::doodleTopMargin(YES); + }; + + [coordinator animateAlongsideTransition:transition completion:nil]; +} + #pragma mark - Property - (void)setIsShowing:(BOOL)isShowing { @@ -146,6 +172,8 @@ [self.headerView updateSearchFieldWidth:self.fakeOmniboxWidthConstraint height:self.fakeOmniboxHeightConstraint topMargin:self.fakeOmniboxTopMarginConstraint + hintLabel:self.searchHintLabel + hintLabelWidth:self.hintLabelWidthConstraint subviewConstraints:constraints forOffset:offset screenWidth:screenWidth @@ -175,7 +203,7 @@ CGFloat offsetY = headerHeight - ntp_header::kScrolledToTopOmniboxBottomMargin; if (!IsIPadIdiom()) - offsetY -= ntp_header::kToolbarHeight; + offsetY -= ntp_header::ToolbarHeight(); return offsetY; } @@ -253,7 +281,7 @@ // Initialize and add a search field tap target and a voice search button. - (void)addFakeOmnibox { self.fakeOmnibox = [[UIButton alloc] init]; - if (IsIPadIdiom()) { + if (IsIPadIdiom() && !IsUIRefreshPhase1Enabled()) { UIImage* searchBoxImage = [[UIImage imageNamed:@"ntp_google_search_box"] resizableImageWithCapInsets:kSearchBoxStretchInsets]; [self.fakeOmnibox setBackgroundImage:searchBoxImage @@ -267,20 +295,28 @@ ntp_home::FakeOmniboxAccessibilityID(); // Set up fakebox hint label. - UILabel* searchHintLabel = [[UILabel alloc] init]; - content_suggestions::configureSearchHintLabel(searchHintLabel, + _searchHintLabel = [[UILabel alloc] init]; + content_suggestions::configureSearchHintLabel(_searchHintLabel, self.fakeOmnibox); - self.hintLabelLeadingConstraint = [searchHintLabel.leadingAnchor + self.hintLabelLeadingConstraint = [_searchHintLabel.leadingAnchor constraintEqualToAnchor:[self.fakeOmnibox leadingAnchor] - constant:kHintLabelSidePadding]; - [_hintLabelLeadingConstraint setActive:YES]; + constant:ntp_header::kHintLabelSidePadding]; + if (!IsUIRefreshPhase1Enabled()) + self.hintLabelLeadingConstraint.constant = + ntp_header::kHintLabelSidePaddingLegacy; + [self.hintLabelLeadingConstraint setActive:YES]; + + if (IsUIRefreshPhase1Enabled()) { + self.hintLabelWidthConstraint = + [_searchHintLabel.widthAnchor constraintEqualToConstant:0]; + } // Set a button the same size as the fake omnibox as the accessibility // element. If the hint is the only accessible element, when the fake omnibox // is taking the full width, there are few points that are not accessible and // allow to select the content below it. - searchHintLabel.isAccessibilityElement = NO; + _searchHintLabel.isAccessibilityElement = NO; UIButton* accessibilityButton = [[UIButton alloc] init]; [accessibilityButton addTarget:self action:@selector(fakeOmniboxTapped:) @@ -299,11 +335,15 @@ self.voiceTapTrailingConstraint = [voiceTapTarget.trailingAnchor constraintEqualToAnchor:[self.fakeOmnibox trailingAnchor]]; - [NSLayoutConstraint activateConstraints:@[ - [searchHintLabel.trailingAnchor - constraintEqualToAnchor:voiceTapTarget.leadingAnchor], - _voiceTapTrailingConstraint - ]]; + if (IsUIRefreshPhase1Enabled()) { + [NSLayoutConstraint activateConstraints:@[ _voiceTapTrailingConstraint ]]; + } else { + [NSLayoutConstraint activateConstraints:@[ + [_searchHintLabel.trailingAnchor + constraintEqualToAnchor:voiceTapTarget.leadingAnchor], + _voiceTapTrailingConstraint + ]]; + } if (self.voiceSearchIsEnabled) { [voiceTapTarget addTarget:self
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.mm index 739171f..085157e 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_layout.mm
@@ -24,7 +24,7 @@ CGFloat minimumHeight = collectionViewHeight + headerHeight - ntp_header::kScrolledToTopOmniboxBottomMargin; if (!IsIPadIdiom()) - minimumHeight -= ntp_header::kToolbarHeight; + minimumHeight -= ntp_header::ToolbarHeight(); CGSize contentSize = [super collectionViewContentSize]; if (contentSize.height < minimumHeight) {
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm index 01aa074e..b0909ca 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.mm
@@ -583,7 +583,7 @@ withVelocity:velocity targetContentOffset:targetContentOffset]; - CGFloat toolbarHeight = ntp_header::kToolbarHeight; + CGFloat toolbarHeight = ntp_header::ToolbarHeight(); CGFloat targetY = targetContentOffset->y; if (IsIPadIdiom() || targetY <= 0 || targetY >= toolbarHeight || @@ -620,7 +620,7 @@ if (direction == UIAccessibilityScrollDirectionDown) { CGFloat newYOffset = self.collectionView.contentOffset.y + self.collectionView.bounds.size.height - - ntp_header::kToolbarHeight; + ntp_header::ToolbarHeight(); newYOffset = MIN(self.collectionView.contentSize.height - self.collectionView.bounds.size.height, newYOffset); @@ -629,7 +629,7 @@ } else if (direction == UIAccessibilityScrollDirectionUp) { CGFloat newYOffset = self.collectionView.contentOffset.y - self.collectionView.bounds.size.height + - ntp_header::kToolbarHeight; + ntp_header::ToolbarHeight(); newYOffset = MAX(0, newYOffset); self.collectionView.contentOffset = CGPointMake(self.collectionView.contentOffset.x, newYOffset);
diff --git a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm index f0df24a..d181cf7 100644 --- a/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm +++ b/ios/chrome/browser/ui/content_suggestions/ntp_home_mediator.mm
@@ -201,7 +201,7 @@ // offset, taking into account the size of the toolbar. offset = MAX(0, MIN(offset, collection.contentSize.height - collection.bounds.size.height - - ntp_header::kToolbarHeight)); + ntp_header::ToolbarHeight())); collection.contentOffset = CGPointMake(0, offset); // Update the constraints in case the omnibox needs to be moved. [self.suggestionsViewController updateConstraints];
diff --git a/ios/chrome/browser/ui/content_suggestions/resources/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/resources/BUILD.gn index 599a408..ca385d9 100644 --- a/ios/chrome/browser/ui/content_suggestions/resources/BUILD.gn +++ b/ios/chrome/browser/ui/content_suggestions/resources/BUILD.gn
@@ -21,3 +21,12 @@ "content_suggestions_offline.imageset/content_suggestions_offline@3x.png", ] } + +imageset("ntp_search_icon") { + sources = [ + "ntp_search_icon.imageset/Contents.json", + "ntp_search_icon.imageset/ntp_search_icon.png", + "ntp_search_icon.imageset/ntp_search_icon@2x.png", + "ntp_search_icon.imageset/ntp_search_icon@3x.png", + ] +}
diff --git a/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/Contents.json b/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/Contents.json new file mode 100644 index 0000000..bdee628 --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/Contents.json
@@ -0,0 +1,23 @@ +{ + "images": [ + { + "idiom": "universal", + "scale": "1x", + "filename": "ntp_search_icon.png" + }, + { + "idiom": "universal", + "scale": "2x", + "filename": "ntp_search_icon@2x.png" + }, + { + "idiom": "universal", + "scale": "3x", + "filename": "ntp_search_icon@3x.png" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +}
diff --git a/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/ntp_search_icon.png b/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/ntp_search_icon.png new file mode 100644 index 0000000..7146a1e --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/ntp_search_icon.png Binary files differ
diff --git a/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/ntp_search_icon@2x.png b/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/ntp_search_icon@2x.png new file mode 100644 index 0000000..af824f6 --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/ntp_search_icon@2x.png Binary files differ
diff --git a/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/ntp_search_icon@3x.png b/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/ntp_search_icon@3x.png new file mode 100644 index 0000000..a23d0df --- /dev/null +++ b/ios/chrome/browser/ui/content_suggestions/resources/ntp_search_icon.imageset/ntp_search_icon@3x.png Binary files differ
diff --git a/ios/chrome/browser/ui/ntp/BUILD.gn b/ios/chrome/browser/ui/ntp/BUILD.gn index 0c4f21c5..dfda704 100644 --- a/ios/chrome/browser/ui/ntp/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/BUILD.gn
@@ -10,6 +10,9 @@ "new_tab_page_panel_protocol.h", ] configs += [ "//build/config/compiler:enable_arc" ] + deps = [ + "//ios/chrome/browser/ui:ui_util", + ] } source_set("ntp_header") {
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_controller.mm b/ios/chrome/browser/ui/ntp/new_tab_page_controller.mm index 2b3b1b1..c20cec3 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_controller.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_controller.mm
@@ -27,6 +27,7 @@ #import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h" #import "ios/chrome/browser/ui/ntp/incognito_view_controller.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_bar_item.h" +#import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_view.h" #import "ios/chrome/browser/ui/rtl_geometry.h" #include "ios/chrome/browser/ui/ui_util.h" @@ -41,10 +42,6 @@ using base::UserMetricsAction; -namespace { -const CGFloat kToolbarHeight = 56; -} - @interface NewTabPageController () { ios::ChromeBrowserState* _browserState; // weak. __weak id<UrlLoader> _loader; @@ -377,7 +374,8 @@ - (CGFloat)toolbarHeight { // If the google landing controller is nil, there is no toolbar visible in the // native content view, finally there is no toolbar on iPad. - return self.headerController && !IsIPadIdiom() ? kToolbarHeight : 0.0; + return self.headerController && !IsIPadIdiom() ? ntp_header::ToolbarHeight() + : 0.0; } #pragma mark - NewTabPagePanelControllerDelegate
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h b/ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h index 023fff2..ace4fc2 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h +++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h
@@ -17,11 +17,12 @@ // initial frame to its final full bleed frame. extern const CGFloat kAnimationDistance; -extern const CGFloat kToolbarHeight; +CGFloat ToolbarHeight(); extern const CGFloat kScrolledToTopOmniboxBottomMargin; extern const CGFloat kHintLabelSidePadding; +extern const CGFloat kHintLabelSidePaddingLegacy; // The margin of the subviews of the fake omnibox when it is pinned to top. extern const CGFloat kMaxHorizontalMarginDiff;
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_constants.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_constants.mm index 4fd1e8b..034a4ea 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_header_constants.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_constants.mm
@@ -4,6 +4,9 @@ #import "ios/chrome/browser/ui/ntp/new_tab_page_header_constants.h" +#include "ios/chrome/browser/ui/ui_util.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif @@ -12,10 +15,19 @@ const CGFloat kMinHeaderHeight = 62; const CGFloat kAnimationDistance = 42; -const CGFloat kToolbarHeight = 56; +const CGFloat kToolbarHeightLegacy = 56; +const CGFloat kToolbarHeight = 48; const CGFloat kScrolledToTopOmniboxBottomMargin = 4; -const CGFloat kHintLabelSidePadding = 12; +const CGFloat kHintLabelSidePadding = 37; +const CGFloat kHintLabelSidePaddingLegacy = 12; const CGFloat kMaxHorizontalMarginDiff = 5; const CGFloat kMaxTopMarginDiff = 4; +CGFloat ToolbarHeight() { + if (IsUIRefreshPhase1Enabled()) { + return kToolbarHeight; + } + return kToolbarHeightLegacy; +} + } // ntp_header
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm index 1d569b9..5048542 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_header_view.mm
@@ -110,6 +110,8 @@ - (void)updateSearchFieldWidth:(NSLayoutConstraint*)widthConstraint height:(NSLayoutConstraint*)heightConstraint topMargin:(NSLayoutConstraint*)topMarginConstraint + hintLabel:(UILabel*)hintLabel + hintLabelWidth:(NSLayoutConstraint*)hintLabelWidthConstraint subviewConstraints:(NSArray*)constraints forOffset:(CGFloat)offset screenWidth:(CGFloat)screenWidth @@ -139,7 +141,7 @@ CGFloat maxXInset = ui::AlignValueToUpperPixel( (searchFieldNormalWidth - screenWidth) / 2 - 1); CGFloat maxHeightDiff = - ntp_header::kToolbarHeight - content_suggestions::kSearchFieldHeight; + ntp_header::ToolbarHeight() - content_suggestions::kSearchFieldHeight; widthConstraint.constant = searchFieldNormalWidth - 2 * maxXInset * percent; topMarginConstraint.constant = -content_suggestions::searchFieldTopMargin() - @@ -156,7 +158,8 @@ percent * (ntp_header::kMaxHorizontalMarginDiff + safeAreaInsets.left); for (NSLayoutConstraint* constraint in constraints) { if (constraint.constant > 0) - constraint.constant = constantDiff + ntp_header::kHintLabelSidePadding; + constraint.constant = + constantDiff + ntp_header::kHintLabelSidePaddingLegacy; else constraint.constant = -constantDiff; }
diff --git a/ios/chrome/browser/ui/ntp/ntp_header_view_adapter.h b/ios/chrome/browser/ui/ntp/ntp_header_view_adapter.h index 9546eb4..d44515b 100644 --- a/ios/chrome/browser/ui/ntp/ntp_header_view_adapter.h +++ b/ios/chrome/browser/ui/ntp/ntp_header_view_adapter.h
@@ -30,6 +30,8 @@ - (void)updateSearchFieldWidth:(NSLayoutConstraint*)widthConstraint height:(NSLayoutConstraint*)heightConstraint topMargin:(NSLayoutConstraint*)topMarginConstraint + hintLabel:(UILabel*)hintLabel + hintLabelWidth:(NSLayoutConstraint*)hintLabelWidthConstraint subviewConstraints:(NSArray*)constraints forOffset:(CGFloat)offset screenWidth:(CGFloat)screenWidth
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_coordinator.mm b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_coordinator.mm index e714224..4d7f141 100644 --- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_coordinator.mm +++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_coordinator.mm
@@ -4,6 +4,10 @@ #import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_coordinator.h" +#include "base/ios/block_types.h" +#include "base/mac/foundation_util.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_handset_view_controller.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_mediator.h" #import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h" #import "ios/chrome/browser/ui/table_view/table_container_view_controller.h" #import "ios/chrome/browser/ui/util/form_sheet_navigation_controller.h" @@ -14,15 +18,24 @@ #error "This file requires ARC support." #endif -@interface RecentTabsTableCoordinator () +// TODO(crbug.com/805135): Remove RecentTabsHandsetViewControllerCommand and +// recent_tabs_handset_view_controller.h import. We need this to dismiss for +// now, but it can be improved. +@interface RecentTabsTableCoordinator ()<RecentTabsHandsetViewControllerCommand> +// Completion block called once the recentTabsViewController is dismissed. +@property(nonatomic, copy) ProceduralBlock completion; +// Mediator being managed by this Coordinator. +@property(nonatomic, strong) RecentTabsMediator* mediator; // ViewController being managed by this Coordinator. @property(nonatomic, strong) TableContainerViewController* recentTabsContainerViewController; @end @implementation RecentTabsTableCoordinator +@synthesize completion = _completion; @synthesize dispatcher = _dispatcher; @synthesize loader = _loader; +@synthesize mediator = _mediator; @synthesize recentTabsContainerViewController = _recentTabsContainerViewController; @@ -33,6 +46,14 @@ recentTabsTableViewController.browserState = self.browserState; recentTabsTableViewController.loader = self.loader; recentTabsTableViewController.dispatcher = self.dispatcher; + recentTabsTableViewController.handsetCommandHandler = self; + + // Initialize and configure RecentTabsMediator. + self.mediator = [[RecentTabsMediator alloc] init]; + self.mediator.browserState = self.browserState; + self.mediator.consumer = recentTabsTableViewController; + [self.mediator initObservers]; + [self.mediator reloadSessions]; // Initialize and configure RecentTabsViewController. self.recentTabsContainerViewController = [[TableContainerViewController alloc] @@ -58,9 +79,24 @@ } - (void)stop { - [self.recentTabsContainerViewController dismissViewControllerAnimated:YES - completion:nil]; + // TODO(crbug.com/805135): Move this dismissal code to RecentTabsContainerVC + // once its created. Remove "base/mac/foundation_util.h" import then. + RecentTabsTableViewController* recentTabsTableViewController = + base::mac::ObjCCastStrict<RecentTabsTableViewController>( + self.recentTabsContainerViewController.tableViewController); + [recentTabsTableViewController dismissModals]; + [self.recentTabsContainerViewController + dismissViewControllerAnimated:YES + completion:self.completion]; self.recentTabsContainerViewController = nil; + [self.mediator disconnect]; +} + +#pragma mark - RecentTabsHandsetViewControllerCommand + +- (void)dismissRecentTabsWithCompletion:(void (^)())completion { + self.completion = completion; + [self stop]; } @end
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h index d70b742246..a6af262 100644 --- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h +++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h
@@ -13,6 +13,8 @@ } @protocol ApplicationCommands; +@protocol LegacyRecentTabsTableViewControllerDelegate; +@protocol RecentTabsHandsetViewControllerCommand; @protocol UrlLoader; @interface RecentTabsTableViewController @@ -23,6 +25,15 @@ @property(nonatomic, weak) id<ApplicationCommands> dispatcher; // UrlLoader used by this ViewController. @property(nonatomic, weak) id<UrlLoader> loader; + +// RecentTabsTableViewControllerDelegate delegate. +@property(nonatomic, weak) id<LegacyRecentTabsTableViewControllerDelegate> + delegate; + +// RecentTabsHandsetViewControllerCommand delegate. +@property(nonatomic, weak) id<RecentTabsHandsetViewControllerCommand> + handsetCommandHandler; + @end #endif // IOS_CHROME_BROWSER_UI_NTP_RECENT_TABS_RECENT_TABS_TABLE_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm index 0a5255d7..0b58127 100644 --- a/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm +++ b/ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.mm
@@ -4,14 +4,119 @@ #import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_table_view_controller.h" +#include "base/logging.h" +#include "base/metrics/user_metrics.h" +#include "base/metrics/user_metrics_action.h" +#include "base/strings/sys_string_conversions.h" +#include "components/browser_sync/profile_sync_service.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync_sessions/open_tabs_ui_delegate.h" +#include "ios/chrome/browser/browser_state/chrome_browser_state.h" +#include "ios/chrome/browser/experimental_flags.h" +#import "ios/chrome/browser/metrics/new_tab_page_uma.h" +#include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios.h" +#include "ios/chrome/browser/sessions/tab_restore_service_delegate_impl_ios_factory.h" +#include "ios/chrome/browser/sync/ios_chrome_profile_sync_service_factory.h" +#import "ios/chrome/browser/ui/authentication/signin_promo_view.h" +#import "ios/chrome/browser/ui/authentication/signin_promo_view_configurator.h" +#import "ios/chrome/browser/ui/authentication/signin_promo_view_consumer.h" +#import "ios/chrome/browser/ui/authentication/signin_promo_view_mediator.h" +#include "ios/chrome/browser/ui/commands/application_commands.h" +#import "ios/chrome/browser/ui/commands/show_signin_command.h" +#import "ios/chrome/browser/ui/context_menu/context_menu_coordinator.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/legacy_recent_tabs_table_view_controller_delegate.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_constants.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/recent_tabs_handset_view_controller.h" +#include "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/views/generic_section_header_view.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/views/header_of_collapsable_section_protocol.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/views/session_section_header_view.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/views/session_tab_data_view.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/views/show_full_history_view.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/views/signed_in_sync_in_progress_view.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/views/signed_in_sync_off_view.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/views/signed_in_sync_on_no_sessions_view.h" +#import "ios/chrome/browser/ui/ntp/recent_tabs/views/spacers_view.h" +#import "ios/chrome/browser/ui/settings/sync_utils/sync_presenter.h" +#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h" +#include "ios/chrome/browser/ui/ui_util.h" +#import "ios/chrome/browser/ui/url_loader.h" +#import "ios/chrome/browser/ui/util/constraints_ui_util.h" +#import "ios/chrome/browser/ui/util/top_view_controller.h" +#include "ios/chrome/grit/ios_chromium_strings.h" +#include "ios/chrome/grit/ios_strings.h" +#include "ios/web/public/referrer.h" +#import "ios/web/public/web_state/context_menu_params.h" +#include "ui/base/l10n/l10n_util.h" + #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif +namespace { + +// Key for saving whether the Other Device section is collapsed. +NSString* const kOtherDeviceCollapsedKey = @"OtherDevicesCollapsed"; + +// Key for saving whether the Recently Closed section is collapsed. +NSString* const kRecentlyClosedCollapsedKey = @"RecentlyClosedCollapsed"; + +// Tag to extract the section headers from the cells. +enum { kSectionHeader = 1 }; + +// Margin at the top of the sigin-in promo view. +const CGFloat kSigninPromoViewTopMargin = 24; + +// Types of sections. +enum SectionType { + SEPARATOR_SECTION, + CLOSED_TAB_SECTION, + OTHER_DEVICES_SECTION, + SESSION_SECTION, +}; + +// Types of cells. +enum CellType { + CELL_CLOSED_TAB_SECTION_HEADER, + CELL_CLOSED_TAB_DATA, + CELL_SHOW_FULL_HISTORY, + CELL_SEPARATOR, + CELL_OTHER_DEVICES_SECTION_HEADER, + CELL_OTHER_DEVICES_SIGNED_IN_SYNC_OFF, + CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS, + CELL_OTHER_DEVICES_SIGNIN_PROMO, + CELL_OTHER_DEVICES_SYNC_IN_PROGRESS, + CELL_SESSION_SECTION_HEADER, + CELL_SESSION_TAB_DATA, +}; + +} // namespace + +@interface RecentTabsTableViewController ()<SigninPromoViewConsumer, + SigninPresenter, + SyncPresenter, + UIGestureRecognizerDelegate> { + std::unique_ptr<synced_sessions::SyncedSessions> _syncedSessions; +} +// The service that manages the recently closed tabs +@property(nonatomic, assign) sessions::TabRestoreService* tabRestoreService; +// The sync state. +@property(nonatomic, assign) SessionsSyncUserState sessionState; +// Handles displaying the context menu for all form factors. +@property(nonatomic, strong) ContextMenuCoordinator* contextMenuCoordinator; +@property(nonatomic, strong) SigninPromoViewMediator* signinPromoViewMediator; +@end + @implementation RecentTabsTableViewController : ChromeTableViewController @synthesize browserState = _browserState; +@synthesize contextMenuCoordinator = _contextMenuCoordinator; +@synthesize delegate = delegate_; @synthesize dispatcher = _dispatcher; +@synthesize handsetCommandHandler = _handsetCommandHandler; @synthesize loader = _loader; +@synthesize sessionState = _sessionState; +@synthesize signinPromoViewMediator = _signinPromoViewMediator; +@synthesize tabRestoreService = _tabRestoreService; #pragma mark - Public Interface @@ -23,23 +128,852 @@ _dispatcher = dispatcher; _loader = loader; _browserState = browserState; + _sessionState = SessionsSyncUserState::USER_SIGNED_OUT; + _syncedSessions.reset(new synced_sessions::SyncedSessions()); } return self; } -// TODO(crbug.com/805135) -- (void)refreshUserState:(SessionsSyncUserState)state { +- (void)dealloc { + [_signinPromoViewMediator signinPromoViewRemoved]; } -// TODO(crbug.com/805135) -- (void)refreshRecentlyClosedTabs { +- (void)viewDidLoad { + [super viewDidLoad]; + self.view.accessibilityIdentifier = + kRecentTabsTableViewControllerAccessibilityIdentifier; + self.tableView.rowHeight = UITableViewAutomaticDimension; + self.tableView.estimatedRowHeight = + [SessionTabDataView desiredHeightInUITableViewCell]; + [self.tableView setSeparatorColor:[UIColor clearColor]]; + [self.tableView setDataSource:self]; + [self.tableView setDelegate:self]; + UILongPressGestureRecognizer* longPress = + [[UILongPressGestureRecognizer alloc] + initWithTarget:self + action:@selector(handleLongPress:)]; + longPress.delegate = self; + [self.tableView addGestureRecognizer:longPress]; } -// TODO(crbug.com/805135) -- (void)setTabRestoreService:(sessions::TabRestoreService*)tabRestoreService { +- (SectionType)sectionType:(NSInteger)section { + if (section == 0) { + return CLOSED_TAB_SECTION; + } + if (section == 1) { + return SEPARATOR_SECTION; + } + if (section < [self numberOfSectionsBeforeSessionOrOtherDevicesSections]) { + return CLOSED_TAB_SECTION; + } + if (self.sessionState == + SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_WITH_SESSIONS) { + return SESSION_SECTION; + } + // Other cases of recent_tabs::USER_SIGNED_IN_SYNC_OFF, + // recent_tabs::USER_SIGNED_IN_SYNC_ON_NO_SESSIONS, and + // recent_tabs::USER_SIGNED_OUT falls through to here. + return OTHER_DEVICES_SECTION; } -// TODO(crbug.com/805135) + +- (CellType)cellType:(NSIndexPath*)indexPath { + SectionType sectionType = [self sectionType:indexPath.section]; + switch (sectionType) { + case CLOSED_TAB_SECTION: + if (indexPath.row == 0) { + return CELL_CLOSED_TAB_SECTION_HEADER; + } + // The last cell of the section is to access the history panel. + if (indexPath.row == + [self numberOfCellsInRecentlyClosedTabsSection] - 1) { + return CELL_SHOW_FULL_HISTORY; + } + return CELL_CLOSED_TAB_DATA; + case SEPARATOR_SECTION: + return CELL_SEPARATOR; + case SESSION_SECTION: + if (indexPath.row == 0) { + return CELL_SESSION_SECTION_HEADER; + } + return CELL_SESSION_TAB_DATA; + case OTHER_DEVICES_SECTION: + if (self.sessionState == + SessionsSyncUserState::USER_SIGNED_IN_SYNC_IN_PROGRESS) { + return CELL_OTHER_DEVICES_SYNC_IN_PROGRESS; + } + if (indexPath.row == 0) { + return CELL_OTHER_DEVICES_SECTION_HEADER; + } + switch (self.sessionState) { + case SessionsSyncUserState::USER_SIGNED_OUT: + return CELL_OTHER_DEVICES_SIGNIN_PROMO; + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_OFF: + return CELL_OTHER_DEVICES_SIGNED_IN_SYNC_OFF; + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_NO_SESSIONS: + return CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS; + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_WITH_SESSIONS: + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_IN_PROGRESS: + NOTREACHED(); + // These cases should never occur. Still, this method needs to + // return _something_, so it's returning the least wrong cell type. + return CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS; + } + } +} + +- (NSInteger)sectionIndexForSectionType:(SectionType)sectionType { + NSUInteger sectionCount = [self numberOfSectionsInTableView:self.tableView]; + for (NSUInteger sectionIndex = 0; sectionIndex < sectionCount; + ++sectionIndex) { + if ([self sectionType:sectionIndex] == sectionType) + return sectionIndex; + } + return NSNotFound; +} + +- (NSInteger)numberOfSectionsBeforeSessionOrOtherDevicesSections { + // The 2 sections are CLOSED_TAB_SECTION and SEPARATOR_SECTION. + return 2; +} + - (void)dismissModals { + [self.contextMenuCoordinator stop]; +} + +#pragma mark - Recently closed tab helpers + +- (void)refreshRecentlyClosedTabs { + [self.tableView reloadData]; +} + +- (void)setTabRestoreService:(sessions::TabRestoreService*)tabRestoreService { + _tabRestoreService = tabRestoreService; +} + +- (NSInteger)numberOfCellsInRecentlyClosedTabsSection { + // + 2 because of the section header, and the "Show full history" cell. + return [self numberOfRecentlyClosedTabs] + 2; +} + +- (NSInteger)numberOfRecentlyClosedTabs { + if (!self.tabRestoreService) + return 0; + return static_cast<NSInteger>(self.tabRestoreService->entries().size()); +} + +- (const sessions::TabRestoreService::Entry*)tabRestoreEntryAtIndex: + (NSIndexPath*)indexPath { + DCHECK_EQ([self sectionType:indexPath.section], CLOSED_TAB_SECTION); + // "- 1" because of the section header. + NSInteger index = indexPath.row - 1; + DCHECK_LE(index, [self numberOfRecentlyClosedTabs]); + if (!self.tabRestoreService) + return nullptr; + + // Advance the entry iterator to the correct index. + // Note that std:list<> can only be accessed sequentially, which is + // suboptimal when using Cocoa table APIs. This list doesn't appear + // to get very long, so it probably won't matter for perf. + sessions::TabRestoreService::Entries::const_iterator iter = + self.tabRestoreService->entries().begin(); + std::advance(iter, index); + CHECK(*iter); + return iter->get(); +} + +#pragma mark - Helpers to open tabs, or show the full history view. + +- (void)dismissRecentTabsModal { + [self.handsetCommandHandler dismissRecentTabsWithCompletion:nil]; +} + +- (void)openTabWithContentOfDistantTab: + (synced_sessions::DistantTab const*)distantTab { + sync_sessions::OpenTabsUIDelegate* openTabs = + IOSChromeProfileSyncServiceFactory::GetForBrowserState(self.browserState) + ->GetOpenTabsUIDelegate(); + const sessions::SessionTab* toLoad = nullptr; + [self dismissRecentTabsModal]; + if (openTabs->GetForeignTab(distantTab->session_tag, distantTab->tab_id, + &toLoad)) { + base::RecordAction(base::UserMetricsAction( + "MobileRecentTabManagerTabFromOtherDeviceOpened")); + new_tab_page_uma::RecordAction( + self.browserState, new_tab_page_uma::ACTION_OPENED_FOREIGN_SESSION); + [self.loader loadSessionTab:toLoad]; + } +} + +- (void)openTabWithTabRestoreEntry: + (const sessions::TabRestoreService::Entry*)entry { + DCHECK(entry); + if (!entry) + return; + // We only handle the TAB type. + if (entry->type != sessions::TabRestoreService::TAB) + return; + TabRestoreServiceDelegateImplIOS* delegate = + TabRestoreServiceDelegateImplIOSFactory::GetForBrowserState( + self.browserState); + [self dismissRecentTabsModal]; + base::RecordAction( + base::UserMetricsAction("MobileRecentTabManagerRecentTabOpened")); + new_tab_page_uma::RecordAction( + self.browserState, new_tab_page_uma::ACTION_OPENED_RECENTLY_CLOSED_ENTRY); + self.tabRestoreService->RestoreEntryById(delegate, entry->id, + WindowOpenDisposition::CURRENT_TAB); +} + +- (void)openTabWithURL:(const GURL&)url { + if (url.is_valid()) { + [self dismissRecentTabsModal]; + [self.loader loadURL:url + referrer:web::Referrer() + transition:ui::PAGE_TRANSITION_TYPED + rendererInitiated:NO]; + } +} + +- (void)showFullHistory { + __weak RecentTabsTableViewController* weakSelf = self; + ProceduralBlock openHistory = ^{ + [weakSelf.dispatcher showHistory]; + }; + DCHECK(self.handsetCommandHandler); + [self.handsetCommandHandler dismissRecentTabsWithCompletion:openHistory]; +} + +#pragma mark - Handling of the collapsed sections. + +- (void)toggleExpansionOfSection:(NSInteger)sectionIndex { + NSString* sectionCollapseKey = nil; + int cellCount = 0; + + SectionType section = [self sectionType:sectionIndex]; + + switch (section) { + case CLOSED_TAB_SECTION: + sectionCollapseKey = kRecentlyClosedCollapsedKey; + // - 1 because the header does not count. + cellCount = [self numberOfCellsInRecentlyClosedTabsSection] - 1; + break; + case SEPARATOR_SECTION: + NOTREACHED(); + return; + case OTHER_DEVICES_SECTION: + cellCount = 1; + sectionCollapseKey = kOtherDeviceCollapsedKey; + break; + case SESSION_SECTION: { + size_t indexOfSession = + sectionIndex - + [self numberOfSectionsBeforeSessionOrOtherDevicesSections]; + DCHECK_LT(indexOfSession, _syncedSessions->GetSessionCount()); + synced_sessions::DistantSession const* distantSession = + _syncedSessions->GetSession(indexOfSession); + cellCount = distantSession->tabs.size(); + sectionCollapseKey = [self keyForDistantSession:distantSession]; + break; + } + } + DCHECK(sectionCollapseKey); + BOOL collapsed = ![self sectionIsCollapsed:sectionCollapseKey]; + [self setSection:sectionCollapseKey collapsed:collapsed]; + + // Builds an array indexing all the cells needing to be removed or inserted to + // collapse/expand the section. + NSMutableArray* cellIndexPathsToDeleteOrInsert = [NSMutableArray array]; + for (int i = 1; i <= cellCount; i++) { + NSIndexPath* tabIndexPath = + [NSIndexPath indexPathForRow:i inSection:sectionIndex]; + [cellIndexPathsToDeleteOrInsert addObject:tabIndexPath]; + } + + // Update the table view. + [self.tableView beginUpdates]; + if (collapsed) { + [self.tableView deleteRowsAtIndexPaths:cellIndexPathsToDeleteOrInsert + withRowAnimation:UITableViewRowAnimationFade]; + } else { + [self.tableView insertRowsAtIndexPaths:cellIndexPathsToDeleteOrInsert + withRowAnimation:UITableViewRowAnimationFade]; + } + [self.tableView endUpdates]; + + // Rotate disclosure icon. + NSIndexPath* sectionCellIndexPath = + [NSIndexPath indexPathForRow:0 inSection:sectionIndex]; + UITableViewCell* sectionCell = + [self.tableView cellForRowAtIndexPath:sectionCellIndexPath]; + UIView* subview = [sectionCell viewWithTag:kSectionHeader]; + DCHECK([subview + conformsToProtocol:@protocol(HeaderOfCollapsableSectionProtocol)]); + id<HeaderOfCollapsableSectionProtocol> headerView = + static_cast<id<HeaderOfCollapsableSectionProtocol>>(subview); + [headerView setSectionIsCollapsed:collapsed animated:YES]; +} + +- (NSString*)keyForDistantSession: + (synced_sessions::DistantSession const*)distantSession { + return base::SysUTF8ToNSString(distantSession->tag); +} + +- (void)setSection:(NSString*)sectionKey collapsed:(BOOL)collapsed { + // TODO(crbug.com/419346): Store in the browser state preference instead of + // NSUserDefaults. + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + NSDictionary* collapsedSections = + [defaults dictionaryForKey:kCollapsedSectionsKey]; + NSMutableDictionary* newCollapsedSessions = + [NSMutableDictionary dictionaryWithDictionary:collapsedSections]; + NSNumber* value = [NSNumber numberWithBool:collapsed]; + [newCollapsedSessions setValue:value forKey:sectionKey]; + [defaults setObject:newCollapsedSessions forKey:kCollapsedSectionsKey]; +} + +- (BOOL)sectionIsCollapsed:(NSString*)sectionKey { + // TODO(crbug.com/419346): Store in the profile's preference instead of the + // NSUserDefaults. + DCHECK(sectionKey); + NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; + NSDictionary* collapsedSessions = + [defaults dictionaryForKey:kCollapsedSectionsKey]; + NSNumber* value = (NSNumber*)[collapsedSessions valueForKey:sectionKey]; + return [value boolValue]; +} + +#pragma mark - Distant Sessions helpers + +- (void)refreshUserState:(SessionsSyncUserState)newSessionState { + if ((newSessionState == self.sessionState && + self.sessionState != + SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_WITH_SESSIONS) || + self.signinPromoViewMediator.isSigninInProgress) { + // No need to refresh the sections. + return; + } + + [self.tableView beginUpdates]; + NSIndexSet* indexesToBeDeleted = [self sessionOrOtherDevicesSectionsIndexes]; + [self.tableView deleteSections:indexesToBeDeleted + withRowAnimation:UITableViewRowAnimationFade]; + syncer::SyncService* syncService = + IOSChromeProfileSyncServiceFactory::GetForBrowserState(self.browserState); + _syncedSessions.reset(new synced_sessions::SyncedSessions(syncService)); + self.sessionState = newSessionState; + + if (self.sessionState == + SessionsSyncUserState::USER_SIGNED_IN_SYNC_IN_PROGRESS) { + // Expand the "Other Device" section once sync is finished. + [self setSection:kOtherDeviceCollapsedKey collapsed:NO]; + } + + NSIndexSet* indexesToBeInserted = [self sessionOrOtherDevicesSectionsIndexes]; + [self.tableView insertSections:indexesToBeInserted + withRowAnimation:UITableViewRowAnimationFade]; + [self.tableView endUpdates]; + + if (self.sessionState != SessionsSyncUserState::USER_SIGNED_OUT) { + [self.signinPromoViewMediator signinPromoViewRemoved]; + self.signinPromoViewMediator = nil; + } +} + +- (NSInteger)numberOfSessionSections { + DCHECK(self.sessionState == + SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_WITH_SESSIONS); + return _syncedSessions->GetSessionCount(); +} + +- (NSIndexSet*)sessionOrOtherDevicesSectionsIndexes { + NSInteger sectionCount = 0; + switch (self.sessionState) { + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_WITH_SESSIONS: + sectionCount = [self numberOfSessionSections]; + break; + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_OFF: + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_NO_SESSIONS: + case SessionsSyncUserState::USER_SIGNED_OUT: + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_IN_PROGRESS: + sectionCount = 1; + break; + } + NSRange rangeOfSessionSections = NSMakeRange( + [self numberOfSectionsBeforeSessionOrOtherDevicesSections], sectionCount); + NSIndexSet* sessionSectionsIndexes = + [NSIndexSet indexSetWithIndexesInRange:rangeOfSessionSections]; + return sessionSectionsIndexes; +} + +- (size_t)indexOfSessionAtIndexPath:(NSIndexPath*)indexPath { + DCHECK_EQ([self sectionType:indexPath.section], SESSION_SECTION); + size_t indexOfSession = + indexPath.section - + [self numberOfSectionsBeforeSessionOrOtherDevicesSections]; + DCHECK_LT(indexOfSession, _syncedSessions->GetSessionCount()); + return indexOfSession; +} + +- (synced_sessions::DistantSession const*)sessionAtIndexPath: + (NSIndexPath*)indexPath { + return _syncedSessions->GetSession( + [self indexOfSessionAtIndexPath:indexPath]); +} + +- (synced_sessions::DistantTab const*)distantTabAtIndex: + (NSIndexPath*)indexPath { + DCHECK_EQ([self sectionType:indexPath.section], SESSION_SECTION); + // "- 1" because of the section header. + size_t indexOfDistantTab = indexPath.row - 1; + synced_sessions::DistantSession const* session = + [self sessionAtIndexPath:indexPath]; + DCHECK_LT(indexOfDistantTab, session->tabs.size()); + return session->tabs[indexOfDistantTab].get(); +} + +#pragma mark - Long press and context menus + +- (void)handleLongPress:(UILongPressGestureRecognizer*)longPressGesture { + DCHECK_EQ(self.tableView, longPressGesture.view); + if (longPressGesture.state == UIGestureRecognizerStateBegan) { + CGPoint point = [longPressGesture locationInView:self.tableView]; + NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:point]; + if (!indexPath) + return; + DCHECK_LE(indexPath.section, + [self numberOfSectionsInTableView:self.tableView]); + + CellType cellType = [self cellType:indexPath]; + if (cellType != CELL_SESSION_SECTION_HEADER) { + NOTREACHED(); + return; + } + + web::ContextMenuParams params; + // Get view coordinates in local space. + CGPoint viewCoordinate = [longPressGesture locationInView:self.tableView]; + params.location = viewCoordinate; + params.view = self.tableView; + + // Present sheet/popover using controller that is added to view hierarchy. + // TODO(crbug.com/754642): Remove TopPresentedViewController(). + UIViewController* topController = + top_view_controller::TopPresentedViewController(); + + self.contextMenuCoordinator = + [[ContextMenuCoordinator alloc] initWithBaseViewController:topController + params:params]; + + // Fill the sheet/popover with buttons. + __weak RecentTabsTableViewController* weakSelf = self; + + // "Open all tabs" button. + NSString* openAllButtonLabel = + l10n_util::GetNSString(IDS_IOS_RECENT_TABS_OPEN_ALL_MENU_OPTION); + [self.contextMenuCoordinator + addItemWithTitle:openAllButtonLabel + action:^{ + [weakSelf openTabsFromSessionAtIndexPath:indexPath]; + }]; + + // "Hide for now" button. + NSString* hideButtonLabel = + l10n_util::GetNSString(IDS_IOS_RECENT_TABS_HIDE_MENU_OPTION); + [self.contextMenuCoordinator + addItemWithTitle:hideButtonLabel + action:^{ + [weakSelf removeSessionAtIndexPath:indexPath]; + }]; + + [self.contextMenuCoordinator start]; + } +} + +- (void)openTabsFromSessionAtIndexPath:(NSIndexPath*)indexPath { + synced_sessions::DistantSession const* session = + [self sessionAtIndexPath:indexPath]; + [self dismissRecentTabsModal]; + for (auto const& tab : session->tabs) { + [self.loader webPageOrderedOpen:tab->virtual_url + referrer:web::Referrer() + inBackground:YES + appendTo:kLastTab]; + } +} + +- (void)removeSessionAtIndexPath:(NSIndexPath*)indexPath { + DCHECK_EQ([self cellType:indexPath], CELL_SESSION_SECTION_HEADER); + synced_sessions::DistantSession const* session = + [self sessionAtIndexPath:indexPath]; + std::string sessionTagCopy = session->tag; + syncer::SyncService* syncService = + IOSChromeProfileSyncServiceFactory::GetForBrowserState(self.browserState); + sync_sessions::OpenTabsUIDelegate* openTabs = + syncService->GetOpenTabsUIDelegate(); + _syncedSessions->EraseSession([self indexOfSessionAtIndexPath:indexPath]); + [self.tableView + deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] + withRowAnimation:UITableViewRowAnimationLeft]; + // Use dispatch_async to give the action sheet a chance to cleanup before + // replacing its parent view. + dispatch_async(dispatch_get_main_queue(), ^{ + openTabs->DeleteForeignSession(sessionTagCopy); + }); +} + +#pragma mark - UIGestureRecognizerDelegate + +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer*)gestureRecognizer { + CGPoint point = [gestureRecognizer locationInView:self.tableView]; + NSIndexPath* indexPath = [self.tableView indexPathForRowAtPoint:point]; + if (!indexPath) + return NO; + CellType cellType = [self cellType:indexPath]; + // Context menus can be opened on a section header for tabs. + return cellType == CELL_SESSION_SECTION_HEADER; +} + +#pragma mark - UITableViewDataSource + +- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView { + switch (self.sessionState) { + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_WITH_SESSIONS: + return [self numberOfSectionsBeforeSessionOrOtherDevicesSections] + + [self numberOfSessionSections]; + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_OFF: + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_NO_SESSIONS: + case SessionsSyncUserState::USER_SIGNED_OUT: + case SessionsSyncUserState::USER_SIGNED_IN_SYNC_IN_PROGRESS: + return [self numberOfSectionsBeforeSessionOrOtherDevicesSections] + 1; + } +} + +- (NSInteger)tableView:(UITableView*)tableView + numberOfRowsInSection:(NSInteger)section { + switch ([self sectionType:section]) { + case CLOSED_TAB_SECTION: + if ([self sectionIsCollapsed:kRecentlyClosedCollapsedKey]) + return 1; + else + return [self numberOfCellsInRecentlyClosedTabsSection]; + case SEPARATOR_SECTION: + return 1; + case OTHER_DEVICES_SECTION: + if (self.sessionState == + SessionsSyncUserState::USER_SIGNED_IN_SYNC_IN_PROGRESS) + return 1; + if ([self sectionIsCollapsed:kOtherDeviceCollapsedKey]) + return 1; + else + return 2; + case SESSION_SECTION: { + DCHECK(self.sessionState == + SessionsSyncUserState::USER_SIGNED_IN_SYNC_ON_WITH_SESSIONS); + size_t sessionIndex = + section - [self numberOfSectionsBeforeSessionOrOtherDevicesSections]; + DCHECK_LT(sessionIndex, _syncedSessions->GetSessionCount()); + synced_sessions::DistantSession const* distantSession = + _syncedSessions->GetSession(sessionIndex); + NSString* key = [self keyForDistantSession:distantSession]; + if ([self sectionIsCollapsed:key]) + return 1; + else + return distantSession->tabs.size() + 1; + } + } +} + +- (UITableViewCell*)tableView:(UITableView*)tableView + cellForRowAtIndexPath:(NSIndexPath*)indexPath { + UITableViewCell* cell = + [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:nil]; + UIView* contentView = cell.contentView; + CGFloat contentViewTopMargin = 0; + + UIView* subview; + CellType cellType = [self cellType:indexPath]; + switch (cellType) { + case CELL_CLOSED_TAB_SECTION_HEADER: { + BOOL collapsed = [self sectionIsCollapsed:kRecentlyClosedCollapsedKey]; + subview = [[GenericSectionHeaderView alloc] + initWithType:recent_tabs::RECENTLY_CLOSED_TABS_SECTION_HEADER + sectionIsCollapsed:collapsed]; + [subview setTag:kSectionHeader]; + break; + } + case CELL_CLOSED_TAB_DATA: { + SessionTabDataView* genericTabData = + [[SessionTabDataView alloc] initWithFrame:CGRectZero]; + [genericTabData + updateWithTabRestoreEntry:[self tabRestoreEntryAtIndex:indexPath] + browserState:self.browserState]; + subview = genericTabData; + break; + } + case CELL_SHOW_FULL_HISTORY: + subview = [[ShowFullHistoryView alloc] initWithFrame:CGRectZero]; + break; + case CELL_SEPARATOR: + subview = [[RecentlyClosedSectionFooter alloc] initWithFrame:CGRectZero]; + [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; + break; + case CELL_OTHER_DEVICES_SECTION_HEADER: { + BOOL collapsed = [self sectionIsCollapsed:kOtherDeviceCollapsedKey]; + subview = [[GenericSectionHeaderView alloc] + initWithType:recent_tabs::OTHER_DEVICES_SECTION_HEADER + sectionIsCollapsed:collapsed]; + [subview setTag:kSectionHeader]; + break; + } + case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_OFF: + subview = [[SignedInSyncOffView alloc] initWithFrame:CGRectZero + browserState:self.browserState + presenter:self]; + [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; + break; + case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS: + subview = [[SignedInSyncOnNoSessionsView alloc] initWithFrame:CGRectZero]; + [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; + break; + case CELL_OTHER_DEVICES_SIGNIN_PROMO: { + if (!self.signinPromoViewMediator) { + self.signinPromoViewMediator = [[SigninPromoViewMediator alloc] + initWithBrowserState:self.browserState + accessPoint:signin_metrics::AccessPoint:: + ACCESS_POINT_RECENT_TABS + presenter:self /* id<SigninPresenter> */]; + self.signinPromoViewMediator.consumer = self; + } + contentViewTopMargin = kSigninPromoViewTopMargin; + SigninPromoView* signinPromoView = + [[SigninPromoView alloc] initWithFrame:CGRectZero]; + signinPromoView.delegate = self.signinPromoViewMediator; + signinPromoView.textLabel.text = + l10n_util::GetNSString(IDS_IOS_SIGNIN_PROMO_RECENT_TABS); + signinPromoView.textLabel.preferredMaxLayoutWidth = + CGRectGetWidth(self.tableView.bounds) - + 2 * signinPromoView.horizontalPadding; + SigninPromoViewConfigurator* configurator = + [self.signinPromoViewMediator createConfigurator]; + [configurator configureSigninPromoView:signinPromoView]; + subview = signinPromoView; + [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; + [self.signinPromoViewMediator signinPromoViewVisible]; + break; + } + case CELL_OTHER_DEVICES_SYNC_IN_PROGRESS: + subview = [[SignedInSyncInProgressView alloc] initWithFrame:CGRectZero]; + [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; + break; + case CELL_SESSION_SECTION_HEADER: { + synced_sessions::DistantSession const* distantSession = + [self sessionAtIndexPath:indexPath]; + NSString* key = [self keyForDistantSession:distantSession]; + BOOL collapsed = [self sectionIsCollapsed:key]; + SessionSectionHeaderView* sessionSectionHeader = + [[SessionSectionHeaderView alloc] initWithFrame:CGRectZero + sectionIsCollapsed:collapsed]; + [sessionSectionHeader updateWithSession:distantSession]; + subview = sessionSectionHeader; + [subview setTag:kSectionHeader]; + break; + } + case CELL_SESSION_TAB_DATA: { + SessionTabDataView* genericTabData = + [[SessionTabDataView alloc] initWithFrame:CGRectZero]; + [genericTabData updateWithDistantTab:[self distantTabAtIndex:indexPath] + browserState:self.browserState]; + subview = genericTabData; + break; + } + } + + DCHECK(subview); + [contentView addSubview:subview]; + + // Sets constraints on the subview. + [subview setTranslatesAutoresizingMaskIntoConstraints:NO]; + + NSDictionary* viewsDictionary = @{@"view" : subview}; + // This set of constraints should match the constraints set on the + // RecentlyClosedSectionFooter. + // clang-format off + NSArray* constraints = @[ + @"V:|-(TopMargin)-[view]-0-|", + @"H:|-(>=0)-[view(<=548)]-(>=0)-|", + @"H:[view(==548@500)]" + ]; + // clang-format on + [contentView addConstraint:[NSLayoutConstraint + constraintWithItem:subview + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:contentView + attribute:NSLayoutAttributeCenterX + multiplier:1 + constant:0]]; + NSDictionary* metrics = @{ @"TopMargin" : @(contentViewTopMargin) }; + ApplyVisualConstraintsWithMetrics(constraints, viewsDictionary, metrics); + return cell; +} + +#pragma mark - UITableViewDelegate + +- (NSIndexPath*)tableView:(UITableView*)tableView + willSelectRowAtIndexPath:(NSIndexPath*)indexPath { + DCHECK_EQ(tableView, self.tableView); + CellType cellType = [self cellType:indexPath]; + switch (cellType) { + case CELL_CLOSED_TAB_SECTION_HEADER: + case CELL_OTHER_DEVICES_SECTION_HEADER: + case CELL_SESSION_SECTION_HEADER: + case CELL_CLOSED_TAB_DATA: + case CELL_SESSION_TAB_DATA: + case CELL_SHOW_FULL_HISTORY: + return indexPath; + case CELL_SEPARATOR: + case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_OFF: + case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS: + case CELL_OTHER_DEVICES_SIGNIN_PROMO: + case CELL_OTHER_DEVICES_SYNC_IN_PROGRESS: + return nil; + } +} + +- (void)tableView:(UITableView*)tableView + didSelectRowAtIndexPath:(NSIndexPath*)indexPath { + DCHECK_EQ(tableView, self.tableView); + CellType cellType = [self cellType:indexPath]; + switch (cellType) { + case CELL_CLOSED_TAB_SECTION_HEADER: + case CELL_OTHER_DEVICES_SECTION_HEADER: + case CELL_SESSION_SECTION_HEADER: + // Collapse or uncollapse section. + [tableView deselectRowAtIndexPath:indexPath animated:NO]; + [self toggleExpansionOfSection:indexPath.section]; + break; + case CELL_CLOSED_TAB_DATA: + // Open new tab. + [self openTabWithTabRestoreEntry:[self tabRestoreEntryAtIndex:indexPath]]; + break; + case CELL_SESSION_TAB_DATA: + // Open new tab. + [self openTabWithContentOfDistantTab:[self distantTabAtIndex:indexPath]]; + break; + case CELL_SHOW_FULL_HISTORY: + [tableView deselectRowAtIndexPath:indexPath animated:NO]; + [self showFullHistory]; + break; + case CELL_SEPARATOR: + case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_OFF: + case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS: + case CELL_OTHER_DEVICES_SIGNIN_PROMO: + case CELL_OTHER_DEVICES_SYNC_IN_PROGRESS: + NOTREACHED(); + break; + } +} + +- (CGFloat)tableView:(UITableView*)tableView + heightForRowAtIndexPath:(NSIndexPath*)indexPath { + DCHECK_EQ(self.tableView, tableView); + CellType cellType = [self cellType:indexPath]; + switch (cellType) { + case CELL_SHOW_FULL_HISTORY: + return [ShowFullHistoryView desiredHeightInUITableViewCell]; + case CELL_SEPARATOR: + return [RecentlyClosedSectionFooter desiredHeightInUITableViewCell]; + case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_OFF: + return [SignedInSyncOffView desiredHeightInUITableViewCell]; + case CELL_OTHER_DEVICES_SIGNED_IN_SYNC_ON_NO_SESSIONS: + return [SignedInSyncOnNoSessionsView desiredHeightInUITableViewCell]; + case CELL_OTHER_DEVICES_SIGNIN_PROMO: + return UITableViewAutomaticDimension; + case CELL_SESSION_SECTION_HEADER: + return [SessionSectionHeaderView desiredHeightInUITableViewCell]; + case CELL_CLOSED_TAB_DATA: + case CELL_SESSION_TAB_DATA: + return [SessionTabDataView desiredHeightInUITableViewCell]; + case CELL_CLOSED_TAB_SECTION_HEADER: + case CELL_OTHER_DEVICES_SECTION_HEADER: + return [GenericSectionHeaderView desiredHeightInUITableViewCell]; + case CELL_OTHER_DEVICES_SYNC_IN_PROGRESS: + return [SignedInSyncInProgressView desiredHeightInUITableViewCell]; + } +} + +- (UIView*)tableView:(UITableView*)tableView + viewForHeaderInSection:(NSInteger)section { + if ([self sectionType:section] == CLOSED_TAB_SECTION) { + return [[RecentlyTabsTopSpacingHeader alloc] initWithFrame:CGRectZero]; + } + return nil; +} + +- (CGFloat)tableView:(UITableView*)tableView + heightForHeaderInSection:(NSInteger)section { + if ([self sectionType:section] == CLOSED_TAB_SECTION) { + return [RecentlyTabsTopSpacingHeader desiredHeightInUITableViewCell]; + } + return 0; +} + +#pragma mark - SigninPromoViewConsumer + +- (void)configureSigninPromoWithConfigurator: + (SigninPromoViewConfigurator*)configurator + identityChanged:(BOOL)identityChanged { + DCHECK(self.signinPromoViewMediator); + if ([self sectionIsCollapsed:kOtherDeviceCollapsedKey]) + return; + NSInteger sectionIndex = + [self sectionIndexForSectionType:OTHER_DEVICES_SECTION]; + DCHECK(sectionIndex != NSNotFound); + NSIndexPath* indexPath = + [NSIndexPath indexPathForRow:1 inSection:sectionIndex]; + if (identityChanged) { + [self.tableView reloadRowsAtIndexPaths:@[ indexPath ] + withRowAnimation:UITableViewRowAnimationNone]; + return; + } + UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath]; + NSArray<UIView*>* contentViews = cell.contentView.subviews; + DCHECK(contentViews.count == 1); + UIView* subview = contentViews[0]; + DCHECK([subview isKindOfClass:[SigninPromoView class]]); + SigninPromoView* signinPromoView = (SigninPromoView*)subview; + [configurator configureSigninPromoView:signinPromoView]; +} + +- (void)signinDidFinish { + [self.delegate refreshSessionsView]; +} + +#pragma mark - SyncPresenter + +- (void)showReauthenticateSignin { + [self.dispatcher + showSignin: + [[ShowSigninCommand alloc] + initWithOperation:AUTHENTICATION_OPERATION_REAUTHENTICATE + accessPoint:signin_metrics::AccessPoint:: + ACCESS_POINT_UNKNOWN] + baseViewController:self]; +} + +- (void)showSyncSettings { + [self.dispatcher showSyncSettingsFromViewController:self]; +} + +- (void)showSyncPassphraseSettings { + [self.dispatcher showSyncPassphraseSettingsFromViewController:self]; +} + +#pragma mark - SigninPresenter + +- (void)showSignin:(ShowSigninCommand*)command { + [self.dispatcher showSignin:command baseViewController:self]; } @end
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm index c5bdcd0a..db2665d 100644 --- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm +++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
@@ -537,6 +537,14 @@ return [self layoutRightViewForBounds:bounds]; } +#pragma mark - UITextInput + +- (void)beginFloatingCursorAtPoint:(CGPoint)point { + // Exit preedit because it blocks the view of the textfield. + [self exitPreEditState]; + [super beginFloatingCursorAtPoint:point]; +} + #pragma mark - UIView - (void)layoutSubviews {
diff --git a/ios/chrome/browser/ui/tab_grid/BUILD.gn b/ios/chrome/browser/ui/tab_grid/BUILD.gn index 0d24b23..57c0e97b 100644 --- a/ios/chrome/browser/ui/tab_grid/BUILD.gn +++ b/ios/chrome/browser/ui/tab_grid/BUILD.gn
@@ -20,6 +20,7 @@ ":tab_grid_ui", "//base", "//components/favicon/ios", + "//ios/chrome/browser", "//ios/chrome/browser/snapshots", "//ios/chrome/browser/tabs", "//ios/chrome/browser/ui/commands", @@ -49,6 +50,7 @@ "grid_view_controller.mm", "tab_grid_bottom_toolbar.h", "tab_grid_bottom_toolbar.mm", + "tab_grid_paging.h", "tab_grid_top_toolbar.h", "tab_grid_top_toolbar.mm", "tab_grid_transition_handler.h", @@ -95,3 +97,38 @@ "//third_party/ocmock", ] } + +source_set("eg_tests") { + configs += [ "//build/config/compiler:enable_arc" ] + testonly = true + sources = [ + "tab_grid_egtest.mm", + ] + + deps = [ + ":tab_grid_ui", + "//base", + "//components/strings", + "//ios/chrome/app:app_internal", + "//ios/chrome/app/strings", + "//ios/chrome/browser/ui:ui_util", + "//ios/chrome/browser/ui/util", + "//ios/chrome/test/app:test_support", + "//ios/chrome/test/earl_grey:test_support", + "//ios/testing/earl_grey:earl_grey_support", + "//ios/web:earl_grey_test_support", + "//ui/base", + ] + libs = [ "XCTest.framework" ] +} + +source_set("hooks") { + configs += [ "//build/config/compiler:enable_arc" ] + testonly = true + sources = [ + "tab_grid_egtests_hook.mm", + ] + deps = [ + "//ios/chrome/app:tests_hook", + ] +}
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.h b/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.h index f55dc12..ea8765f9 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.h +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.h
@@ -10,6 +10,8 @@ #import "ios/chrome/browser/ui/tab_grid/tab_grid_mediator.h" #import "ios/chrome/browser/ui/tab_switcher/tab_switcher.h" +@protocol TabGridPaging; + // An opque adaptor for the TabSwitcher protocol into the TabGrid. // Consuming objects should be passed instances of this object as an // id<TabSwitcher>. @@ -22,6 +24,8 @@ @property(nonatomic, weak) id<ApplicationCommands, BrowserCommands, OmniboxFocuser, ToolbarCommands> adaptedDispatcher; +// Object that can set the current page of the tab grid. +@property(nonatomic, weak) id<TabGridPaging> tabGridPager; // The mediator for the incognito grid. @property(nonatomic, weak) TabGridMediator* incognitoMediator; @end
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm index 2aa1a431..3cea4bb 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_adaptor.mm
@@ -6,6 +6,8 @@ #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/main/view_controller_swapping.h" +#import "ios/chrome/browser/ui/tab_grid/tab_grid_paging.h" + #import "ios/web/public/navigation_manager.h" #import "base/logging.h" @@ -21,6 +23,7 @@ // Public properties @synthesize tabGridViewController = _tabGridViewController; @synthesize adaptedDispatcher = _adaptedDispatcher; +@synthesize tabGridPager = _tabGridPager; @synthesize incognitoMediator = _incognitoMediator; #pragma mark - TabSwitcher @@ -41,7 +44,13 @@ - (void)restoreInternalStateWithMainTabModel:(TabModel*)mainModel otrTabModel:(TabModel*)otrModel activeTabModel:(TabModel*)activeModel { - // This is a no-op, but it will be called frequently. + // The only action here is to signal to the tab grid which panel should be + // active. + if (activeModel == otrModel) { + self.tabGridPager.currentPage = TabGridPageIncognitoTabs; + } else { + self.tabGridPager.currentPage = TabGridPageRegularTabs; + } } - (void)prepareForDisplayAtSize:(CGSize)size {
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm index 7a962ad..36125dc 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.mm
@@ -4,6 +4,7 @@ #import "ios/chrome/browser/ui/tab_grid/tab_grid_coordinator.h" +#include "ios/chrome/browser/chrome_url_constants.h" #import "ios/chrome/browser/tabs/tab_model.h" #import "ios/chrome/browser/ui/commands/browser_commands.h" #import "ios/chrome/browser/ui/commands/command_dispatcher.h" @@ -93,6 +94,7 @@ self.adaptor.adaptedDispatcher = static_cast<id<ApplicationCommands, BrowserCommands, OmniboxFocuser, ToolbarCommands>>(self.dispatcher); + self.adaptor.tabGridPager = mainViewController; self.regularTabsMediator = [[TabGridMediator alloc] initWithConsumer:mainViewController.regularTabsConsumer]; @@ -204,6 +206,15 @@ #pragma mark - BrowserCommands - (void)openNewTab:(OpenNewTabCommand*)command { + TabModel* activeTabModel = + command.incognito ? self.incognitoTabModel : self.regularTabModel; + // TODO(crbug.com/804587) : It is better to use the mediator to insert a + // webState and show the active tab. + [self.tabSwitcher + dismissWithNewTabAnimationToModel:activeTabModel + withURL:GURL(kChromeUINewTabURL) + atIndex:NSNotFound + transition:ui::PAGE_TRANSITION_TYPED]; } - (void)closeAllTabs {
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm new file mode 100644 index 0000000..2488df3 --- /dev/null +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_egtest.mm
@@ -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. + +#import "ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.h" +#import "ios/chrome/test/app/chrome_test_util.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" +#import "ios/chrome/test/earl_grey/chrome_matchers.h" +#import "ios/chrome/test/earl_grey/chrome_test_case.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { +// Matcher for done button in tab grid. +id<GREYMatcher> TabGridDoneButton() { + return grey_allOf(grey_accessibilityID(kTabGridDoneButtonAccessibilityID), + grey_sufficientlyVisible(), nil); +} +} // namespace + +@interface TabGridTestCase : ChromeTestCase +@end + +@implementation TabGridTestCase + +// Tests entering and leaving the tab grid. +- (void)testEnteringAndLeavingTabGrid { + [[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:TabGridDoneButton()] + performAction:grey_tap()]; +} + +@end
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_egtests_hook.mm b/ios/chrome/browser/ui/tab_grid/tab_grid_egtests_hook.mm new file mode 100644 index 0000000..681321c --- /dev/null +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_egtests_hook.mm
@@ -0,0 +1,54 @@ +// 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 "ios/chrome/app/tests_hook.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace tests_hook { + +bool DisableContentSuggestions() { + return true; +} + +bool DisableContextualSearch() { + return true; +} + +bool DisableFirstRun() { + return true; +} + +bool DisableGeolocation() { + return true; +} + +bool DisableSigninRecallPromo() { + return true; +} + +bool DisableUpdateService() { + return true; +} + +bool ForceUIRefreshPhase1() { + return true; +} + +// TODO(crbug.com/818560) : Remove this hook. +bool ForceTabSwitcherTabGrid() { + return true; +} + +void SetUpTestsIfPresent() { + // No-op for Earl Grey. +} + +void RunTestsIfPresent() { + // No-op for Earl Grey. +} + +} // namespace tests_hook
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_paging.h b/ios/chrome/browser/ui/tab_grid/tab_grid_paging.h new file mode 100644 index 0000000..c1dbea7 --- /dev/null +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_paging.h
@@ -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. + +#ifndef IOS_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_PAGING_H_ +#define IOS_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_PAGING_H_ + +// Page enumerates the kinds of grouped tabs. +typedef NS_ENUM(NSUInteger, TabGridPage) { + TabGridPageIncognitoTabs = 0, + TabGridPageRegularTabs = 1, + TabGridPageRemoteTabs = 2, +}; + +// An object implementing this protocol can change the active "page" of the tab +// grid. +@protocol TabGridPaging<NSObject> +// Current visible page of the tab grid. +@property(nonatomic, assign) TabGridPage currentPage; +@end + +#endif // IOS_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_PAGING_H_
diff --git a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.h b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.h index b94a268..0f9882f7 100644 --- a/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.h +++ b/ios/chrome/browser/ui/tab_grid/tab_grid_view_controller.h
@@ -7,18 +7,16 @@ #import <UIKit/UIKit.h> +#import "ios/chrome/browser/ui/tab_grid/tab_grid_paging.h" #import "ios/chrome/browser/ui/tab_grid/tab_grid_transition_state_provider.h" @protocol GridConsumer; @protocol GridCommands; @protocol GridImageDataSource; -// Page enumerates the kinds of grouped tabs. -typedef NS_ENUM(NSUInteger, TabGridPage) { - TabGridPageIncognitoTabs = 0, - TabGridPageRegularTabs = 1, - TabGridPageRemoteTabs = 2, -}; +// TODO(crbug.com/818198) : Move to constants file. +// The accessibility label for the done button for use in test automation. +extern NSString* const kTabGridDoneButtonAccessibilityID; // Delegate protocol for an object that can handle presenting ("opening") tabs // from the tab grid. @@ -30,7 +28,7 @@ // View controller representing a tab switcher. The tab switcher has an // incognito tab grid, regular tab grid, and remote tabs. @interface TabGridViewController - : UIViewController<TabGridTransitionStateProvider> + : UIViewController<TabGridPaging, TabGridTransitionStateProvider> // Delegate for this view controller to handle presenting tab UI. @property(nonatomic, weak) id<TabPresentationDelegate> tabPresentationDelegate; @@ -47,9 +45,6 @@ @property(nonatomic, weak) id<GridImageDataSource> regularTabsImageDataSource; @property(nonatomic, weak) id<GridImageDataSource> incognitoTabsImageDataSource; -// Current visible page. -@property(nonatomic, assign) TabGridPage currentPage; - @end #endif // IOS_CHROME_BROWSER_UI_TAB_GRID_TAB_GRID_VIEW_CONTROLLER_H_
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 be2bc89..6e0d026 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
@@ -16,6 +16,10 @@ #error "This file requires ARC support." #endif +// The accessibility label for the done button for use in test automation. +NSString* const kTabGridDoneButtonAccessibilityID = + @"TabGridDoneButtonAccessibilityID"; + namespace { // Temporary alert used while building this feature. UIAlertController* NotImplementedAlert() { @@ -53,6 +57,7 @@ @synthesize incognitoTabsDelegate = _incognitoTabsDelegate; @synthesize regularTabsImageDataSource = _regularTabsImageDataSource; @synthesize incognitoTabsImageDataSource = _incognitoTabsImageDataSource; +// TabGridPaging property. @synthesize currentPage = _currentPage; // Private properties. @synthesize regularTabsViewController = _regularTabsViewController; @@ -89,6 +94,13 @@ [self setupBottomToolbarButtons]; } +- (void)viewWillAppear:(BOOL)animated { + // Call the current page setter to sync the scroll view offset to the current + // page value. + self.currentPage = _currentPage; + [super viewWillAppear:animated]; +} + - (void)viewWillLayoutSubviews { [super viewWillLayoutSubviews]; // The content inset of the tab grids must be modified so that the toolbars @@ -121,7 +133,7 @@ CGFloat pageWidth = scrollView.frame.size.width; float fractionalPage = scrollView.contentOffset.x / pageWidth; NSUInteger page = lround(fractionalPage); - self.currentPage = static_cast<TabGridPage>(page); + _currentPage = static_cast<TabGridPage>(page); } #pragma mark - UIScrollViewAccessibilityDelegate @@ -168,6 +180,31 @@ _incognitoTabsImageDataSource = incognitoTabsImageDataSource; } +#pragma mark - TabGridPaging + +- (void)setCurrentPage:(TabGridPage)currentPage { + // This method should never early return if |currentPage| == |_currentPage|; + // the ivar may have been set before the scroll view could be updated. Calling + // this method should always update the scroll view's offset if possible. + + // If the view isn't loaded yet, just do bookkeeping on _currentPage. + if (!self.viewLoaded) { + _currentPage = currentPage; + return; + } + CGFloat pageWidth = self.scrollView.frame.size.width; + NSUInteger page = static_cast<NSUInteger>(currentPage); + CGPoint offset = CGPointMake(page * pageWidth, 0); + // If the view is visible, animate the change. Otherwise don't. + if (self.view.window == nil) { + self.scrollView.contentOffset = offset; + _currentPage = currentPage; + } else { + [self.scrollView setContentOffset:offset animated:YES]; + // _currentPage is set in scrollViewDidEndDecelerating: + } +} + #pragma mark - Private // Adds the scroll view and sets constraints. @@ -356,6 +393,7 @@ - (void)setupTopToolbarButtons { self.doneButton = self.topToolbar.leadingButton; self.closeAllButton = self.topToolbar.trailingButton; + self.doneButton.accessibilityIdentifier = kTabGridDoneButtonAccessibilityID; // TODO(crbug.com/818699) : Localize strings. [self.doneButton setTitle:@"Done" forState:UIControlStateNormal]; [self.closeAllButton setTitle:@"Close All" forState:UIControlStateNormal];
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_eg_tests_hook.mm b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_eg_tests_hook.mm index 7fa1b5b..15a705f 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_eg_tests_hook.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_eg_tests_hook.mm
@@ -38,6 +38,11 @@ return true; } +// TODO(crbug.com/818560) : Remove this hook. +bool ForceTabSwitcherTabGrid() { + return false; +} + void SetUpTestsIfPresent() { // No-op for Earl Grey. }
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm index 0609fd70..d02f3d45 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_egtest.mm
@@ -128,24 +128,20 @@ // Split toolbar. // Test the visibility of the primary toolbar buttons. - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - assertWithMatcher:VisibleInPrimaryToolbar()]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::ForwardButton()] - assertWithMatcher:VisibleInPrimaryToolbar()]; [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()] assertWithMatcher:VisibleInPrimaryToolbar()]; // Test the visibility of the secondary toolbar buttons. - [[EarlGrey selectElementWithMatcher:chrome_test_util:: - ButtonWithAccessibilityLabelId( - IDS_IOS_TOOLBAR_SHOW_TABS)] + [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] assertWithMatcher:VisibleInSecondaryToolbar()]; - [[EarlGrey selectElementWithMatcher:ShareButton()] + [[EarlGrey selectElementWithMatcher:chrome_test_util::ForwardButton()] assertWithMatcher:VisibleInSecondaryToolbar()]; [[EarlGrey selectElementWithMatcher:grey_accessibilityID( kToolbarOmniboxButtonIdentifier)] assertWithMatcher:VisibleInSecondaryToolbar()]; - [[EarlGrey selectElementWithMatcher:BookmarkButton()] + [[EarlGrey selectElementWithMatcher:chrome_test_util:: + ButtonWithAccessibilityLabelId( + IDS_IOS_TOOLBAR_SHOW_TABS)] assertWithMatcher:VisibleInSecondaryToolbar()]; [[EarlGrey selectElementWithMatcher:chrome_test_util:: ButtonWithAccessibilityLabelId( @@ -203,14 +199,8 @@ IDS_CANCEL), VisibleInPrimaryToolbar(), nil)] assertWithMatcher:grey_notNil()]; - - // Check that controls are faded out. - [[EarlGrey selectElementWithMatcher:chrome_test_util::ForwardButton()] - assertWithMatcher:grey_not(grey_sufficientlyVisible())]; - [[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()] - assertWithMatcher:grey_not(grey_sufficientlyVisible())]; } else { - // Check that the cancel button is shown. + // Check that the cancel button is hidden. [[EarlGrey selectElementWithMatcher: grey_allOf( @@ -236,6 +226,12 @@ // Tests that bookmarks button is selected for the bookmarked pages. - (void)testBookmarkButton { + if (!IsIPadIdiom()) { + // If this test is run on an iPhone, rotate it to have the unsplit toolbar. + [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft + errorOrNil:nil]; + } + // Setup the bookmarks. [ChromeEarlGrey waitForBookmarksToFinishLoading]; GREYAssert(chrome_test_util::ClearBookmarks(), @@ -270,6 +266,12 @@ // Clean the bookmarks GREYAssert(chrome_test_util::ClearBookmarks(), @"Not all bookmarks were removed."); + + if (!IsIPadIdiom()) { + // Cancel rotation. + [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationPortrait + errorOrNil:nil]; + } } // Tests that tapping a button cancels the focus on the omnibox. @@ -469,20 +471,28 @@ // Tests share button is enabled only on pages that can be shared. - (void)testShareButton { + if (!IsIPadIdiom()) { + // If this test is run on an iPhone, rotate it to have the unsplit toolbar. + [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft + errorOrNil:nil]; + } + // Setup the server. self.testServer->RegisterRequestHandler( base::BindRepeating(&StandardResponse)); GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); const GURL pageURL = self.testServer->GetURL(kPageURL); - // The button is disabled on the NTP. - [[EarlGrey selectElementWithMatcher:ShareButton()] - assertWithMatcher:grey_not(grey_enabled())]; - // Navigate to another page and check that the share button is enabled. [ChromeEarlGrey loadURL:pageURL]; [[EarlGrey selectElementWithMatcher:ShareButton()] assertWithMatcher:grey_interactable()]; + + if (!IsIPadIdiom()) { + // Cancel rotation. + [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationPortrait + errorOrNil:nil]; + } } // Verifies the existence and state of toolbar UI elements.
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view.h b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view.h index aed7ce9f..e772597 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view.h +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view.h
@@ -24,6 +24,8 @@ // Button to navigate back. @property(nonatomic, strong, readonly) ToolbarButton* backButton; +// Buttons to navigate forward. +@property(nonatomic, strong, readonly) ToolbarButton* forwardButton; // Button to display the TabGrid. @property(nonatomic, strong, readonly) ToolbarTabGridButton* tabGridButton; // Button to stop the loading of the page. @@ -39,15 +41,6 @@ // Button to display the tools menu. @property(nonatomic, strong, readonly) ToolbarButton* omniboxButton; -// The following 2 properties are for the two buttons to navigate forward that -// are visible in various mutually exclusive configurations of the toolbar. -// Forward button when it's positioned on the leading side of the toolbar -// (relatively to the omnibox) | ← → [omnibox] ㉈ â‹® |. -@property(nonatomic, strong, readonly) ToolbarButton* forwardLeadingButton; -// Forward button when it's positioned on the trailing side of the toolbar -// (relatively to the omnibox) | ← [omnibox] → |. -@property(nonatomic, strong, readonly) ToolbarButton* forwardTrailingButton; - @end #endif // IOS_CHROME_BROWSER_UI_TOOLBAR_ADAPTIVE_ADAPTIVE_TOOLBAR_VIEW_H_
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.mm index e007aaf..bae75e8 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.mm
@@ -73,8 +73,7 @@ #pragma mark - ToolbarConsumer - (void)setCanGoForward:(BOOL)canGoForward { - self.view.forwardLeadingButton.enabled = canGoForward; - self.view.forwardTrailingButton.enabled = canGoForward; + self.view.forwardButton.enabled = canGoForward; } - (void)setCanGoBack:(BOOL)canGoBack { @@ -179,10 +178,12 @@ // Records the use of a button. - (IBAction)recordUserMetrics:(id)sender { + if (!sender) + return; + if (sender == self.view.backButton) { base::RecordAction(base::UserMetricsAction("MobileToolbarBack")); - } else if (sender == self.view.forwardLeadingButton || - sender == self.view.forwardTrailingButton) { + } else if (sender == self.view.forwardButton) { base::RecordAction(base::UserMetricsAction("MobileToolbarForward")); } else if (sender == self.view.reloadButton) { base::RecordAction(base::UserMetricsAction("MobileToolbarReload"));
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.h b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.h index a58f569..6f8d9e9 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.h +++ b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.h
@@ -46,12 +46,18 @@ // Button to cancel the edit of the location bar. @property(nonatomic, strong, readonly) UIButton* cancelButton; -// Constraints to be activated when the location bar is focused. +// Constraints to be activated when the location bar is expanded and positioned +// relatively to the cancel button. @property(nonatomic, strong, readonly) - NSMutableArray<NSLayoutConstraint*>* focusedConstraints; -// Constraints to be activated when the location bar is unfocused. + NSMutableArray<NSLayoutConstraint*>* expandedConstraints; +// Constraints to be activated when the location bar is contracted with large +// padding between the location bar and the controls. @property(nonatomic, strong, readonly) - NSMutableArray<NSLayoutConstraint*>* unfocusedConstraints; + NSMutableArray<NSLayoutConstraint*>* contractedConstraints; +// Constraints to be activated when the location bar is expanded without cancel +// button. +@property(nonatomic, strong, readonly) + NSMutableArray<NSLayoutConstraint*>* contractedNoMarginConstraints; // Constraint for the bottom of the location bar. @property(nonatomic, strong, readwrite)
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.mm index 7a72d46e..0510cedd 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.mm
@@ -48,8 +48,8 @@ #pragma mark** Buttons in the leading stack view. ** // Button to navigate back, redefined as readwrite. @property(nonatomic, strong, readwrite) ToolbarButton* backButton; -// Button to navigate forward, leading position, redefined as readwrite. -@property(nonatomic, strong, readwrite) ToolbarButton* forwardLeadingButton; +// Button to navigate forward, redefined as readwrite. +@property(nonatomic, strong, readwrite) ToolbarButton* forwardButton; // Button to display the TabGrid, redefined as readwrite. @property(nonatomic, strong, readwrite) ToolbarTabGridButton* tabGridButton; // Button to stop the loading of the page, redefined as readwrite. @@ -58,8 +58,6 @@ @property(nonatomic, strong, readwrite) ToolbarButton* reloadButton; #pragma mark** Buttons in the trailing stack view. ** -// Button to navigate forward, trailing position, redefined as readwrite. -@property(nonatomic, strong, readwrite) ToolbarButton* forwardTrailingButton; // Button to display the share menu, redefined as readwrite. @property(nonatomic, strong, readwrite) ToolbarButton* shareButton; // Button to manage the bookmarks of this page, redefined as readwrite. @@ -70,14 +68,13 @@ // Button to cancel the edit of the location bar, redefined as readwrite. @property(nonatomic, strong, readwrite) UIButton* cancelButton; -// Constraints to be activated when the location bar is focused, redefined as -// readwrite. +// Constraints for the location bar, redefined as readwrite. @property(nonatomic, strong, readwrite) - NSMutableArray<NSLayoutConstraint*>* focusedConstraints; -// Constraints to be activated when the location bar is unfocused, redefined as -// readwrite. + NSMutableArray<NSLayoutConstraint*>* expandedConstraints; @property(nonatomic, strong, readwrite) - NSMutableArray<NSLayoutConstraint*>* unfocusedConstraints; + NSMutableArray<NSLayoutConstraint*>* contractedConstraints; +@property(nonatomic, strong, readwrite) + NSMutableArray<NSLayoutConstraint*>* contractedNoMarginConstraints; @end @@ -92,20 +89,20 @@ @synthesize leadingStackView = _leadingStackView; @synthesize leadingStackViewButtons = _leadingStackViewButtons; @synthesize backButton = _backButton; -@synthesize forwardLeadingButton = _forwardLeadingButton; +@synthesize forwardButton = _forwardButton; @synthesize tabGridButton = _tabGridButton; @synthesize stopButton = _stopButton; @synthesize reloadButton = _reloadButton; @synthesize locationBarContainer = _locationBarContainer; @synthesize trailingStackView = _trailingStackView; @synthesize trailingStackViewButtons = _trailingStackViewButtons; -@synthesize forwardTrailingButton = _forwardTrailingButton; @synthesize shareButton = _shareButton; @synthesize bookmarkButton = _bookmarkButton; @synthesize toolsMenuButton = _toolsMenuButton; @synthesize cancelButton = _cancelButton; -@synthesize focusedConstraints = _focusedConstraints; -@synthesize unfocusedConstraints = _unfocusedConstraints; +@synthesize expandedConstraints = _expandedConstraints; +@synthesize contractedConstraints = _contractedConstraints; +@synthesize contractedNoMarginConstraints = _contractedNoMarginConstraints; @synthesize blur = _blur; @synthesize contentView = _contentView; @@ -175,7 +172,7 @@ - (void)setUpCancelButton { self.cancelButton = [self.buttonFactory cancelButton]; self.cancelButton.translatesAutoresizingMaskIntoConstraints = NO; - [self.contentView addSubview:self.cancelButton]; + [self addSubview:self.cancelButton]; } // Sets the location bar container and its view if present. @@ -202,38 +199,43 @@ // Sets the leading stack view. - (void)setUpLeadingStackView { self.backButton = [self.buttonFactory backButton]; - self.forwardLeadingButton = [self.buttonFactory leadingForwardButton]; + self.forwardButton = [self.buttonFactory forwardButton]; self.tabGridButton = [self.buttonFactory tabGridButton]; self.stopButton = [self.buttonFactory stopButton]; self.stopButton.hiddenInCurrentState = YES; self.reloadButton = [self.buttonFactory reloadButton]; self.leadingStackViewButtons = @[ - self.backButton, self.forwardLeadingButton, self.tabGridButton, - self.stopButton, self.reloadButton + self.backButton, self.forwardButton, self.tabGridButton, self.stopButton, + self.reloadButton ]; self.leadingStackView = [[UIStackView alloc] initWithArrangedSubviews:self.leadingStackViewButtons]; self.leadingStackView.translatesAutoresizingMaskIntoConstraints = NO; self.leadingStackView.spacing = kAdaptiveToolbarStackViewSpacing; + [self.leadingStackView + setContentHuggingPriority:UILayoutPriorityDefaultHigh + forAxis:UILayoutConstraintAxisHorizontal]; + [self.contentView addSubview:self.leadingStackView]; } // Sets the trailing stack view. - (void)setUpTrailingStackView { - self.forwardTrailingButton = [self.buttonFactory trailingForwardButton]; self.shareButton = [self.buttonFactory shareButton]; self.bookmarkButton = [self.buttonFactory bookmarkButton]; self.toolsMenuButton = [self.buttonFactory toolsMenuButton]; - self.trailingStackViewButtons = @[ - self.forwardTrailingButton, self.shareButton, self.bookmarkButton, - self.toolsMenuButton - ]; + self.trailingStackViewButtons = + @[ self.shareButton, self.bookmarkButton, self.toolsMenuButton ]; self.trailingStackView = [[UIStackView alloc] initWithArrangedSubviews:self.trailingStackViewButtons]; self.trailingStackView.translatesAutoresizingMaskIntoConstraints = NO; self.trailingStackView.spacing = kAdaptiveToolbarStackViewSpacing; + [self.trailingStackView + setContentHuggingPriority:UILayoutPriorityDefaultHigh + forAxis:UILayoutConstraintAxisHorizontal]; + [self.contentView addSubview:self.trailingStackView]; } @@ -248,8 +250,9 @@ // Sets the constraints up. - (void)setUpConstraints { id<LayoutGuideProvider> safeArea = SafeAreaLayoutGuideForView(self); - self.focusedConstraints = [NSMutableArray array]; - self.unfocusedConstraints = [NSMutableArray array]; + self.expandedConstraints = [NSMutableArray array]; + self.contractedConstraints = [NSMutableArray array]; + self.contractedNoMarginConstraints = [NSMutableArray array]; // Leading StackView constraints [NSLayoutConstraint activateConstraints:@[ @@ -274,7 +277,7 @@ self.locationBarBottomConstraint, self.locationBarHeight, ]]; - [self.unfocusedConstraints addObjectsFromArray:@[ + [self.contractedConstraints addObjectsFromArray:@[ [self.locationBarContainer.trailingAnchor constraintEqualToAnchor:self.trailingStackView.leadingAnchor constant:-kContractedLocationBarHorizontalMargin], @@ -282,7 +285,15 @@ constraintEqualToAnchor:self.leadingStackView.trailingAnchor constant:kContractedLocationBarHorizontalMargin], ]]; - [self.focusedConstraints addObjectsFromArray:@[ + [self.contractedNoMarginConstraints addObjectsFromArray:@[ + [self.locationBarContainer.leadingAnchor + constraintEqualToAnchor:safeArea.leadingAnchor + constant:kExpandedLocationBarHorizontalMargin], + [self.locationBarContainer.trailingAnchor + constraintEqualToAnchor:safeArea.trailingAnchor + constant:-kExpandedLocationBarHorizontalMargin] + ]]; + [self.expandedConstraints addObjectsFromArray:@[ [self.locationBarContainer.trailingAnchor constraintEqualToAnchor:self.cancelButton.leadingAnchor], [self.locationBarContainer.leadingAnchor @@ -304,7 +315,13 @@ // locationBarView constraints, if present. if (self.locationBarView) { - AddSameConstraints(self.locationBarContainer, self.locationBarView); + AddSameConstraintsToSides( + self.locationBarView, self.locationBarContainer, + LayoutSides::kTop | LayoutSides::kBottom | LayoutSides::kLeading); + [self.locationBarContainer.trailingAnchor + constraintGreaterThanOrEqualToAnchor:self.locationBarView + .trailingAnchor] + .active = YES; } // Cancel button constraints. @@ -314,13 +331,14 @@ [self.cancelButton.bottomAnchor constraintEqualToAnchor:self.trailingStackView.bottomAnchor], ]]; - NSLayoutConstraint* focusedTrailing = [self.cancelButton.trailingAnchor + NSLayoutConstraint* visibleCancel = [self.cancelButton.trailingAnchor constraintEqualToAnchor:safeArea.trailingAnchor constant:-kExpandedLocationBarHorizontalMargin]; - [self.focusedConstraints addObject:focusedTrailing]; - [self.unfocusedConstraints - addObject:[self.cancelButton.leadingAnchor - constraintEqualToAnchor:self.trailingAnchor]]; + NSLayoutConstraint* hiddenCancel = [self.cancelButton.leadingAnchor + constraintEqualToAnchor:self.trailingAnchor]; + [self.expandedConstraints addObject:visibleCancel]; + [self.contractedConstraints addObject:hiddenCancel]; + [self.contractedNoMarginConstraints addObject:hiddenCancel]; // ProgressBar constraints. [NSLayoutConstraint activateConstraints:@[ @@ -331,8 +349,6 @@ [self.progressBar.heightAnchor constraintEqualToConstant:kProgressBarHeight], ]]; - - [NSLayoutConstraint activateConstraints:self.unfocusedConstraints]; } #pragma mark - Property accessors @@ -352,7 +368,12 @@ return; [self.locationBarContainer addSubview:locationBarView]; - AddSameConstraints(self.locationBarContainer, locationBarView); + AddSameConstraintsToSides( + self.locationBarView, self.locationBarContainer, + LayoutSides::kTop | LayoutSides::kBottom | LayoutSides::kLeading); + [self.locationBarContainer.trailingAnchor + constraintGreaterThanOrEqualToAnchor:self.locationBarView.trailingAnchor] + .active = YES; } - (NSArray<ToolbarButton*>*)allButtons {
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm index e64229f..0d592aac 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.mm
@@ -19,7 +19,8 @@ #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_configuration.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_constants.h" #import "ios/chrome/browser/ui/toolbar/buttons/toolbar_tools_menu_button.h" -#include "ios/chrome/browser/ui/ui_util.h" +#import "ios/chrome/browser/ui/ui_util.h" +#import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/util/named_guide.h" #import "ios/third_party/material_components_ios/src/components/ProgressView/src/MaterialProgressView.h" @@ -75,7 +76,6 @@ - (void)setScrollProgressForTabletOmnibox:(CGFloat)progress { [super setScrollProgressForTabletOmnibox:progress]; - DCHECK(IsIPadIdiom()); self.view.locationBarBottomConstraint.constant = -kLocationBarVerticalMargin * progress; self.view.locationBarContainer.alpha = progress; @@ -98,14 +98,12 @@ // Adds the layout guide to the buttons. self.view.toolsMenuButton.guideName = kTabSwitcherGuide; - self.view.forwardLeadingButton.guideName = kForwardButtonGuide; - self.view.forwardTrailingButton.guideName = kForwardButtonGuide; + self.view.forwardButton.guideName = kForwardButtonGuide; self.view.backButton.guideName = kBackButtonGuide; // Add navigation popup menu triggers. [self addLongPressGestureToView:self.view.backButton]; - [self addLongPressGestureToView:self.view.forwardLeadingButton]; - [self addLongPressGestureToView:self.view.forwardTrailingButton]; + [self addLongPressGestureToView:self.view.forwardButton]; } - (void)didMoveToParentViewController:(UIViewController*)parent { @@ -148,15 +146,13 @@ if (buttonType == ToolbarButtonTypeBack) { self.view.backButton.selected = YES; } else { - self.view.forwardLeadingButton.selected = YES; - self.view.forwardTrailingButton.selected = YES; + self.view.forwardButton.selected = YES; } } - (void)updateUIForTabHistoryWasDismissed { self.view.backButton.selected = NO; - self.view.forwardLeadingButton.selected = NO; - self.view.forwardTrailingButton.selected = NO; + self.view.forwardButton.selected = NO; } #pragma mark - FullscreenUIElement @@ -207,14 +203,19 @@ #pragma mark - ToolbarAnimatee - (void)expandLocationBar { - [NSLayoutConstraint deactivateConstraints:self.view.unfocusedConstraints]; - [NSLayoutConstraint activateConstraints:self.view.focusedConstraints]; + [self deactivateViewLocationBarConstraints]; + [NSLayoutConstraint activateConstraints:self.view.expandedConstraints]; [self.view layoutIfNeeded]; } - (void)contractLocationBar { - [NSLayoutConstraint deactivateConstraints:self.view.focusedConstraints]; - [NSLayoutConstraint activateConstraints:self.view.unfocusedConstraints]; + [self deactivateViewLocationBarConstraints]; + if (IsSplitToolbarMode(self)) { + [NSLayoutConstraint + activateConstraints:self.view.contractedNoMarginConstraints]; + } else { + [NSLayoutConstraint activateConstraints:self.view.contractedConstraints]; + } [self.view layoutIfNeeded]; } @@ -240,6 +241,14 @@ #pragma mark - Private +// Deactivates the constraints on the location bar positioning. +- (void)deactivateViewLocationBarConstraints { + [NSLayoutConstraint deactivateConstraints:self.view.contractedConstraints]; + [NSLayoutConstraint + deactivateConstraints:self.view.contractedNoMarginConstraints]; + [NSLayoutConstraint deactivateConstraints:self.view.expandedConstraints]; +} + // Adds a LongPressGesture to the |view|, with target on -|handleLongPress:|. - (void)addLongPressGestureToView:(UIView*)view { UILongPressGestureRecognizer* navigationHistoryLongPress = @@ -256,8 +265,7 @@ if (gesture.view == self.view.backButton) { [self.dispatcher showTabHistoryPopupForBackwardHistory]; - } else if (gesture.view == self.view.forwardLeadingButton || - gesture.view == self.view.forwardTrailingButton) { + } else if (gesture.view == self.view.forwardButton) { [self.dispatcher showTabHistoryPopupForForwardHistory]; } }
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_view.mm b/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_view.mm index e8fe3744..2926bc0 100644 --- a/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_view.mm
@@ -26,16 +26,16 @@ // The stack view containing the buttons. @property(nonatomic, strong) UIStackView* stackView; +// Button to navigate back, redefined as readwrite. +@property(nonatomic, strong, readwrite) ToolbarButton* backButton; +// Buttons to navigate forward, redefined as readwrite. +@property(nonatomic, strong, readwrite) ToolbarButton* forwardButton; // Button to display the tools menu, redefined as readwrite. @property(nonatomic, strong, readwrite) ToolbarToolsMenuButton* toolsMenuButton; // Button to display the tab grid, redefined as readwrite. @property(nonatomic, strong, readwrite) ToolbarTabGridButton* tabGridButton; -// Button to display the share menu, redefined as readwrite. -@property(nonatomic, strong, readwrite) ToolbarButton* shareButton; // Button to focus the omnibox, redefined as readwrite. @property(nonatomic, strong, readwrite) ToolbarButton* omniboxButton; -// Button to manage the bookmarks of this page, defined as readwrite. -@property(nonatomic, strong, readwrite) ToolbarButton* bookmarkButton; @end @@ -44,10 +44,10 @@ @synthesize allButtons = _allButtons; @synthesize buttonFactory = _buttonFactory; @synthesize stackView = _stackView; +@synthesize backButton = _backButton; +@synthesize forwardButton = _forwardButton; @synthesize toolsMenuButton = _toolsMenuButton; -@synthesize shareButton = _shareButton; @synthesize omniboxButton = _omniboxButton; -@synthesize bookmarkButton = _bookmarkButton; @synthesize tabGridButton = _tabGridButton; #pragma mark - Public @@ -101,15 +101,15 @@ contentView = vibrancyView.contentView; } - self.tabGridButton = [self.buttonFactory tabGridButton]; - self.shareButton = [self.buttonFactory shareButton]; + self.backButton = [self.buttonFactory backButton]; + self.forwardButton = [self.buttonFactory forwardButton]; self.omniboxButton = [self.buttonFactory omniboxButton]; - self.bookmarkButton = [self.buttonFactory bookmarkButton]; + self.tabGridButton = [self.buttonFactory tabGridButton]; self.toolsMenuButton = [self.buttonFactory toolsMenuButton]; self.allButtons = @[ - self.tabGridButton, self.shareButton, self.omniboxButton, - self.bookmarkButton, self.toolsMenuButton + self.backButton, self.forwardButton, self.omniboxButton, self.tabGridButton, + self.toolsMenuButton ]; self.stackView = @@ -135,18 +135,6 @@ #pragma mark - AdaptiveToolbarView -- (ToolbarButton*)backButton { - return nil; -} - -- (ToolbarButton*)forwardLeadingButton { - return nil; -} - -- (ToolbarButton*)forwardTrailingButton { - return nil; -} - - (ToolbarButton*)stopButton { return nil; } @@ -159,4 +147,12 @@ return nil; } +- (ToolbarButton*)bookmarkButton { + return nil; +} + +- (ToolbarButton*)shareButton { + return nil; +} + @end
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h index 9404daa5..a00cf6f 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h
@@ -41,10 +41,8 @@ // Back ToolbarButton. - (ToolbarButton*)backButton; -// Forward ToolbarButton to be displayed on the leading side of the toolbar. -- (ToolbarButton*)leadingForwardButton; -// Forward ToolbarButton to be displayed on the trailing side of the toolbar. -- (ToolbarButton*)trailingForwardButton; +// Forward ToolbarButton. +- (ToolbarButton*)forwardButton; // Tab Grid ToolbarButton. - (ToolbarTabGridButton*)tabGridButton; // Tab Switcher Strip ToolbarButton.
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm index c7e61ea..a106ae4 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.mm
@@ -98,17 +98,44 @@ return backButton; } -- (ToolbarButton*)leadingForwardButton { - ToolbarButton* forwardButton = self.forwardButton; +// Returns a forward button without visibility mask configured. +- (ToolbarButton*)forwardButton { + int forwardButtonImages[styleCount][TOOLBAR_STATE_COUNT] = + TOOLBAR_IDR_THREE_STATE(FORWARD); + ToolbarButton* forwardButton = nil; + if (IsUIRefreshPhase1Enabled()) { + forwardButton = [ToolbarButton + toolbarButtonWithImage:[[UIImage imageNamed:@"toolbar_forward"] + imageFlippedForRightToLeftLayoutDirection]]; + [self configureButton:forwardButton width:kAdaptiveToolbarButtonWidth]; + } else { + forwardButton = [ToolbarButton + toolbarButtonWithImageForNormalState:NativeReversableImage( + forwardButtonImages[self.style] + [DEFAULT], + YES) + imageForHighlightedState:NativeReversableImage( + forwardButtonImages[self.style] + [PRESSED], + YES) + imageForDisabledState:NativeReversableImage( + forwardButtonImages[self.style] + [DISABLED], + YES)]; + [self configureButton:forwardButton width:kToolbarButtonWidth]; + if (!IsIPadIdiom()) { + forwardButton.imageEdgeInsets = + UIEdgeInsetsMakeDirected(0, kForwardButtonImageInset, 0, 0); + } + } forwardButton.visibilityMask = - self.visibilityConfiguration.leadingForwardButtonVisibility; - return forwardButton; -} - -- (ToolbarButton*)trailingForwardButton { - ToolbarButton* forwardButton = self.forwardButton; - forwardButton.visibilityMask = - self.visibilityConfiguration.trailingForwardButtonVisibility; + self.visibilityConfiguration.forwardButtonVisibility; + DCHECK(forwardButton); + forwardButton.accessibilityLabel = + l10n_util::GetNSString(IDS_ACCNAME_FORWARD); + [forwardButton addTarget:self.dispatcher + action:@selector(goForward) + forControlEvents:UIControlEventTouchUpInside]; return forwardButton; } @@ -464,43 +491,5 @@ nil]; } -// Returns a forward button without visibility mask configured. -- (ToolbarButton*)forwardButton { - int forwardButtonImages[styleCount][TOOLBAR_STATE_COUNT] = - TOOLBAR_IDR_THREE_STATE(FORWARD); - ToolbarButton* forwardButton = nil; - if (IsUIRefreshPhase1Enabled()) { - forwardButton = [ToolbarButton - toolbarButtonWithImage:[[UIImage imageNamed:@"toolbar_forward"] - imageFlippedForRightToLeftLayoutDirection]]; - [self configureButton:forwardButton width:kAdaptiveToolbarButtonWidth]; - } else { - forwardButton = [ToolbarButton - toolbarButtonWithImageForNormalState:NativeReversableImage( - forwardButtonImages[self.style] - [DEFAULT], - YES) - imageForHighlightedState:NativeReversableImage( - forwardButtonImages[self.style] - [PRESSED], - YES) - imageForDisabledState:NativeReversableImage( - forwardButtonImages[self.style] - [DISABLED], - YES)]; - [self configureButton:forwardButton width:kToolbarButtonWidth]; - if (!IsIPadIdiom()) { - forwardButton.imageEdgeInsets = - UIEdgeInsetsMakeDirected(0, kForwardButtonImageInset, 0, 0); - } - } - DCHECK(forwardButton); - forwardButton.accessibilityLabel = - l10n_util::GetNSString(IDS_ACCNAME_FORWARD); - [forwardButton addTarget:self.dispatcher - action:@selector(goForward) - forControlEvents:UIControlEventTouchUpInside]; - return forwardButton; -} @end
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.h b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.h index cebf50f..a2a8207c 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.h +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.h
@@ -26,9 +26,7 @@ // Configuration for the forward button displayed in the leading part of the // toolbar. @property(nonatomic, readonly) - ToolbarComponentVisibility leadingForwardButtonVisibility; -@property(nonatomic, readonly) - ToolbarComponentVisibility trailingForwardButtonVisibility; + ToolbarComponentVisibility forwardButtonVisibility; @property(nonatomic, readonly) ToolbarComponentVisibility tabGridButtonVisibility; @property(nonatomic, readonly)
diff --git a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.mm b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.mm index 0401486..3f2f632 100644 --- a/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.mm +++ b/ios/chrome/browser/ui/toolbar/buttons/toolbar_button_visibility_configuration.mm
@@ -23,38 +23,28 @@ - (ToolbarComponentVisibility)backButtonVisibility { switch (self.type) { case PRIMARY: - return ToolbarComponentVisibilityAlways; + return ToolbarComponentVisibilityAlways & + ~ToolbarComponentVisibilitySplit; case SECONDARY: - return ToolbarComponentVisibilityNone; + return ToolbarComponentVisibilitySplit; case LEGACY: return ToolbarComponentVisibilityAlways; } } -- (ToolbarComponentVisibility)leadingForwardButtonVisibility { +- (ToolbarComponentVisibility)forwardButtonVisibility { switch (self.type) { case PRIMARY: return ToolbarComponentVisibilityAlways & - ~self.trailingForwardButtonVisibility; + ~ToolbarComponentVisibilitySplit; case SECONDARY: - return ToolbarComponentVisibilityNone; + return ToolbarComponentVisibilitySplit; case LEGACY: return ToolbarComponentVisibilityOnlyWhenEnabled | ToolbarComponentVisibilityRegularWidthRegularHeight; } } -- (ToolbarComponentVisibility)trailingForwardButtonVisibility { - switch (self.type) { - case PRIMARY: - return ToolbarComponentVisibilityCompactWidthRegularHeight; - case SECONDARY: - return ToolbarComponentVisibilityNone; - case LEGACY: - return ToolbarComponentVisibilityNone; - } -} - - (ToolbarComponentVisibility)tabGridButtonVisibility { switch (self.type) { case PRIMARY: @@ -85,7 +75,7 @@ return ToolbarComponentVisibilityAlways & ~ToolbarComponentVisibilityCompactWidthRegularHeight; case SECONDARY: - return ToolbarComponentVisibilitySplit; + return ToolbarComponentVisibilityNone; case LEGACY: return ToolbarComponentVisibilityRegularWidthRegularHeight; } @@ -119,7 +109,7 @@ return ToolbarComponentVisibilityAlways & ~ToolbarComponentVisibilityCompactWidthRegularHeight; case SECONDARY: - return ToolbarComponentVisibilitySplit; + return ToolbarComponentVisibilityNone; case LEGACY: return ToolbarComponentVisibilityRegularWidthCompactHeight | ToolbarComponentVisibilityRegularWidthRegularHeight;
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_view.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_view.mm index 4b7f63b..4e46f2cd6 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_view.mm +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_view.mm
@@ -131,7 +131,7 @@ - (void)setUpToolbarButtons { self.backButton = [self.buttonFactory backButton]; - self.forwardButton = [self.buttonFactory leadingForwardButton]; + self.forwardButton = [self.buttonFactory forwardButton]; self.tabSwitchStripButton = [self.buttonFactory tabSwitcherStripButton]; self.toolsMenuButton = [self.buttonFactory toolsMenuButton]; self.shareButton = [self.buttonFactory shareButton];
diff --git a/ios/chrome/browser/ui/ui_util.mm b/ios/chrome/browser/ui/ui_util.mm index 5f0432f..9e68e25 100644 --- a/ios/chrome/browser/ui/ui_util.mm +++ b/ios/chrome/browser/ui/ui_util.mm
@@ -63,7 +63,10 @@ return base::FeatureList::IsEnabled(kUIRefreshPhase1); } +// TODO(crbug.com/818560) : Remove this flag. bool IsTabSwitcherTabGridEnabled() { + if (tests_hook::ForceTabSwitcherTabGrid()) + return true; return base::FeatureList::IsEnabled(kTabSwitcherTabGrid); }
diff --git a/ios/chrome/test/app/chrome_test_util.mm b/ios/chrome/test/app/chrome_test_util.mm index c1ffaf9a..0008ad6b 100644 --- a/ios/chrome/test/app/chrome_test_util.mm +++ b/ios/chrome/test/app/chrome_test_util.mm
@@ -114,9 +114,19 @@ UIViewController* GetActiveViewController() { UIWindow* main_window = [[UIApplication sharedApplication] keyWindow]; DCHECK([main_window isKindOfClass:[ChromeOverlayWindow class]]); - id<ViewControllerSwapping> main_view_controller = - static_cast<id<ViewControllerSwapping>>([main_window rootViewController]); - return main_view_controller.activeViewController; + UIViewController* main_view_controller = main_window.rootViewController; + if ([main_view_controller + conformsToProtocol:@protocol(ViewControllerSwapping)]) { + // This is either the stack_view or the iPad tab_switcher, in which case it + // is best to call |-activeViewController|. + return [static_cast<id<ViewControllerSwapping>>(main_view_controller) + activeViewController]; + } + // The active view controller is either the TabGridViewController or its + // presented BVC. + return main_view_controller.presentedViewController + ? main_view_controller.presentedViewController + : main_view_controller; } id<ApplicationCommands, BrowserCommands> DispatcherForActiveViewController() { @@ -125,10 +135,15 @@ if (bvc) return bvc.dispatcher; if ([vc conformsToProtocol:@protocol(TabSwitcher)]) { + // In stack_view and the iPad tab switcher, the view controller has a + // dispatcher. id<TabSwitcher> tabSwitcher = static_cast<id<TabSwitcher>>(vc); return tabSwitcher.dispatcher; } - return nil; + // In tab grid, the TabSwitcher object is not in the view hierarchy so it must + // be gotten through the MainController. + return static_cast<id<ApplicationCommands, BrowserCommands>>( + GetMainController().tabSwitcher.dispatcher); } void RemoveAllInfoBars() {
diff --git a/ios/chrome/test/earl_grey/BUILD.gn b/ios/chrome/test/earl_grey/BUILD.gn index 969b4409..7fca231 100644 --- a/ios/chrome/test/earl_grey/BUILD.gn +++ b/ios/chrome/test/earl_grey/BUILD.gn
@@ -19,6 +19,7 @@ ":ios_chrome_reading_list_egtests", ":ios_chrome_settings_egtests", ":ios_chrome_smoke_egtests", + ":ios_chrome_tab_grid_egtests", ":ios_chrome_ui_egtests", ":ios_chrome_web_egtests", ] @@ -74,6 +75,14 @@ ] } +chrome_ios_eg_test("ios_chrome_tab_grid_egtests") { + deps = [ + ":test_support", + "//ios/chrome/browser/ui/tab_grid:eg_tests", + ] + hooks_target = "//ios/chrome/browser/ui/tab_grid:hooks" +} + chrome_ios_eg_test("ios_chrome_ui_egtests") { deps = [ "//ios/chrome/browser/ui:eg_tests",
diff --git a/ios/chrome/test/earl_grey/eg_tests_hook.mm b/ios/chrome/test/earl_grey/eg_tests_hook.mm index f1f1ada..05154c2 100644 --- a/ios/chrome/test/earl_grey/eg_tests_hook.mm +++ b/ios/chrome/test/earl_grey/eg_tests_hook.mm
@@ -38,6 +38,11 @@ return false; } +// TODO(crbug.com/818560) : Remove this hook. +bool ForceTabSwitcherTabGrid() { + return false; +} + void SetUpTestsIfPresent() { // No-op for Earl Grey. }
diff --git a/net/BUILD.gn b/net/BUILD.gn index db2c8a9..ee97a615 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -2191,6 +2191,7 @@ "websockets/websocket_handshake_request_info.h", "websockets/websocket_handshake_response_info.cc", "websockets/websocket_handshake_response_info.h", + "websockets/websocket_handshake_stream_base.cc", "websockets/websocket_handshake_stream_base.h", "websockets/websocket_handshake_stream_create_helper.cc", "websockets/websocket_handshake_stream_create_helper.h", @@ -2648,6 +2649,8 @@ "test/keychain_test_util_mac.h", "test/net_test_suite.cc", "test/net_test_suite.h", + "test/quic_simple_test_server.cc", + "test/quic_simple_test_server.h", "test/scoped_disable_exit_on_dfatal.cc", "test/scoped_disable_exit_on_dfatal.h", "test/tcp_socket_proxy.cc", @@ -2687,6 +2690,7 @@ ] deps = [ + ":simple_quic_tools", "//third_party/zlib", ]
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc index ce09270f..58a8b86 100644 --- a/net/cookies/cookie_monster.cc +++ b/net/cookies/cookie_monster.cc
@@ -97,8 +97,8 @@ namespace { -void MayeRunDeleteCallback(base::WeakPtr<net::CookieMonster> cookie_monster, - base::OnceClosure callback) { +void MaybeRunDeleteCallback(base::WeakPtr<net::CookieMonster> cookie_monster, + base::OnceClosure callback) { if (cookie_monster && callback) std::move(callback).Run(); } @@ -652,7 +652,7 @@ } FlushStore( - base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&MaybeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(), callback ? base::BindOnce(std::move(callback), num_deleted) : base::OnceClosure())); } @@ -680,7 +680,7 @@ } FlushStore( - base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&MaybeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(), callback ? base::BindOnce(std::move(callback), num_deleted) : base::OnceClosure())); } @@ -749,7 +749,7 @@ } } - FlushStore(base::BindOnce(&MayeRunDeleteCallback, + FlushStore(base::BindOnce(&MaybeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(), // No callback null check needed as BindOnce // is not being called and MaybeRunDeleteCallback @@ -772,7 +772,7 @@ } } FlushStore( - base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&MaybeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(), callback ? base::BindOnce(std::move(callback), result) : base::OnceClosure())); } @@ -794,7 +794,7 @@ } FlushStore( - base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(), + base::BindOnce(&MaybeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(), callback ? base::BindOnce(std::move(callback), num_deleted) : base::OnceClosure())); }
diff --git a/components/grpc_support/test/quic_test_server.cc b/net/test/quic_simple_test_server.cc similarity index 64% rename from components/grpc_support/test/quic_test_server.cc rename to net/test/quic_simple_test_server.cc index 2d286fd..0f11650 100644 --- a/components/grpc_support/test/quic_test_server.cc +++ b/net/test/quic_simple_test_server.cc
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/grpc_support/test/quic_test_server.h" +#include "net/test/quic_simple_test_server.h" #include <memory> #include <utility> @@ -12,6 +12,7 @@ #include "base/files/file_util.h" #include "base/message_loop/message_loop.h" #include "base/path_service.h" +#include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" @@ -24,12 +25,11 @@ #include "net/tools/quic/quic_http_response_cache.h" #include "net/tools/quic/quic_simple_server.h" -namespace grpc_support { +namespace { const char kTestServerDomain[] = "example.com"; // This must match the certificate used (quic-chain.pem and quic-leaf-cert.key). const char kTestServerHost[] = "test.example.com"; -const char kTestServerUrl[] = "https://test.example.com/hello.txt"; const char kStatusHeader[] = ":status"; @@ -43,7 +43,6 @@ const char kHelloTrailerName[] = "hello_trailer"; const char kHelloTrailerValue[] = "hello trailer value"; -const char kTestServerSimpleUrl[] = "https://test.example.com/simple.txt"; const char kSimplePath[] = "/simple.txt"; const char kSimpleBodyValue[] = "Simple Hello from QUIC Server"; const char kSimpleStatus[] = "200"; @@ -56,16 +55,92 @@ net::QuicSimpleServer* g_quic_server = nullptr; int g_quic_server_port = 0; +} // namespace + +namespace net { + +const std::string QuicSimpleTestServer::GetDomain() { + return kTestServerDomain; +} + +const std::string QuicSimpleTestServer::GetHost() { + return kTestServerHost; +} + +GURL QuicSimpleTestServer::GetFileURL(const std::string& file_path) { + return GURL("https://test.example.com:" + base::NumberToString(GetPort())) + .Resolve(file_path); +} + +GURL QuicSimpleTestServer::GetHelloURL() { + // Don't include |port| into Hello URL as it is mapped differently. + return GURL("https://test.example.com").Resolve(kHelloPath); +} + +const std::string QuicSimpleTestServer::GetStatusHeaderName() { + return kStatusHeader; +} + +// Hello Url returns response with HTTP/2 headers and trailers. +const std::string QuicSimpleTestServer::GetHelloPath() { + return kHelloPath; +} + +const std::string QuicSimpleTestServer::GetHelloBodyValue() { + return kHelloBodyValue; +} +const std::string QuicSimpleTestServer::GetHelloStatus() { + return kHelloStatus; +} + +const std::string QuicSimpleTestServer::GetHelloHeaderName() { + return kHelloHeaderName; +} + +const std::string QuicSimpleTestServer::GetHelloHeaderValue() { + return kHelloHeaderValue; +} + +const std::string QuicSimpleTestServer::GetHelloTrailerName() { + return kHelloTrailerName; +} + +const std::string QuicSimpleTestServer::GetHelloTrailerValue() { + return kHelloTrailerValue; +} + +// Simple Url returns response without HTTP/2 trailers. +GURL QuicSimpleTestServer::GetSimpleURL() { + // Don't include |port| into Simple URL as it is mapped differently. + return GURL("https://test.example.com").Resolve(kSimplePath); +} + +const std::string QuicSimpleTestServer::GetSimpleBodyValue() { + return kSimpleBodyValue; +} + +const std::string QuicSimpleTestServer::GetSimpleStatus() { + return kSimpleStatus; +} + +const std::string QuicSimpleTestServer::GetSimpleHeaderName() { + return kSimpleHeaderName; +} + +const std::string QuicSimpleTestServer::GetSimpleHeaderValue() { + return kSimpleHeaderValue; +} + void SetupQuicHttpResponseCache() { - net::SpdyHeaderBlock headers; + SpdyHeaderBlock headers; headers[kHelloHeaderName] = kHelloHeaderValue; - headers[kStatusHeader] = kHelloStatus; - net::SpdyHeaderBlock trailers; + headers[kStatusHeader] = kHelloStatus; + SpdyHeaderBlock trailers; trailers[kHelloTrailerName] = kHelloTrailerValue; - g_quic_response_cache = new net::QuicHttpResponseCache(); + g_quic_response_cache = new QuicHttpResponseCache(); g_quic_response_cache->AddResponse(base::StringPrintf("%s", kTestServerHost), - kHelloPath, std::move(headers), - kHelloBodyValue, std::move(trailers)); + kHelloPath, std::move(headers), + kHelloBodyValue, std::move(trailers)); headers[kSimpleHeaderName] = kSimpleHeaderValue; headers[kStatusHeader] = kSimpleStatus; g_quic_response_cache->AddResponse(base::StringPrintf("%s", kTestServerHost), @@ -78,25 +153,22 @@ DCHECK(g_quic_server_thread->task_runner()->BelongsToCurrentThread()); DCHECK(!g_quic_server); - net::QuicConfig config; + QuicConfig config; // Set up server certs. base::FilePath directory; directory = test_files_root; - std::unique_ptr<net::ProofSourceChromium> proof_source( - new net::ProofSourceChromium()); + std::unique_ptr<ProofSourceChromium> proof_source(new ProofSourceChromium()); CHECK(proof_source->Initialize(directory.AppendASCII("quic-chain.pem"), directory.AppendASCII("quic-leaf-cert.key"), base::FilePath())); SetupQuicHttpResponseCache(); - g_quic_server = new net::QuicSimpleServer( - std::move(proof_source), config, - net::QuicCryptoServerConfig::ConfigOptions(), net::AllSupportedVersions(), - g_quic_response_cache); + g_quic_server = new QuicSimpleServer( + std::move(proof_source), config, QuicCryptoServerConfig::ConfigOptions(), + AllSupportedVersions(), g_quic_response_cache); // Start listening on an unbound port. - int rv = g_quic_server->Listen( - net::IPEndPoint(net::IPAddress::IPv4AllZeros(), 0)); + int rv = g_quic_server->Listen(IPEndPoint(IPAddress::IPv4AllZeros(), 0)); CHECK_GE(rv, 0) << "Quic server fails to start"; g_quic_server_port = g_quic_server->server_address().port(); server_started_event->Signal(); @@ -119,7 +191,7 @@ dispatcher_stopped_event->Signal(); } -bool StartQuicTestServer() { +bool QuicSimpleTestServer::Start() { DVLOG(3) << g_quic_server_thread; DCHECK(!g_quic_server_thread); g_quic_server_thread = new base::Thread("quic server thread"); @@ -127,7 +199,7 @@ thread_options.message_loop_type = base::MessageLoop::TYPE_IO; bool started = g_quic_server_thread->StartWithOptions(thread_options); DCHECK(started); - base::FilePath test_files_root = net::GetTestCertsDirectory(); + base::FilePath test_files_root = GetTestCertsDirectory(); base::WaitableEvent server_started_event( base::WaitableEvent::ResetPolicy::MANUAL, @@ -140,7 +212,7 @@ } // Shut down the server dispatcher, and the stream should error out. -void ShutdownQuicTestServerDispatcher() { +void QuicSimpleTestServer::ShutdownDispatcherForTesting() { if (!g_quic_server) return; DCHECK(!g_quic_server_thread->task_runner()->BelongsToCurrentThread()); @@ -153,7 +225,7 @@ dispatcher_stopped_event.Wait(); } -void ShutdownQuicTestServer() { +void QuicSimpleTestServer::Shutdown() { if (!g_quic_server) return; DCHECK(!g_quic_server_thread->task_runner()->BelongsToCurrentThread()); @@ -168,8 +240,8 @@ g_quic_server_thread = nullptr; } -int GetQuicTestServerPort() { +int QuicSimpleTestServer::GetPort() { return g_quic_server_port; } -} // namespace grpc_support +} // namespace net
diff --git a/net/test/quic_simple_test_server.h b/net/test/quic_simple_test_server.h new file mode 100644 index 0000000..03ed5b7 --- /dev/null +++ b/net/test/quic_simple_test_server.h
@@ -0,0 +1,60 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_TEST_QUIC_SIMPLE_TEST_SERVER_H_ +#define NET_TEST_QUIC_SIMPLE_TEST_SERVER_H_ + +#include <string> + +#include "url/gurl.h" + +namespace net { + +class QuicSimpleTestServer { + public: + static bool Start(); + static void Shutdown(); + + // Shuts down the server dispatcher, which results in sending ConnectionClose + // frames to all connected clients. + static void ShutdownDispatcherForTesting(); + + // Returns example.com + static const std::string GetDomain(); + // Returns test.example.com + static const std::string GetHost(); + // Returns port number of the server. + static int GetPort(); + // Returns test.example.com:port + static const std::string GetHostPort(); + + // Returns URL with host, port and file path, for example + // https://test.example.com:12345/{file_path} + static GURL GetFileURL(const std::string& file_path); + + static const std::string GetStatusHeaderName(); + + // Server returns response with HTTP/2 headers and trailers. Does not include + // |port| as it is resolved differently: https://test.example.com/hello.txt + static GURL GetHelloURL(); + static const std::string GetHelloPath(); + static const std::string GetHelloBodyValue(); + static const std::string GetHelloStatus(); + static const std::string GetHelloHeaderName(); + static const std::string GetHelloHeaderValue(); + static const std::string GetHelloTrailerName(); + static const std::string GetHelloTrailerValue(); + + // Server returns response without HTTP/2 trailers. + // https://test.example.com/simple.txt + static GURL GetSimpleURL(); + static const std::string GetSimpleBodyValue(); + static const std::string GetSimpleStatus(); + static const std::string GetSimpleHeaderName(); + static const std::string GetSimpleHeaderValue(); +}; + +} // namespace net + +#endif // NET_TEST_QUIC_SIMPLE_TEST_SERVER_H_
diff --git a/net/websockets/websocket_basic_handshake_stream.cc b/net/websockets/websocket_basic_handshake_stream.cc index 189b72a0..f8a3565 100644 --- a/net/websockets/websocket_basic_handshake_stream.cc +++ b/net/websockets/websocket_basic_handshake_stream.cc
@@ -9,7 +9,6 @@ #include <iterator> #include <set> #include <string> -#include <unordered_set> #include <utility> #include <vector> @@ -42,7 +41,6 @@ #include "net/websockets/websocket_deflate_predictor_impl.h" #include "net/websockets/websocket_deflate_stream.h" #include "net/websockets/websocket_deflater.h" -#include "net/websockets/websocket_extension_parser.h" #include "net/websockets/websocket_handshake_challenge.h" #include "net/websockets/websocket_handshake_constants.h" #include "net/websockets/websocket_handshake_request_info.h" @@ -57,13 +55,6 @@ } // namespace -// TODO(ricea): If more extensions are added, replace this with a more general -// mechanism. -struct WebSocketExtensionParams { - bool deflate_enabled = false; - WebSocketDeflateParameters deflate_parameters; -}; - namespace { enum GetHeaderResult { @@ -76,13 +67,6 @@ return std::string("'") + header_name + "' header is missing"; } -std::string MultipleHeaderValuesMessage(const std::string& header_name) { - return - std::string("'") + - header_name + - "' header must not appear more than once in a response"; -} - std::string GenerateHandshakeChallenge() { std::string raw_challenge(websockets::kRawChallengeLength, '\0'); crypto::RandBytes(base::string_as_array(&raw_challenge), @@ -92,14 +76,6 @@ return encoded_challenge; } -void AddVectorHeaderIfNonEmpty(const char* name, - const std::vector<std::string>& value, - HttpRequestHeaders* headers) { - if (value.empty()) - return; - headers->SetHeader(name, base::JoinString(value, ", ")); -} - GetHeaderResult GetSingleHeaderValue(const HttpResponseHeaders* headers, const base::StringPiece& name, std::string* value) { @@ -122,7 +98,8 @@ return false; } if (result == GET_HEADER_MULTIPLE) { - *failure_message = MultipleHeaderValuesMessage(header_name); + *failure_message = + WebSocketHandshakeStreamBase::MultipleHeaderValuesMessage(header_name); return false; } DCHECK_EQ(result, GET_HEADER_OK); @@ -182,111 +159,6 @@ return true; } -bool ValidateSubProtocol( - const HttpResponseHeaders* headers, - const std::vector<std::string>& requested_sub_protocols, - std::string* sub_protocol, - std::string* failure_message) { - size_t iter = 0; - std::string value; - std::unordered_set<std::string> requested_set(requested_sub_protocols.begin(), - requested_sub_protocols.end()); - int count = 0; - bool has_multiple_protocols = false; - bool has_invalid_protocol = false; - - while (!has_invalid_protocol || !has_multiple_protocols) { - std::string temp_value; - if (!headers->EnumerateHeader(&iter, websockets::kSecWebSocketProtocol, - &temp_value)) - break; - value = temp_value; - if (requested_set.count(value) == 0) - has_invalid_protocol = true; - if (++count > 1) - has_multiple_protocols = true; - } - - if (has_multiple_protocols) { - *failure_message = - MultipleHeaderValuesMessage(websockets::kSecWebSocketProtocol); - return false; - } else if (count > 0 && requested_sub_protocols.size() == 0) { - *failure_message = - std::string("Response must not include 'Sec-WebSocket-Protocol' " - "header if not present in request: ") - + value; - return false; - } else if (has_invalid_protocol) { - *failure_message = - "'Sec-WebSocket-Protocol' header value '" + - value + - "' in response does not match any of sent values"; - return false; - } else if (requested_sub_protocols.size() > 0 && count == 0) { - *failure_message = - "Sent non-empty 'Sec-WebSocket-Protocol' header " - "but no response was received"; - return false; - } - *sub_protocol = value; - return true; -} - -bool ValidateExtensions(const HttpResponseHeaders* headers, - std::string* accepted_extensions_descriptor, - std::string* failure_message, - WebSocketExtensionParams* params) { - size_t iter = 0; - std::string header_value; - std::vector<std::string> header_values; - // TODO(ricea): If adding support for additional extensions, generalise this - // code. - bool seen_permessage_deflate = false; - while (headers->EnumerateHeader(&iter, websockets::kSecWebSocketExtensions, - &header_value)) { - WebSocketExtensionParser parser; - if (!parser.Parse(header_value)) { - // TODO(yhirano) Set appropriate failure message. - *failure_message = - "'Sec-WebSocket-Extensions' header value is " - "rejected by the parser: " + - header_value; - return false; - } - - const std::vector<WebSocketExtension>& extensions = parser.extensions(); - for (const auto& extension : extensions) { - if (extension.name() == "permessage-deflate") { - if (seen_permessage_deflate) { - *failure_message = "Received duplicate permessage-deflate response"; - return false; - } - seen_permessage_deflate = true; - auto& deflate_parameters = params->deflate_parameters; - if (!deflate_parameters.Initialize(extension, failure_message) || - !deflate_parameters.IsValidAsResponse(failure_message)) { - *failure_message = "Error in permessage-deflate: " + *failure_message; - return false; - } - // Note that we don't have to check the request-response compatibility - // here because we send a request compatible with any valid responses. - // TODO(yhirano): Place a DCHECK here. - - header_values.push_back(header_value); - } else { - *failure_message = "Found an unsupported extension '" + - extension.name() + - "' in 'Sec-WebSocket-Extensions' header"; - return false; - } - } - } - *accepted_extensions_descriptor = base::JoinString(header_values, ", "); - params->deflate_enabled = seen_permessage_deflate; - return true; -} - } // namespace WebSocketBasicHandshakeStream::WebSocketBasicHandshakeStream(
diff --git a/net/websockets/websocket_handshake_constants.cc b/net/websockets/websocket_handshake_constants.cc index ce9bb62..4bd4bd1 100644 --- a/net/websockets/websocket_handshake_constants.cc +++ b/net/websockets/websocket_handshake_constants.cc
@@ -22,8 +22,6 @@ const char kUpgrade[] = "Upgrade"; const char kWebSocketGuid[] = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; -const char kSecWebSocketProtocolLowercase[] = "sec-websocket-protocol"; -const char kSecWebSocketExtensionsLowercase[] = "sec-websocket-extensions"; const char kWebSocketLowercase[] = "websocket"; } // namespace websockets
diff --git a/net/websockets/websocket_handshake_constants.h b/net/websockets/websocket_handshake_constants.h index 8fb5fc5..3794d3ff 100644 --- a/net/websockets/websocket_handshake_constants.h +++ b/net/websockets/websocket_handshake_constants.h
@@ -56,14 +56,6 @@ // RFC6455. extern const char NET_EXPORT kWebSocketGuid[]; -// Some parts of the code require lowercase versions of the header names in -// order to do case-insensitive comparisons, or because of HTTP/2. -// "sec-websocket-protocol" -extern const char kSecWebSocketProtocolLowercase[]; - -// "sec-websocket-extensions" -extern const char kSecWebSocketExtensionsLowercase[]; - // "websocket", as used in the "Upgrade:" header. This is always lowercase // (except in obsolete versions of the protocol). extern const char kWebSocketLowercase[];
diff --git a/net/websockets/websocket_handshake_stream_base.cc b/net/websockets/websocket_handshake_stream_base.cc new file mode 100644 index 0000000..a90a896a --- /dev/null +++ b/net/websockets/websocket_handshake_stream_base.cc
@@ -0,0 +1,141 @@ +// 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 "net/websockets/websocket_handshake_stream_base.h" + +#include <unordered_set> + +#include "base/strings/string_util.h" +#include "net/http/http_request_headers.h" +#include "net/http/http_response_headers.h" +#include "net/websockets/websocket_extension.h" +#include "net/websockets/websocket_extension_parser.h" +#include "net/websockets/websocket_handshake_constants.h" + +namespace net { + +// static +std::string WebSocketHandshakeStreamBase::MultipleHeaderValuesMessage( + const std::string& header_name) { + return std::string("'") + header_name + + "' header must not appear more than once in a response"; +} + +// static +void WebSocketHandshakeStreamBase::AddVectorHeaderIfNonEmpty( + const char* name, + const std::vector<std::string>& value, + HttpRequestHeaders* headers) { + if (value.empty()) + return; + headers->SetHeader(name, base::JoinString(value, ", ")); +} + +// static +bool WebSocketHandshakeStreamBase::ValidateSubProtocol( + const HttpResponseHeaders* headers, + const std::vector<std::string>& requested_sub_protocols, + std::string* sub_protocol, + std::string* failure_message) { + size_t iter = 0; + std::string value; + std::unordered_set<std::string> requested_set(requested_sub_protocols.begin(), + requested_sub_protocols.end()); + int count = 0; + bool has_multiple_protocols = false; + bool has_invalid_protocol = false; + + while (!has_invalid_protocol || !has_multiple_protocols) { + std::string temp_value; + if (!headers->EnumerateHeader(&iter, websockets::kSecWebSocketProtocol, + &temp_value)) + break; + value = temp_value; + if (requested_set.count(value) == 0) + has_invalid_protocol = true; + if (++count > 1) + has_multiple_protocols = true; + } + + if (has_multiple_protocols) { + *failure_message = + MultipleHeaderValuesMessage(websockets::kSecWebSocketProtocol); + return false; + } else if (count > 0 && requested_sub_protocols.size() == 0) { + *failure_message = std::string( + "Response must not include 'Sec-WebSocket-Protocol' " + "header if not present in request: ") + + value; + return false; + } else if (has_invalid_protocol) { + *failure_message = "'Sec-WebSocket-Protocol' header value '" + value + + "' in response does not match any of sent values"; + return false; + } else if (requested_sub_protocols.size() > 0 && count == 0) { + *failure_message = + "Sent non-empty 'Sec-WebSocket-Protocol' header " + "but no response was received"; + return false; + } + *sub_protocol = value; + return true; +} + +// static +bool WebSocketHandshakeStreamBase::ValidateExtensions( + const HttpResponseHeaders* headers, + std::string* accepted_extensions_descriptor, + std::string* failure_message, + WebSocketExtensionParams* params) { + size_t iter = 0; + std::string header_value; + std::vector<std::string> header_values; + // TODO(ricea): If adding support for additional extensions, generalise this + // code. + bool seen_permessage_deflate = false; + while (headers->EnumerateHeader(&iter, websockets::kSecWebSocketExtensions, + &header_value)) { + WebSocketExtensionParser parser; + if (!parser.Parse(header_value)) { + // TODO(yhirano) Set appropriate failure message. + *failure_message = + "'Sec-WebSocket-Extensions' header value is " + "rejected by the parser: " + + header_value; + return false; + } + + const std::vector<WebSocketExtension>& extensions = parser.extensions(); + for (const auto& extension : extensions) { + if (extension.name() == "permessage-deflate") { + if (seen_permessage_deflate) { + *failure_message = "Received duplicate permessage-deflate response"; + return false; + } + seen_permessage_deflate = true; + auto& deflate_parameters = params->deflate_parameters; + if (!deflate_parameters.Initialize(extension, failure_message) || + !deflate_parameters.IsValidAsResponse(failure_message)) { + *failure_message = "Error in permessage-deflate: " + *failure_message; + return false; + } + // Note that we don't have to check the request-response compatibility + // here because we send a request compatible with any valid responses. + // TODO(yhirano): Place a DCHECK here. + + header_values.push_back(header_value); + } else { + *failure_message = "Found an unsupported extension '" + + extension.name() + + "' in 'Sec-WebSocket-Extensions' header"; + return false; + } + } + } + *accepted_extensions_descriptor = base::JoinString(header_values, ", "); + params->deflate_enabled = seen_permessage_deflate; + return true; +} + +} // namespace net
diff --git a/net/websockets/websocket_handshake_stream_base.h b/net/websockets/websocket_handshake_stream_base.h index feb12a38..d8abbc4 100644 --- a/net/websockets/websocket_handshake_stream_base.h +++ b/net/websockets/websocket_handshake_stream_base.h
@@ -11,6 +11,7 @@ #include <memory> #include <string> +#include <vector> #include "base/macros.h" #include "base/memory/weak_ptr.h" @@ -18,12 +19,15 @@ #include "net/base/net_export.h" #include "net/http/http_stream.h" #include "net/url_request/websocket_handshake_userdata_key.h" +#include "net/websockets/websocket_deflate_parameters.h" #include "net/websockets/websocket_stream.h" namespace net { class ClientSocketHandle; class SpdySession; +class HttpRequestHeaders; +class HttpResponseHeaders; // WebSocketHandshakeStreamBase is the base class of // WebSocketBasicHandshakeStream. net/http code uses this interface to handle @@ -31,6 +35,9 @@ // HttpStreamBase. class NET_EXPORT WebSocketHandshakeStreamBase : public HttpStream { public: + WebSocketHandshakeStreamBase() = default; + ~WebSocketHandshakeStreamBase() override = default; + // An object that stores data needed for the creation of a // WebSocketBasicHandshakeStream object. A new CreateHelper is used for each // WebSocket connection. @@ -58,10 +65,6 @@ base::WeakPtr<SpdySession> session) = 0; }; - // This has to have an inline implementation so that the net/url_request/ - // tests do not fail on iOS. - ~WebSocketHandshakeStreamBase() override {} - // After the handshake has completed, this method creates a WebSocketStream // (of the appropriate type) from the WebSocketHandshakeStreamBase object. // The WebSocketHandshakeStreamBase object is unusable after Upgrade() has @@ -70,9 +73,31 @@ void SetRequestHeadersCallback(RequestHeadersCallback callback) override {} + static std::string MultipleHeaderValuesMessage( + const std::string& header_name); + protected: - // As with the destructor, this must be inline. - WebSocketHandshakeStreamBase() {} + // TODO(ricea): If more extensions are added, replace this with a more general + // mechanism. + struct WebSocketExtensionParams { + bool deflate_enabled = false; + WebSocketDeflateParameters deflate_parameters; + }; + + static void AddVectorHeaderIfNonEmpty(const char* name, + const std::vector<std::string>& value, + HttpRequestHeaders* headers); + + static bool ValidateSubProtocol( + const HttpResponseHeaders* headers, + const std::vector<std::string>& requested_sub_protocols, + std::string* sub_protocol, + std::string* failure_message); + + static bool ValidateExtensions(const HttpResponseHeaders* headers, + std::string* accepted_extensions_descriptor, + std::string* failure_message, + WebSocketExtensionParams* params); private: DISALLOW_COPY_AND_ASSIGN(WebSocketHandshakeStreamBase);
diff --git a/net/websockets/websocket_http2_handshake_stream.cc b/net/websockets/websocket_http2_handshake_stream.cc index 987f38b..beb332e8 100644 --- a/net/websockets/websocket_http2_handshake_stream.cc +++ b/net/websockets/websocket_http2_handshake_stream.cc
@@ -5,13 +5,11 @@ #include "net/websockets/websocket_http2_handshake_stream.h" #include <cstddef> -#include <unordered_set> #include <utility> #include "base/bind.h" #include "base/logging.h" #include "base/metrics/histogram_macros.h" -#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/time/time.h" #include "net/http/http_request_headers.h" @@ -26,141 +24,17 @@ #include "net/websockets/websocket_deflate_predictor_impl.h" #include "net/websockets/websocket_deflate_stream.h" #include "net/websockets/websocket_deflater.h" -#include "net/websockets/websocket_extension_parser.h" #include "net/websockets/websocket_handshake_constants.h" #include "net/websockets/websocket_handshake_request_info.h" namespace net { -// TODO(ricea): If more extensions are added, replace this with a more general -// mechanism. -struct WebSocketExtensionParams { - bool deflate_enabled = false; - WebSocketDeflateParameters deflate_parameters; -}; - namespace { -void AddVectorHeaderIfNonEmpty(const char* name, - const std::vector<std::string>& value, - HttpRequestHeaders* headers) { - if (value.empty()) - return; - headers->SetHeader(name, base::JoinString(value, ", ")); -} - -std::string MultipleHeaderValuesMessage(const std::string& header_name) { - return std::string("'") + header_name + - "' header must not appear more than once in a response"; -} - bool ValidateStatus(const HttpResponseHeaders* headers) { return headers->GetStatusLine() == "HTTP/1.1 200"; } -bool ValidateSubProtocol( - const HttpResponseHeaders* headers, - const std::vector<std::string>& requested_sub_protocols, - std::string* sub_protocol, - std::string* failure_message) { - size_t iter = 0; - std::string value; - std::unordered_set<std::string> requested_set(requested_sub_protocols.begin(), - requested_sub_protocols.end()); - int count = 0; - bool has_multiple_protocols = false; - bool has_invalid_protocol = false; - - while (!has_invalid_protocol || !has_multiple_protocols) { - std::string temp_value; - if (!headers->EnumerateHeader( - &iter, websockets::kSecWebSocketProtocolLowercase, &temp_value)) - break; - value = temp_value; - if (requested_set.count(value) == 0) - has_invalid_protocol = true; - if (++count > 1) - has_multiple_protocols = true; - } - - if (has_multiple_protocols) { - *failure_message = - MultipleHeaderValuesMessage(websockets::kSecWebSocketProtocolLowercase); - return false; - } else if (count > 0 && requested_sub_protocols.size() == 0) { - *failure_message = std::string( - "Response must not include 'Sec-WebSocket-Protocol' " - "header if not present in request: ") + - value; - return false; - } else if (has_invalid_protocol) { - *failure_message = "'Sec-WebSocket-Protocol' header value '" + value + - "' in response does not match any of sent values"; - return false; - } else if (requested_sub_protocols.size() > 0 && count == 0) { - *failure_message = - "Sent non-empty 'Sec-WebSocket-Protocol' header " - "but no response was received"; - return false; - } - *sub_protocol = value; - return true; -} - -bool ValidateExtensions(const HttpResponseHeaders* headers, - std::string* accepted_extensions_descriptor, - std::string* failure_message, - WebSocketExtensionParams* params) { - size_t iter = 0; - std::string header_value; - std::vector<std::string> header_values; - // TODO(ricea): If adding support for additional extensions, generalise this - // code. - bool seen_permessage_deflate = false; - while (headers->EnumerateHeader( - &iter, websockets::kSecWebSocketExtensionsLowercase, &header_value)) { - WebSocketExtensionParser parser; - if (!parser.Parse(header_value)) { - // TODO(yhirano) Set appropriate failure message. - *failure_message = - "'Sec-WebSocket-Extensions' header value is " - "rejected by the parser: " + - header_value; - return false; - } - - const std::vector<WebSocketExtension>& extensions = parser.extensions(); - for (const auto& extension : extensions) { - if (extension.name() == "permessage-deflate") { - if (seen_permessage_deflate) { - *failure_message = "Received duplicate permessage-deflate response"; - return false; - } - seen_permessage_deflate = true; - auto& deflate_parameters = params->deflate_parameters; - if (!deflate_parameters.Initialize(extension, failure_message) || - !deflate_parameters.IsValidAsResponse(failure_message)) { - *failure_message = "Error in permessage-deflate: " + *failure_message; - return false; - } - // Note that we don't have to check the request-response compatibility - // here because we send a request compatible with any valid responses. - // TODO(yhirano): Place a DCHECK here. - - header_values.push_back(header_value); - } else { - *failure_message = "Found an unsupported extension '" + - extension.name() + - "' in 'Sec-WebSocket-Extensions' header"; - return false; - } - } - } - *accepted_extensions_descriptor = base::JoinString(header_values, ", "); - params->deflate_enabled = seen_permessage_deflate; - return true; -} - } // namespace WebSocketHttp2HandshakeStream::WebSocketHttp2HandshakeStream(
diff --git a/net/websockets/websocket_stream_test.cc b/net/websockets/websocket_stream_test.cc index 05e76eec..65139b14 100644 --- a/net/websockets/websocket_stream_test.cc +++ b/net/websockets/websocket_stream_test.cc
@@ -90,7 +90,10 @@ class WebSocketStreamCreateTest : public TestWithParam<HandshakeStreamType>, public WebSocketStreamCreateTestBase { protected: - WebSocketStreamCreateTest() : stream_type_(GetParam()), sequence_number_(0) {} + WebSocketStreamCreateTest() + : stream_type_(GetParam()), + http2_response_status_("200"), + sequence_number_(0) {} ~WebSocketStreamCreateTest() override { // Permit any endpoint locks to be released. stream_request_.reset(); @@ -108,6 +111,18 @@ url_request_context_host_.AddSSLSocketDataProvider(std::move(ssl_data)); } + void SetTimer(std::unique_ptr<base::Timer> timer) { + timer_ = std::move(timer); + } + + void SetAdditionalResponseData(std::string additional_data) { + additional_data_ = std::move(additional_data); + } + + void SetHttp2ResponseStatus(const char* const http2_response_status) { + http2_response_status_ = http2_response_status; + } + // Set up mock data and start websockets request, either for WebSocket // upgraded from an HTTP/1 connection, or for a WebSocket request over HTTP/2. void CreateAndConnectStandard( @@ -119,9 +134,7 @@ const GURL& site_for_cookies, const WebSocketExtraHeaders& send_additional_request_headers, const WebSocketExtraHeaders& extra_request_headers, - const WebSocketExtraHeaders& extra_response_headers, - std::unique_ptr<base::Timer> timer = {}, - const std::string& additional_data = {}) { + const WebSocketExtraHeaders& extra_response_headers) { if (stream_type_ == BASIC_HANDSHAKE_STREAM) { url_request_context_host_.SetExpectations( WebSocketStandardRequest( @@ -130,11 +143,11 @@ WebSocketExtraHeadersToString(extra_request_headers)), WebSocketStandardResponse( WebSocketExtraHeadersToString(extra_response_headers)) + - additional_data); + additional_data_); CreateAndConnectStream( GURL(socket_url), sub_protocols, origin, site_for_cookies, WebSocketExtraHeadersToString(send_additional_request_headers), - std::move(timer)); + std::move(timer_)); return; } @@ -221,15 +234,15 @@ // Save a pointer to the original header value provided by the caller. extra_response_headers_vector.push_back(extra_header.second.c_str()); } - frames_.push_back(spdy_util_.ConstructSpdyGetReply( - extra_response_headers_vector.data(), + frames_.push_back(spdy_util_.ConstructSpdyReplyError( + http2_response_status_, extra_response_headers_vector.data(), extra_response_headers_vector.size() / 2, 3)); AddRead(&frames_.back()); // WebSocket data received. - if (!additional_data.empty()) { + if (!additional_data_.empty()) { frames_.push_back( - spdy_util_.ConstructSpdyDataFrame(3, additional_data, true)); + spdy_util_.ConstructSpdyDataFrame(3, additional_data_, true)); AddRead(&frames_.back()); } @@ -261,7 +274,7 @@ CreateAndConnectStream( GURL(socket_url), sub_protocols, origin, site_for_cookies, WebSocketExtraHeadersToString(send_additional_request_headers), - std::move(timer)); + std::move(timer_)); } // Like CreateAndConnectStandard(), but allow for arbitrary response body. @@ -317,14 +330,13 @@ const url::Origin& origin, const GURL& site_for_cookies, const std::string& send_additional_request_headers, - std::unique_ptr<SequencedSocketData> socket_data, - std::unique_ptr<base::Timer> timer = std::unique_ptr<base::Timer>()) { + std::unique_ptr<SequencedSocketData> socket_data) { ASSERT_EQ(BASIC_HANDSHAKE_STREAM, stream_type_); url_request_context_host_.AddRawExpectations(std::move(socket_data)); CreateAndConnectStream(GURL(socket_url), sub_protocols, origin, site_for_cookies, send_additional_request_headers, - std::move(timer)); + std::move(timer_)); } private: @@ -342,6 +354,9 @@ const HandshakeStreamType stream_type_; private: + std::unique_ptr<base::Timer> timer_; + std::string additional_data_; + const char* http2_response_status_; SpdyTestUtil spdy_util_; NetLogWithSource log_; @@ -535,7 +550,7 @@ INSTANTIATE_TEST_CASE_P(, WebSocketStreamCreateUMATest, - Values(BASIC_HANDSHAKE_STREAM)); + Values(BASIC_HANDSHAKE_STREAM, HTTP2_HANDSHAKE_STREAM)); // Confirm that the basic case works as expected. TEST_P(WebSocketMultiProtocolStreamCreateTest, SimpleSuccess) { @@ -728,20 +743,11 @@ WaitUntilConnectDone(); EXPECT_FALSE(stream_); EXPECT_TRUE(has_failed()); - if (stream_type_ == BASIC_HANDSHAKE_STREAM) { - EXPECT_EQ( - "Error during WebSocket handshake: " - "'Sec-WebSocket-Protocol' header must not appear " - "more than once in a response", - failure_message()); - } else { - DCHECK_EQ(HTTP2_HANDSHAKE_STREAM, stream_type_); - EXPECT_EQ( - "Error during WebSocket handshake: " - "'sec-websocket-protocol' header must not appear " - "more than once in a response", - failure_message()); - } + EXPECT_EQ( + "Error during WebSocket handshake: " + "'Sec-WebSocket-Protocol' header must not appear " + "more than once in a response", + failure_message()); } // Unmatched sub-protocol should be rejected. @@ -786,15 +792,14 @@ // permessage-deflate enabled. TEST_P(WebSocketStreamCreateExtensionTest, PerMessageDeflateInflates) { AddSSLData(); + SetAdditionalResponseData(std::string( + "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) + "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed + 9)); CreateAndConnectStandard( "wss://www.example.org/testing_path", "www.example.org", "/testing_path", NoSubProtocols(), Origin(), Url(), {}, {}, - {{"Sec-WebSocket-Extensions", "permessage-deflate"}}, - std::unique_ptr<base::Timer>(), - std::string( - "\xc1\x07" // WebSocket header (FIN + RSV1, Text payload 7 bytes) - "\xf2\x48\xcd\xc9\xc9\x07\x00", // "Hello" DEFLATE compressed - 9)); + {{"Sec-WebSocket-Extensions", "permessage-deflate"}}); WaitUntilConnectDone(); ASSERT_TRUE(stream_); @@ -895,19 +900,28 @@ // Redirects are not followed (according to the WHATWG WebSocket API, which // overrides RFC6455 for browser applications). -TEST_P(WebSocketStreamCreateTest, RedirectsRejected) { - static const char kRedirectResponse[] = - "HTTP/1.1 302 Moved Temporarily\r\n" - "Content-Type: text/html\r\n" - "Content-Length: 34\r\n" - "Connection: keep-alive\r\n" - "Location: wss://www.example.org/other\r\n" - "\r\n" - "<title>Moved</title><h1>Moved</h1>"; - CreateAndConnectCustomResponse("ws://www.example.org/", "www.example.org", - "/", NoSubProtocols(), Origin(), Url(), {}, {}, - kRedirectResponse); +TEST_P(WebSocketMultiProtocolStreamCreateTest, RedirectsRejected) { + AddSSLData(); + if (stream_type_ == BASIC_HANDSHAKE_STREAM) { + static const char kRedirectResponse[] = + "HTTP/1.1 302 Moved Temporarily\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 34\r\n" + "Connection: keep-alive\r\n" + "Location: wss://www.example.org/other\r\n" + "\r\n" + "<title>Moved</title><h1>Moved</h1>"; + CreateAndConnectCustomResponse("wss://www.example.org/", "www.example.org", + "/", NoSubProtocols(), Origin(), Url(), {}, + {}, kRedirectResponse); + } else { + DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM); + SetHttp2ResponseStatus("302"); + CreateAndConnectStandard("wss://www.example.org/", "www.example.org", "/", + NoSubProtocols(), Origin(), Url(), {}, {}, {}); + } WaitUntilConnectDone(); + EXPECT_TRUE(has_failed()); EXPECT_EQ("Error during WebSocket handshake: Unexpected response code: 302", failure_message()); @@ -1113,9 +1127,9 @@ socket_data->set_connect_data(MockConnect(SYNCHRONOUS, ERR_IO_PENDING)); auto timer = std::make_unique<MockWeakTimer>(false, false); base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); + SetTimer(std::move(timer)); CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), - Origin(), Url(), "", std::move(socket_data), - std::move(timer)); + Origin(), Url(), "", std::move(socket_data)); EXPECT_FALSE(has_failed()); ASSERT_TRUE(weak_timer.get()); EXPECT_TRUE(weak_timer->IsRunning()); @@ -1134,9 +1148,9 @@ auto timer = std::make_unique<MockWeakTimer>(false, false); base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); + SetTimer(std::move(timer)); CreateAndConnectStandard("ws://www.example.org/", "www.example.org", "/", - NoSubProtocols(), Origin(), Url(), {}, {}, {}, - std::move(timer)); + NoSubProtocols(), Origin(), Url(), {}, {}, {}); ASSERT_TRUE(weak_timer); EXPECT_TRUE(weak_timer->IsRunning()); @@ -1154,9 +1168,9 @@ MockConnect(SYNCHRONOUS, ERR_CONNECTION_REFUSED)); auto timer = std::make_unique<MockWeakTimer>(false, false); base::WeakPtr<MockWeakTimer> weak_timer = timer->AsWeakPtr(); + SetTimer(std::move(timer)); CreateAndConnectRawExpectations("ws://www.example.org/", NoSubProtocols(), - Origin(), Url(), "", std::move(socket_data), - std::move(timer)); + Origin(), Url(), "", std::move(socket_data)); ASSERT_TRUE(weak_timer.get()); EXPECT_TRUE(weak_timer->IsRunning()); @@ -1363,7 +1377,8 @@ TEST_P(WebSocketStreamCreateUMATest, Incomplete) { base::HistogramTester histogram_tester; - CreateAndConnectStandard("ws://www.example.org/", "www.example.org", "/", + AddSSLData(); + CreateAndConnectStandard("wss://www.example.org/", "www.example.org", "/", NoSubProtocols(), Origin(), Url(), {}, {}, {}); stream_request_.reset(); @@ -1377,7 +1392,8 @@ TEST_P(WebSocketStreamCreateUMATest, Connected) { base::HistogramTester histogram_tester; - CreateAndConnectStandard("ws://www.example.org/", "www.example.org", "/", + AddSSLData(); + CreateAndConnectStandard("wss://www.example.org/", "www.example.org", "/", NoSubProtocols(), Origin(), Url(), {}, {}, {}); WaitUntilConnectDone(); stream_request_.reset(); @@ -1392,17 +1408,28 @@ TEST_P(WebSocketStreamCreateUMATest, Failed) { base::HistogramTester histogram_tester; - static const char kInvalidStatusCodeResponse[] = - "HTTP/1.1 200 OK\r\n" - "Upgrade: websocket\r\n" - "Connection: Upgrade\r\n" - "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" - "\r\n"; - CreateAndConnectCustomResponse("ws://www.example.org/", "www.example.org", - "/", NoSubProtocols(), Origin(), Url(), {}, {}, - kInvalidStatusCodeResponse); - WaitUntilConnectDone(); - stream_request_.reset(); + if (stream_type_ == BASIC_HANDSHAKE_STREAM) { + AddSSLData(); + static const char kInvalidStatusCodeResponse[] = + "HTTP/1.1 200 OK\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\r\n" + "\r\n"; + CreateAndConnectCustomResponse("wss://www.example.org/", "www.example.org", + "/", NoSubProtocols(), Origin(), Url(), {}, + {}, kInvalidStatusCodeResponse); + WaitUntilConnectDone(); + stream_request_.reset(); + } else { + DCHECK_EQ(stream_type_, HTTP2_HANDSHAKE_STREAM); + AddSSLData(); + SetHttp2ResponseStatus("404"); + CreateAndConnectStandard("wss://www.example.org/", "www.example.org", "/", + NoSubProtocols(), Origin(), Url(), {}, {}, {}); + WaitUntilConnectDone(); + stream_request_.reset(); + } auto samples = histogram_tester.GetHistogramSamplesSinceCreation( "Net.WebSocket.HandshakeResult");
diff --git a/services/tracing/coordinator.cc b/services/tracing/coordinator.cc index 795abd0..351a66d8 100644 --- a/services/tracing/coordinator.cc +++ b/services/tracing/coordinator.cc
@@ -347,7 +347,7 @@ weak_ptr_factory_.GetWeakPtr(), base::Unretained(agent_entry), false)); agent_entry->agent()->StartTracing( - config_, base::TimeTicks::Now(), + config_, TRACE_TIME_TICKS_NOW(), base::BindRepeating(&Coordinator::OnTracingStarted, weak_ptr_factory_.GetWeakPtr(), base::Unretained(agent_entry)));
diff --git a/services/tracing/public/cpp/chrome_trace_event_agent.cc b/services/tracing/public/cpp/chrome_trace_event_agent.cc index 0def62c..135105eb 100644 --- a/services/tracing/public/cpp/chrome_trace_event_agent.cc +++ b/services/tracing/public/cpp/chrome_trace_event_agent.cc
@@ -65,7 +65,7 @@ // NaCl and system times are offset by a bit, so subtract some time from // the captured timestamps. The value might be off by a bit due to messaging // latency. - base::TimeDelta time_offset = base::TimeTicks::Now() - coordinator_time; + base::TimeDelta time_offset = TRACE_TIME_TICKS_NOW() - coordinator_time; TraceLog::GetInstance()->SetTimeOffset(time_offset); #endif enabled_tracing_modes_ = base::trace_event::TraceLog::RECORDING_MODE;
diff --git a/services/viz/public/cpp/compositing/copy_output_result_struct_traits.cc b/services/viz/public/cpp/compositing/copy_output_result_struct_traits.cc index 0b952bd..c0fd8a8 100644 --- a/services/viz/public/cpp/compositing/copy_output_result_struct_traits.cc +++ b/services/viz/public/cpp/compositing/copy_output_result_struct_traits.cc
@@ -40,6 +40,92 @@ namespace mojo { // static +viz::mojom::CopyOutputResultFormat +EnumTraits<viz::mojom::CopyOutputResultFormat, viz::CopyOutputResult::Format>:: + ToMojom(viz::CopyOutputResult::Format format) { + switch (format) { + case viz::CopyOutputResult::Format::RGBA_BITMAP: + return viz::mojom::CopyOutputResultFormat::RGBA_BITMAP; + case viz::CopyOutputResult::Format::RGBA_TEXTURE: + return viz::mojom::CopyOutputResultFormat::RGBA_TEXTURE; + case viz::CopyOutputResult::Format::I420_PLANES: + break; // Not intended for transport across service boundaries. + } + NOTREACHED(); + return viz::mojom::CopyOutputResultFormat::RGBA_BITMAP; +} + +// static +bool EnumTraits<viz::mojom::CopyOutputResultFormat, + viz::CopyOutputResult::Format>:: + FromMojom(viz::mojom::CopyOutputResultFormat input, + viz::CopyOutputResult::Format* out) { + switch (input) { + case viz::mojom::CopyOutputResultFormat::RGBA_BITMAP: + *out = viz::CopyOutputResult::Format::RGBA_BITMAP; + return true; + case viz::mojom::CopyOutputResultFormat::RGBA_TEXTURE: + *out = viz::CopyOutputResult::Format::RGBA_TEXTURE; + return true; + } + return false; +} + +// static +viz::CopyOutputResult::Format +StructTraits<viz::mojom::CopyOutputResultDataView, + std::unique_ptr<viz::CopyOutputResult>>:: + format(const std::unique_ptr<viz::CopyOutputResult>& result) { + return result->format(); +} + +// static +const gfx::Rect& StructTraits<viz::mojom::CopyOutputResultDataView, + std::unique_ptr<viz::CopyOutputResult>>:: + rect(const std::unique_ptr<viz::CopyOutputResult>& result) { + return result->rect(); +} + +// static +const SkBitmap& StructTraits<viz::mojom::CopyOutputResultDataView, + std::unique_ptr<viz::CopyOutputResult>>:: + bitmap(const std::unique_ptr<viz::CopyOutputResult>& result) { + // This will return a non-drawable bitmap if the result was not + // RGBA_BITMAP or if the result is empty. + return result->AsSkBitmap(); +} + +// static +base::Optional<gpu::Mailbox> +StructTraits<viz::mojom::CopyOutputResultDataView, + std::unique_ptr<viz::CopyOutputResult>>:: + mailbox(const std::unique_ptr<viz::CopyOutputResult>& result) { + if (result->format() != viz::CopyOutputResult::Format::RGBA_TEXTURE) + return base::nullopt; + return result->GetTextureResult()->mailbox; +} + +// static +base::Optional<gpu::SyncToken> +StructTraits<viz::mojom::CopyOutputResultDataView, + std::unique_ptr<viz::CopyOutputResult>>:: + sync_token(const std::unique_ptr<viz::CopyOutputResult>& result) { + if (result->format() != viz::CopyOutputResult::Format::RGBA_TEXTURE) + return base::nullopt; + return result->GetTextureResult()->sync_token; +} + +// static +base::Optional<gfx::ColorSpace> +StructTraits<viz::mojom::CopyOutputResultDataView, + std::unique_ptr<viz::CopyOutputResult>>:: + color_space(const std::unique_ptr<viz::CopyOutputResult>& result) { + if (result->format() != viz::CopyOutputResult::Format::RGBA_TEXTURE) + return base::nullopt; + return result->GetTextureResult()->color_space; +} + +// static viz::mojom::TextureReleaserPtr StructTraits<viz::mojom::CopyOutputResultDataView, std::unique_ptr<viz::CopyOutputResult>>::
diff --git a/services/viz/public/cpp/compositing/copy_output_result_struct_traits.h b/services/viz/public/cpp/compositing/copy_output_result_struct_traits.h index 2fdcfc2e..60900bd 100644 --- a/services/viz/public/cpp/compositing/copy_output_result_struct_traits.h +++ b/services/viz/public/cpp/compositing/copy_output_result_struct_traits.h
@@ -20,73 +20,32 @@ struct EnumTraits<viz::mojom::CopyOutputResultFormat, viz::CopyOutputResult::Format> { static viz::mojom::CopyOutputResultFormat ToMojom( - viz::CopyOutputResult::Format format) { - switch (format) { - case viz::CopyOutputResult::Format::RGBA_BITMAP: - return viz::mojom::CopyOutputResultFormat::RGBA_BITMAP; - case viz::CopyOutputResult::Format::RGBA_TEXTURE: - return viz::mojom::CopyOutputResultFormat::RGBA_TEXTURE; - case viz::CopyOutputResult::Format::I420_PLANES: - break; // Not intended for transport across service boundaries. - } - NOTREACHED(); - return viz::mojom::CopyOutputResultFormat::RGBA_BITMAP; - } + viz::CopyOutputResult::Format format); static bool FromMojom(viz::mojom::CopyOutputResultFormat input, - viz::CopyOutputResult::Format* out) { - switch (input) { - case viz::mojom::CopyOutputResultFormat::RGBA_BITMAP: - *out = viz::CopyOutputResult::Format::RGBA_BITMAP; - return true; - case viz::mojom::CopyOutputResultFormat::RGBA_TEXTURE: - *out = viz::CopyOutputResult::Format::RGBA_TEXTURE; - return true; - } - return false; - } + viz::CopyOutputResult::Format* out); }; template <> struct StructTraits<viz::mojom::CopyOutputResultDataView, std::unique_ptr<viz::CopyOutputResult>> { static viz::CopyOutputResult::Format format( - const std::unique_ptr<viz::CopyOutputResult>& result) { - return result->format(); - } + const std::unique_ptr<viz::CopyOutputResult>& result); static const gfx::Rect& rect( - const std::unique_ptr<viz::CopyOutputResult>& result) { - return result->rect(); - } + const std::unique_ptr<viz::CopyOutputResult>& result); static const SkBitmap& bitmap( - const std::unique_ptr<viz::CopyOutputResult>& result) { - // This will return a non-drawable bitmap if the result was not - // RGBA_BITMAP or if the result is empty. - return result->AsSkBitmap(); - } + const std::unique_ptr<viz::CopyOutputResult>& result); static base::Optional<gpu::Mailbox> mailbox( - const std::unique_ptr<viz::CopyOutputResult>& result) { - if (result->format() != viz::CopyOutputResult::Format::RGBA_TEXTURE) - return base::nullopt; - return result->GetTextureResult()->mailbox; - } + const std::unique_ptr<viz::CopyOutputResult>& result); static base::Optional<gpu::SyncToken> sync_token( - const std::unique_ptr<viz::CopyOutputResult>& result) { - if (result->format() != viz::CopyOutputResult::Format::RGBA_TEXTURE) - return base::nullopt; - return result->GetTextureResult()->sync_token; - } + const std::unique_ptr<viz::CopyOutputResult>& result); static base::Optional<gfx::ColorSpace> color_space( - const std::unique_ptr<viz::CopyOutputResult>& result) { - if (result->format() != viz::CopyOutputResult::Format::RGBA_TEXTURE) - return base::nullopt; - return result->GetTextureResult()->color_space; - } + const std::unique_ptr<viz::CopyOutputResult>& result); static viz::mojom::TextureReleaserPtr releaser( const std::unique_ptr<viz::CopyOutputResult>& result);
diff --git a/services/viz/public/cpp/compositing/paint_filter.typemap b/services/viz/public/cpp/compositing/paint_filter.typemap index 8dc59bd4..610e620b 100644 --- a/services/viz/public/cpp/compositing/paint_filter.typemap +++ b/services/viz/public/cpp/compositing/paint_filter.typemap
@@ -9,4 +9,7 @@ deps = [ "//cc/paint", ] +sources = [ + "//services/viz/public/cpp/compositing/paint_filter_struct_traits.cc", +] type_mappings = [ "viz.mojom.PaintFilter=sk_sp<cc::PaintFilter>" ]
diff --git a/services/viz/public/cpp/compositing/paint_filter_struct_traits.cc b/services/viz/public/cpp/compositing/paint_filter_struct_traits.cc new file mode 100644 index 0000000..2e5757bd --- /dev/null +++ b/services/viz/public/cpp/compositing/paint_filter_struct_traits.cc
@@ -0,0 +1,62 @@ +// 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 "services/viz/public/cpp/compositing/paint_filter_struct_traits.h" + +#include "cc/paint/paint_filter.h" + +namespace mojo { + +// static +base::Optional<std::vector<uint8_t>> +StructTraits<viz::mojom::PaintFilterDataView, sk_sp<cc::PaintFilter>>::data( + const sk_sp<cc::PaintFilter>& filter) { + std::vector<uint8_t> memory; + memory.resize(cc::PaintOpWriter::HeaderBytes() + + cc::PaintFilter::GetFilterSize(filter.get())); + cc::PaintOpWriter writer(memory.data(), memory.size(), nullptr, nullptr, + true /* enable_security_constraints */); + writer.Write(filter.get()); + + if (writer.size() == 0) + return base::nullopt; + + memory.resize(writer.size()); + return memory; +} + +// static +bool StructTraits<viz::mojom::PaintFilterDataView, sk_sp<cc::PaintFilter>>:: + Read(viz::mojom::PaintFilterDataView data, sk_sp<cc::PaintFilter>* out) { + base::Optional<std::vector<uint8_t>> buffer; + if (!data.ReadData(&buffer)) + return false; + + if (!buffer) { + // We may fail to serialize the filter if it doesn't fit in kBufferSize + // above, use an empty filter instead of rejecting the message. + *out = nullptr; + return true; + } + + cc::PaintOpReader reader(buffer->data(), buffer->size(), nullptr, + true /* enable_security_constraints */); + sk_sp<cc::PaintFilter> filter; + reader.Read(&filter); + if (!reader.valid()) { + *out = nullptr; + return false; + } + + // We must have consumed all bytes writen when reading this filter. + if (reader.remaining_bytes() != 0u) { + *out = nullptr; + return false; + } + + *out = std::move(filter); + return true; +} + +} // namespace mojo
diff --git a/services/viz/public/cpp/compositing/paint_filter_struct_traits.h b/services/viz/public/cpp/compositing/paint_filter_struct_traits.h index a6df351..de2e8bd 100644 --- a/services/viz/public/cpp/compositing/paint_filter_struct_traits.h +++ b/services/viz/public/cpp/compositing/paint_filter_struct_traits.h
@@ -7,62 +7,23 @@ #include <vector> -#include "cc/paint/paint_filter.h" #include "cc/paint/paint_op_reader.h" #include "cc/paint/paint_op_writer.h" #include "services/viz/public/interfaces/compositing/paint_filter.mojom-shared.h" +namespace cc { +class PaintFilter; +} + namespace mojo { template <> struct StructTraits<viz::mojom::PaintFilterDataView, sk_sp<cc::PaintFilter>> { static base::Optional<std::vector<uint8_t>> data( - const sk_sp<cc::PaintFilter>& filter) { - std::vector<uint8_t> memory; - memory.resize(cc::PaintOpWriter::HeaderBytes() + - cc::PaintFilter::GetFilterSize(filter.get())); - cc::PaintOpWriter writer(memory.data(), memory.size(), nullptr, nullptr, - true /* enable_security_constraints */); - writer.Write(filter.get()); - - if (writer.size() == 0) - return base::nullopt; - - memory.resize(writer.size()); - return memory; - } + const sk_sp<cc::PaintFilter>& filter); static bool Read(viz::mojom::PaintFilterDataView data, - sk_sp<cc::PaintFilter>* out) { - base::Optional<std::vector<uint8_t>> buffer; - if (!data.ReadData(&buffer)) - return false; - - if (!buffer) { - // We may fail to serialize the filter if it doesn't fit in kBufferSize - // above, use an empty filter instead of rejecting the message. - *out = nullptr; - return true; - } - - cc::PaintOpReader reader(buffer->data(), buffer->size(), nullptr, - true /* enable_security_constraints */); - sk_sp<cc::PaintFilter> filter; - reader.Read(&filter); - if (!reader.valid()) { - *out = nullptr; - return false; - } - - // We must have consumed all bytes writen when reading this filter. - if (reader.remaining_bytes() != 0u) { - *out = nullptr; - return false; - } - - *out = std::move(filter); - return true; - } + sk_sp<cc::PaintFilter>* out); }; } // namespace mojo
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter index 4490cff..055ae80 100644 --- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -211,14 +211,6 @@ # Remove streams concept from code and replace with data pipe passing. -MimeHandlerViewTests/MimeHandlerViewTest.Abort/0 -MimeHandlerViewTests/MimeHandlerViewTest.Abort/1 --MimeHandlerViewTests/MimeHandlerViewTest.DataUrl/0 --MimeHandlerViewTests/MimeHandlerViewTest.DataUrl/1 --MimeHandlerViewTests/MimeHandlerViewTest.EmbeddedDataUrlEmbed/0 --MimeHandlerViewTests/MimeHandlerViewTest.EmbeddedDataUrlEmbed/1 --MimeHandlerViewTests/MimeHandlerViewTest.EmbeddedDataUrlLong/0 --MimeHandlerViewTests/MimeHandlerViewTest.EmbeddedDataUrlLong/1 --MimeHandlerViewTests/MimeHandlerViewTest.EmbeddedDataUrlObject/0 --MimeHandlerViewTests/MimeHandlerViewTest.EmbeddedDataUrlObject/1 -MimeHandlerViewTests/MimeHandlerViewTest.SingleRequest/0 -MimeHandlerViewTests/MimeHandlerViewTest.SingleRequest/1 -PrerenderBrowserTestWithExtensions.StreamsTest @@ -334,16 +326,6 @@ -ContentFaviconDriverTest.ReloadBypassingCache -ContentFaviconDriverTest.MixedContentSecureFaviconAllowed - -# Failing NoStatePrefetch tests -# https://crbug.com/792776 -# -# Crashing. --NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchCookie/1 --NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchCookie/0 --NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchCookieCrossDomain/0 --NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchCookieCrossDomain/1 - # Add support of download_to_file for URLLoader. # http://crbug.com/791702 -OutOfProcessPPAPITest.FileRef1
diff --git a/third_party/WebKit/LayoutTests/ASANExpectations b/third_party/WebKit/LayoutTests/ASANExpectations index 4a25f084..537d6434 100644 --- a/third_party/WebKit/LayoutTests/ASANExpectations +++ b/third_party/WebKit/LayoutTests/ASANExpectations
@@ -70,3 +70,6 @@ crbug.com/803276 virtual/sampling-heap-profiler/inspector-protocol/memory/sampling-native-profile.js [ Skip ] crbug.com/803276 virtual/sampling-heap-profiler/inspector-protocol/memory/sampling-native-snapshot.js [ Skip ] +# Tests timing out sometimes on WebKit Linux Trusty ASAN/MSAN +crbug.com/681919 [ Linux ] http/tests/media/media-src-suspend-after-have-metadata.html [ Timeout Pass ] +crbug.com/681919 [ Linux ] http/tests/media/media-src-suspend-before-have-metadata.html [ Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/MSANExpectations b/third_party/WebKit/LayoutTests/MSANExpectations index f322677..659f5ae 100644 --- a/third_party/WebKit/LayoutTests/MSANExpectations +++ b/third_party/WebKit/LayoutTests/MSANExpectations
@@ -93,3 +93,6 @@ crbug.com/803276 virtual/sampling-heap-profiler/inspector-protocol/memory/sampling-native-profile.js [ Skip ] crbug.com/803276 virtual/sampling-heap-profiler/inspector-protocol/memory/sampling-native-snapshot.js [ Skip ] +# Tests timing out sometimes on WebKit Linux Trusty ASAN/MSAN +crbug.com/681919 [ Linux ] http/tests/media/media-src-suspend-after-have-metadata.html [ Timeout Pass ] +crbug.com/681919 [ Linux ] http/tests/media/media-src-suspend-before-have-metadata.html [ Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 873c8d73..5c2bd039 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -883,10 +883,8 @@ crbug.com/441840 external/wpt/css/css-shapes/shape-outside/values/shape-outside-polygon-004.html [ Failure ] crbug.com/441840 [ Linux Win ] external/wpt/css/css-shapes/shape-outside/values/shape-outside-shape-arguments-000.html [ Failure ] -crbug.com/817804 [ Linux ] external/wpt/css/css-text/i18n/css3-text-line-break-opclns-004.html [ Failure ] crbug.com/817781 external/wpt/css/css-text/i18n/css3-text-line-break-opclns-013.html [ Failure ] crbug.com/817781 external/wpt/css/css-text/i18n/css3-text-line-break-opclns-048.html [ Failure ] -crbug.com/817804 [ Linux ] external/wpt/css/css-text/i18n/css3-text-line-break-opclns-111.html [ Failure ] crbug.com/817778 external/wpt/css/css-text/i18n/css3-text-line-break-opclns-118.html [ Failure ] crbug.com/817778 external/wpt/css/css-text/i18n/css3-text-line-break-opclns-154.html [ Failure ] crbug.com/817778 external/wpt/css/css-text/i18n/css3-text-line-break-opclns-216.html [ Failure ] @@ -1669,6 +1667,7 @@ crbug.com/805463 external/wpt/acid/acid3/numbered-tests.html [ Skip ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/css/css-writing-modes/available-size-019.html [ Failure ] crbug.com/626703 external/wpt/payment-request/change-shipping-option-select-last-manual.https.html [ Skip ] crbug.com/626703 [ Mac10.13 ] external/wpt/css/css-text/word-break/word-break-break-all-004.html [ Failure ] crbug.com/626703 [ Android ] external/wpt/bluetooth/requestDevice/canonicalizeFilter/no-arguments.https.html [ Crash ] @@ -3357,11 +3356,15 @@ crbug.com/811977 virtual/new-remote-playback-pipeline/media/controls/picture-in-picture-interstitial.html [ Skip ] # Sheriff 2018-02-26 -crbug.com/816475 [ Win7 ] external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Failure Pass ] +# NOT FIXED - must be commented out to let temp disable below be committed: crbug.com/816475 [ Win7 ] external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Failure Pass ] crbug.com/816914 [ Mac ] fast/canvas/canvas-drawImage-live-video.html [ Failure Pass ] crbug.com/816766 [ Mac ] fast/dom/Window/window-focus-self.html [ Failure Pass ] crbug.com/817167 http/tests/devtools/oopif/oopif-cookies-refresh.js [ Failure Timeout Pass ] +# Temporary disable to allow webrtc bugfix to land +crbug.com/819118 external/wpt/webrtc/RTCDTMFSender-ontonechange.https.html [ Skip ] +crbug.com/819118 external/wpt/webrtc/RTCDTMFSender-insertDTMF.https.html [ Skip ] + # Sheriff 2018-03-01 crbug.com/817678 [ Win ] http/tests/devtools/console/console-group-similar.js [ Failure Pass ] @@ -3395,3 +3398,7 @@ # Sheriff 2018-03-05 crbug.com/818650 [ Linux ] fast/speech/scripted/speechrecognition-restart-onend.html [ Crash Pass ] + +# Sheriff 2018-03-06 +crbug.com/681919 [ Linux Debug ] http/tests/media/media-src-suspend-after-have-metadata.html [ Timeout Pass ] +crbug.com/681919 [ Linux Debug ] http/tests/media/media-src-suspend-before-have-metadata.html [ Timeout Pass ]
diff --git a/third_party/WebKit/LayoutTests/animations/interpolation/column-count-interpolation.html b/third_party/WebKit/LayoutTests/animations/interpolation/column-count-interpolation.html new file mode 100644 index 0000000..608b9c7 --- /dev/null +++ b/third_party/WebKit/LayoutTests/animations/interpolation/column-count-interpolation.html
@@ -0,0 +1,58 @@ +<!DOCTYPE html> +<body> +<style> +.parent { + column-count: 30; +} +.target { + column-count: 10; +} +</style> +<script src="resources/interpolation-test.js"></script> +<script> +assertInterpolation({ + property: 'column-count', + from: neutralKeyframe, + to: '20', +}, [ + {at: -0.5, is: '5'}, + {at: 0, is: '10'}, + {at: 0.3, is: '13'}, + {at: 0.7, is: '17'}, + {at: 1, is: '20'}, + {at: 1.5, is: '25'}, +]); + +assertNoInterpolation({ + property: 'column-count', + from: 'auto', + to: '20', +}); + +assertInterpolation({ + property: 'column-count', + from: 'inherit', + to: '20', +}, [ + {at: -0.5, is: '35'}, + {at: 0, is: '30'}, + {at: 0.3, is: '27'}, + {at: 0.7, is: '23'}, + {at: 1, is: '20'}, + {at: 1.5, is: '15'}, +]); + +assertInterpolation({ + property: 'column-count', + from: '10', + to: '1' +}, [ + {at: -0.5, is: '15'}, + {at: 0, is: '10'}, + {at: 0.3, is: '7'}, + {at: 0.7, is: '4'}, + // Only positive integers are valid + {at: 1, is: '1'}, + {at: 1.5, is: '1'} +]); +</script>
diff --git a/third_party/WebKit/LayoutTests/animations/responsive/animations-responsive-columnCount.html b/third_party/WebKit/LayoutTests/animations/responsive/animations-responsive-columnCount.html new file mode 100644 index 0000000..cda651cf --- /dev/null +++ b/third_party/WebKit/LayoutTests/animations/responsive/animations-responsive-columnCount.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<div id='container'> + <div id='element'></div> +</div> +<script> + +var container = document.getElementById('container'); +var element = document.getElementById('element'); + +test(function() { + var keyframes = [ + {columnCount: 'inherit'}, + {columnCount: '6'} + ]; + + container.style.columnCount = 'auto'; + var player = element.animate(keyframes, 20); + + player.pause(); + player.currentTime = 5; + assert_equals(getComputedStyle(element).columnCount, 'auto'); + + container.style.columnCount = '2'; + assert_equals(getComputedStyle(element).columnCount, '3'); + + player.currentTime = 10; + container.style.columnCount = '8'; + assert_equals(getComputedStyle(element).columnCount, '7'); +}, 'column-count responsive to inherited column-count changes'); +</script>
diff --git a/third_party/WebKit/LayoutTests/animations/responsive/animations-responsive-font-size-adjust.html b/third_party/WebKit/LayoutTests/animations/responsive/animations-responsive-font-size-adjust.html new file mode 100644 index 0000000..447c6378 --- /dev/null +++ b/third_party/WebKit/LayoutTests/animations/responsive/animations-responsive-font-size-adjust.html
@@ -0,0 +1,32 @@ +<!DOCTYPE html> +<script src="../../resources/testharness.js"></script> +<script src="../../resources/testharnessreport.js"></script> +<div id='container'> + <div id='element'></div> +</div> +<script> + +var container = document.getElementById('container'); +var element = document.getElementById('element'); + +test(function() { + var keyframes = [ + {fontSizeAdjust: 'inherit'}, + {fontSizeAdjust: '6'} + ]; + + container.style.fontSizeAdjust = 'none'; + var player = element.animate(keyframes, 20); + + player.pause(); + player.currentTime = 5; + assert_equals(getComputedStyle(element).fontSizeAdjust, 'none'); + + container.style.fontSizeAdjust = '2'; + assert_equals(getComputedStyle(element).fontSizeAdjust, '3'); + + player.currentTime = 10; + container.style.fontSizeAdjust = '8'; + assert_equals(getComputedStyle(element).fontSizeAdjust, '7'); +}, 'font-size-adjust responsive to inherited font-size-adjust changes'); +</script>
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index ae78a8f..c59f07b 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -74741,6 +74741,18 @@ {} ] ], + "css/css-writing-modes/available-size-019.html": [ + [ + "/css/css-writing-modes/available-size-019.html", + [ + [ + "/css/css-writing-modes/reference/available-size-002-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-writing-modes/background-position-vrl-018.xht": [ [ "/css/css-writing-modes/background-position-vrl-018.xht", @@ -146550,6 +146562,11 @@ {} ] ], + "html/semantics/forms/textfieldselection/selection-start-end-extra-expected.txt": [ + [ + {} + ] + ], "html/semantics/forms/the-button-element/.gitkeep": [ [ {} @@ -177591,6 +177608,12 @@ {} ] ], + "css/css-display/display-contents-parsing-001.html": [ + [ + "/css/css-display/display-contents-parsing-001.html", + {} + ] + ], "css/css-display/display-contents-svg-anchor-child.html": [ [ "/css/css-display/display-contents-svg-anchor-child.html", @@ -178017,6 +178040,12 @@ {} ] ], + "css/css-flexbox/getcomputedstyle/flexbox_computedstyle_min-auto-size.html": [ + [ + "/css/css-flexbox/getcomputedstyle/flexbox_computedstyle_min-auto-size.html", + {} + ] + ], "css/css-flexbox/getcomputedstyle/flexbox_computedstyle_min-height-auto.html": [ [ "/css/css-flexbox/getcomputedstyle/flexbox_computedstyle_min-height-auto.html", @@ -179295,6 +179324,12 @@ {} ] ], + "css/css-grid/grid-items/grid-item-min-auto-size-001.html": [ + [ + "/css/css-grid/grid-items/grid-item-min-auto-size-001.html", + {} + ] + ], "css/css-grid/grid-items/grid-minimum-size-grid-items-021.html": [ [ "/css/css-grid/grid-items/grid-minimum-size-grid-items-021.html", @@ -180759,6 +180794,12 @@ {} ] ], + "css/css-tables/width-distribution/td-with-subpixel-padding.html": [ + [ + "/css/css-tables/width-distribution/td-with-subpixel-padding.html", + {} + ] + ], "css/css-text-decor/text-decoration-serialization.tentative.html": [ [ "/css/css-text-decor/text-decoration-serialization.tentative.html", @@ -197553,6 +197594,12 @@ {} ] ], + "html/semantics/forms/textfieldselection/selection-start-end-extra.html": [ + [ + "/html/semantics/forms/textfieldselection/selection-start-end-extra.html", + {} + ] + ], "html/semantics/forms/textfieldselection/selection-start-end.html": [ [ "/html/semantics/forms/textfieldselection/selection-start-end.html", @@ -271914,6 +271961,10 @@ "a0114c40f3919ed615525495b8504925dbbc6cc7", "reftest" ], + "css/css-display/display-contents-parsing-001.html": [ + "a058037193f51ef4cfdf6870d5e09e24901cbe9c", + "testharness" + ], "css/css-display/display-contents-pass-green-no-red-ref.html": [ "6c4a6b62d0ea48e8a7778ea20b1d2a26ff8e68aa", "support" @@ -274458,6 +274509,10 @@ "0b598a59d971769ea6e6243652493ac12206e374", "testharness" ], + "css/css-flexbox/getcomputedstyle/flexbox_computedstyle_min-auto-size.html": [ + "6a91427df77eb29fa9b04568abd30c96c218b69e", + "testharness" + ], "css/css-flexbox/getcomputedstyle/flexbox_computedstyle_min-height-auto.html": [ "0ba6f6efc0a0663dc822f2795aad3b322dfd7e9c", "testharness" @@ -283898,6 +283953,10 @@ "21d5aae1010b398e29175baa05eeca7fef76d8c0", "reftest" ], + "css/css-grid/grid-items/grid-item-min-auto-size-001.html": [ + "ec33f67361be5b5f13334788b998c1f6676343e6", + "testharness" + ], "css/css-grid/grid-items/grid-items-001.html": [ "9d1066bf6e7051f36c7750b1cd22ad2c23ef2ae4", "reftest" @@ -289222,6 +289281,10 @@ "9eeb49d2d78c3f81825de0d9e24de2a097275175", "testharness" ], + "css/css-tables/width-distribution/td-with-subpixel-padding.html": [ + "3f7a5f9c45ea9a664220ddaa45f7bc671810f9e6", + "testharness" + ], "css/css-tables/zero-rowspan-001-ref.html": [ "b7886acdf8a380f85ebbcab0ded1e927fd509600", "support" @@ -301295,7 +301358,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/declared/append.tentative.html": [ - "b7e04deeef9b7f7c71534973425a87435727706b", + "51933be93dabfa2cd0e57224d9a53733d6e20809", "testharness" ], "css/css-typed-om/the-stylepropertymap/declared/clear.html": [ @@ -301351,11 +301414,11 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/declared/set.tentative.html": [ - "23c875b8bb41344e9c4ffc0753f8f8fb36171d8b", + "6ae0c80287da3f5053a1fbe79893fcffed48524f", "testharness" ], "css/css-typed-om/the-stylepropertymap/inline/append.tentative.html": [ - "d8d853cb1ac33b5668f42a6f8cb53fbac1e43936", + "198863e1d89a6408aad8768f11e0f7f7d3de0899", "testharness" ], "css/css-typed-om/the-stylepropertymap/inline/clear.html": [ @@ -301407,7 +301470,7 @@ "testharness" ], "css/css-typed-om/the-stylepropertymap/inline/set.tentative.html": [ - "68095148a2ede91974f5df04d29a64bcad3ab2f6", + "65c9c20da930fd46136d4dd5706524ae05118807", "testharness" ], "css/css-typed-om/the-stylepropertymap/interface-expected.txt": [ @@ -305855,7 +305918,7 @@ "reftest" ], "css/css-writing-modes/available-size-008.html": [ - "b422cebb5c5839abfa11a049395702cda52a1459", + "ca5b879b261068dbf49246d1f1c9c602d5908236", "reftest" ], "css/css-writing-modes/available-size-009.html": [ @@ -305898,6 +305961,10 @@ "ce16806681745f6904483d09d1954152605bf39b", "reftest" ], + "css/css-writing-modes/available-size-019.html": [ + "3cd3d22d4c43b8e577901f50647080802f007a03", + "reftest" + ], "css/css-writing-modes/background-position-vlr-003.xht": [ "c56c42d17b140be6868cc6f413f545dd6a5180e8", "manual" @@ -338126,6 +338193,14 @@ "db63d0d1eedec810d4c7e1b38789be457e06e985", "testharness" ], + "html/semantics/forms/textfieldselection/selection-start-end-extra-expected.txt": [ + "80487b2ab10598fcb4326963a5d47b7ab90354b3", + "support" + ], + "html/semantics/forms/textfieldselection/selection-start-end-extra.html": [ + "d50596ef2b907db30e6121ba7a5d98c887cdc2b2", + "testharness" + ], "html/semantics/forms/textfieldselection/selection-start-end.html": [ "6bef6943accb6677e9f466df6cc5ad267b01680f", "testharness"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-004.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-004.html index 4708ae59..96b3539 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-004.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-004.html
@@ -10,12 +10,10 @@ <meta name="assert" content="Because it has OP Opening Punctuation property, the browser will not leave 0F3A TIBETAN MARK GUG RTAGS GYON at the end of a line."> <style type='text/css'> @font-face { - font-family: 'mplus-1p-regular'; - src: url('support/mplus-1p-regular.woff') format('woff'); - /* filesize: 803K */ + font-family: CSSFW; + src: url('../../fonts/adobe-fonts/CSSFWOrientationTest.otf'); } -.test, .ref { font-size: 30px; font-family: mplus-1p-regular, sans-serif; width: 95px; padding: 0; border: 1px solid orange; line-height: 1em; } -.test, .ref { width: 115px; } +.test, .ref { font-size: 30px; font-family: CSSFW, sans-serif; width: 3em; padding: 0; border: 1px solid orange; line-height: 1em; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-111.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-111.html index 6b5dea8..4afbcfb 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-111.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/css3-text-line-break-opclns-111.html
@@ -10,12 +10,10 @@ <meta name="assert" content="Because it has a CL Closing Punctuation property, the browser will not leave 0F3B TIBETAN MARK GUG RTAGS GYAS at the beginning of a line."> <style type='text/css'> @font-face { - font-family: 'mplus-1p-regular'; - src: url('support/mplus-1p-regular.woff') format('woff'); - /* filesize: 803K */ + font-family: CSSFW; + src: url('../../fonts/adobe-fonts/CSSFWOrientationTest.otf'); } -.test, .ref { font-size: 30px; font-family: mplus-1p-regular, sans-serif; width: 95px; padding: 0; border: 1px solid orange; line-height: 1em; } -.test, .ref { width: 115px; } +.test, .ref { font-size: 30px; font-family: CSSFW, sans-serif; width: 3em; padding: 0; border: 1px solid orange; line-height: 1em; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/reference/css3-text-line-break-opclns-004-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/reference/css3-text-line-break-opclns-004-ref.html index ebc6850..06ee93c 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/reference/css3-text-line-break-opclns-004-ref.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/reference/css3-text-line-break-opclns-004-ref.html
@@ -7,12 +7,10 @@ <meta name='flags' content=''> <style type='text/css'> @font-face { - font-family: 'mplus-1p-regular'; - src: url('support/mplus-1p-regular.woff') format('woff'); - /* filesize: 803K */ + font-family: CSSFW; + src: url('../../../fonts/adobe-fonts/CSSFWOrientationTest.otf'); } -.test, .ref { font-size: 30px; font-family: mplus-1p-regular, sans-serif; width: 95px; padding: 0; border: 1px solid orange; line-height: 1em; } -.test, .ref { width: 115px; } +.test, .ref { font-size: 30px; font-family: CSSFW, sans-serif; width: 3em; padding: 0; border: 1px solid orange; line-height: 1em; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/reference/css3-text-line-break-opclns-111-ref.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/reference/css3-text-line-break-opclns-111-ref.html index 030567e0..013ff06a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/reference/css3-text-line-break-opclns-111-ref.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-text/i18n/reference/css3-text-line-break-opclns-111-ref.html
@@ -7,12 +7,10 @@ <meta name='flags' content=''> <style type='text/css'> @font-face { - font-family: 'mplus-1p-regular'; - src: url('support/mplus-1p-regular.woff') format('woff'); - /* filesize: 803K */ + font-family: CSSFW; + src: url('../../../fonts/adobe-fonts/CSSFWOrientationTest.otf'); } -.test, .ref { font-size: 30px; font-family: mplus-1p-regular, sans-serif; width: 95px; padding: 0; border: 1px solid orange; line-height: 1em; } -.test, .ref { width: 115px; } +.test, .ref { font-size: 30px; font-family: CSSFW, sans-serif; padding: 0; width: 3em; border: 1px solid orange; line-height: 1em; } </style> </head> <body>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/available-size-008.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/available-size-008.html index 2fcfbac..d38c9cb 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/available-size-008.html +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/available-size-008.html
@@ -8,7 +8,7 @@ <meta name="flags" content=""> <style> body { margin-top: 0; margin-bottom: 0; } /* Shouldn't matter, but in some browsers does. -007 tests this aspect specifically. */ -div { +div div { writing-mode: vertical-rl; font-family: monospace; font-size: 20px; @@ -46,5 +46,7 @@ <p>Test passes if there is a <strong>green rectangle</strong> below and <strong>no red</strong>. <section> +<div> <div><aside id="red">0</aside><aside class="spacer"></aside><aside class="spacer"></aside><aside class="spacer"></aside><aside class="spacer"></aside><aside class="spacer"></aside> <span>0</span></div> +</div> </section>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/available-size-019.html b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/available-size-019.html new file mode 100644 index 0000000..a25a2f6 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/css/css-writing-modes/available-size-019.html
@@ -0,0 +1,49 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Testing Available Space in Orthogonal Flows / ICB / tall max-height parent</title> +<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net/"> +<link rel="help" href="https://www.w3.org/TR/css-writing-modes-3/#orthogonal-auto"> +<link rel="match" href="reference/available-size-002-ref.html"> +<meta name="assert" content="When an orthogonal flow's parent doesn't have a definite block size, but has a max-height, but that max-height is than the ICB, use the ICB instead."> +<meta name="flags" content=""> +<style> +body { margin-top: 0; margin-bottom: 0; } /* Shouldn't matter, but in some browsers does. -007 tests this aspect specifically. */ +div { + writing-mode: vertical-rl; + font-family: monospace; + font-size: 20px; + position: relative; /* to be a container for #red*/ +} +.spacer { /* using 5 spacers of 20vh each instead of a single large one, so + that the line would wrap between spacers if it ends up being + shorter thatn 100vh*/ + display: inline-block; + height: calc(20vh - 0.1px); /*Using this instead of 20vh, to account for accumulation of rounding errors, that might make 5*20vh taller than 100vh in some browsers*/ +} + +span { + background: green; + display: inline-block; /* This should not change it's size or position, but makes the size of the background predictable*/ + color: transparent; +} + +#red { /* Not necessary when when comparing to the reference, but makes human judgement easier */ + position: absolute; + background: red; + writing-mode: vertical-rl; + z-index: -1; + font-family: monospace; + font-size: 20px; + left: 0; top: 0; +} + +section { + max-height: 120vh; +} +</style> + +<p>Test passes if there is a <strong>green rectangle</strong> below and <strong>no red</strong>. + +<section> +<div><aside id="red">0</aside><aside class="spacer"></aside><aside class="spacer"></aside><aside class="spacer"></aside><aside class="spacer"></aside><aside class="spacer"></aside> <span>0</span></div> +</section>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/basic/integrity-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/basic/integrity-expected.txt deleted file mode 100644 index c91ba4a7..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/basic/integrity-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -This is a testharness.js-based test. -PASS Empty string integrity -PASS SHA-256 integrity -PASS SHA-384 integrity -PASS SHA-512 integrity -PASS Invalid integrity -PASS Multiple integrities: valid stronger than invalid -PASS Multiple integrities: invalid stronger than valid -PASS Multiple integrities: invalid as strong as valid -PASS Multiple integrities: both are valid -PASS Multiple integrities: both are invalid -PASS CORS empty integrity -PASS CORS SHA-512 integrity -PASS CORS invalid integrity -PASS Empty string integrity for opaque response -FAIL SHA-* integrity for opaque response assert_unreached: Should have rejected: undefined Reached unreachable code -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/basic/integrity-sharedworker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/basic/integrity-sharedworker-expected.txt deleted file mode 100644 index c91ba4a7..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/basic/integrity-sharedworker-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -This is a testharness.js-based test. -PASS Empty string integrity -PASS SHA-256 integrity -PASS SHA-384 integrity -PASS SHA-512 integrity -PASS Invalid integrity -PASS Multiple integrities: valid stronger than invalid -PASS Multiple integrities: invalid stronger than valid -PASS Multiple integrities: invalid as strong as valid -PASS Multiple integrities: both are valid -PASS Multiple integrities: both are invalid -PASS CORS empty integrity -PASS CORS SHA-512 integrity -PASS CORS invalid integrity -PASS Empty string integrity for opaque response -FAIL SHA-* integrity for opaque response assert_unreached: Should have rejected: undefined Reached unreachable code -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/basic/integrity-worker-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/fetch/api/basic/integrity-worker-expected.txt deleted file mode 100644 index c91ba4a7..0000000 --- a/third_party/WebKit/LayoutTests/external/wpt/fetch/api/basic/integrity-worker-expected.txt +++ /dev/null
@@ -1,18 +0,0 @@ -This is a testharness.js-based test. -PASS Empty string integrity -PASS SHA-256 integrity -PASS SHA-384 integrity -PASS SHA-512 integrity -PASS Invalid integrity -PASS Multiple integrities: valid stronger than invalid -PASS Multiple integrities: invalid stronger than valid -PASS Multiple integrities: invalid as strong as valid -PASS Multiple integrities: both are valid -PASS Multiple integrities: both are invalid -PASS CORS empty integrity -PASS CORS SHA-512 integrity -PASS CORS invalid integrity -PASS Empty string integrity for opaque response -FAIL SHA-* integrity for opaque response assert_unreached: Should have rejected: undefined Reached unreachable code -Harness: the test ran to completion. -
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/textfieldselection/selection-start-end-extra-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/textfieldselection/selection-start-end-extra-expected.txt new file mode 100644 index 0000000..b2174bf8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/textfieldselection/selection-start-end-extra-expected.txt
@@ -0,0 +1,13 @@ +This is a testharness.js-based test. +PASS Setting defaultValue in a textarea should move the cursor to the end +PASS Setting defaultValue in a textarea with a value should NOT make any difference +PASS Setting textContent in a textarea should move selection{Start,End} to the end +PASS Adding children to a textarea should move selection{Start,End} to the end +PASS Removing children from a textarea should update selection{Start,End} +FAIL Setting the same value (with different newlines) in a textarea should NOT update selection{Start,End} assert_equals: expected 3 but got 14 +PASS Setting value to a shorter string than defaultValue should correct the cursor position +PASS Shortening value by turning the input type into 'url' should correct selection{Start,End} +FAIL Shortening value by turning the input type into 'color' and back to 'text' should correct selection{Start,End} assert_equals: expected 7 but got 9 +PASS Resetting a value to a shorter string than defaultValue should correct the cursor position +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/textfieldselection/selection-start-end-extra.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/textfieldselection/selection-start-end-extra.html new file mode 100644 index 0000000..af51354 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/forms/textfieldselection/selection-start-end-extra.html
@@ -0,0 +1,123 @@ +<!doctype html> +<meta charset=utf-8> +<title></title> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<div id=log></div> +<form id="form"><input id="form-input" type="text" value="abc" /></form> +<script> + // * Should we test setting the dirty flag in any way that isn't + // setting the value? + // * How to simulate users typing? + + test(function() { + var el = document.createElement("textarea"); + assert_equals(el.selectionStart, 0); + assert_equals(el.selectionEnd, 0); + el.defaultValue = "123"; + assert_equals(el.value.length, 3); + assert_equals(el.selectionStart, 3); + assert_equals(el.selectionEnd, 3); + }, "Setting defaultValue in a textarea should move the cursor to the end"); + + test(function() { + var el = document.createElement("textarea"); + el.value = "abcdef"; + assert_equals(el.selectionStart, 6); + assert_equals(el.selectionEnd, 6); + el.defaultValue = "123"; + assert_equals(el.value.length, 6); + assert_equals(el.selectionStart, 6); + assert_equals(el.selectionEnd, 6); + }, "Setting defaultValue in a textarea with a value should NOT make any difference"); + + test(function() { + var el = document.createElement("textarea"); + el.appendChild(document.createTextNode("abcdef")); + assert_equals(el.selectionStart, 6); + assert_equals(el.selectionEnd, 6); + el.textContent = "abcdef123456"; + assert_equals(el.selectionStart, 12); + assert_equals(el.selectionEnd, 12); + }, "Setting textContent in a textarea should move selection{Start,End} to the end"); + + test(function() { + var el = document.createElement("textarea"); + el.appendChild(document.createTextNode("abcdef")); + assert_equals(el.selectionStart, 6); + assert_equals(el.selectionEnd, 6); + el.appendChild(document.createTextNode("123456")); + assert_equals(el.selectionStart, 12); + assert_equals(el.selectionEnd, 12); + }, "Adding children to a textarea should move selection{Start,End} to the end"); + + test(function() { + var el = document.createElement("textarea"); + el.appendChild(document.createTextNode("abcdef")); + el.appendChild(document.createTextNode("123")); + assert_equals(el.selectionStart, 9); + assert_equals(el.selectionEnd, 9); + + el.removeChild(el.firstChild); + assert_equals(el.selectionStart, 3); + assert_equals(el.selectionEnd, 3); + }, "Removing children from a textarea should update selection{Start,End}"); + + test(function() { + var el = document.createElement("textarea"); + el.textContent = "abcdef\nwhatevs"; + el.selectionStart = 3; + el.selectionEnd = 5; + + el.textContent = "abcdef\r\nwhatevs"; + assert_equals(el.selectionStart, 3); + assert_equals(el.selectionEnd, 5); + }, "Setting the same value (with different newlines) in a textarea should NOT update selection{Start,End}"); + + test(function() { + var el = document.createElement("textarea"); + el.defaultValue = "123"; + assert_equals(el.value.length, 3); + assert_equals(el.selectionStart, 3); + assert_equals(el.selectionEnd, 3); + el.value = "12"; + assert_equals(el.value.length, 2); + assert_equals(el.selectionStart, 2); + assert_equals(el.selectionEnd, 2); + }, "Setting value to a shorter string than defaultValue should correct the cursor position"); + + test(function() { + var el = document.createElement("input"); + el.type = "text"; + el.value = "http://example.com "; + assert_equals(el.selectionStart, 21); + assert_equals(el.selectionEnd, 21); + el.type = "url"; + assert_equals(el.selectionStart, 18); + assert_equals(el.selectionEnd, 18); + }, "Shortening value by turning the input type into 'url' should correct selection{Start,End}"); + + test(function() { + var el = document.createElement("input"); + el.type = "text"; + el.value = "#123456xx"; + assert_equals(el.selectionStart, 9); + assert_equals(el.selectionEnd, 9); + el.type = "color"; + el.type = "text"; + assert_equals(el.selectionStart, 7); + assert_equals(el.selectionEnd, 7); + }, "Shortening value by turning the input type into 'color' and back to 'text' should correct selection{Start,End}"); + + test(function() { + var form = document.getElementById("form"); + var el = document.getElementById("form-input"); + + el.value = "abcde"; + assert_equals(el.value.length, 5); + form.reset(); + assert_equals(el.value.length, 3); + assert_equals(el.selectionStart, 3); + assert_equals(el.selectionEnd, 3); + }, "Resetting a value to a shorter string than defaultValue should correct the cursor position"); +</script>
diff --git a/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/signal-gc.html b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/signal-gc.html new file mode 100644 index 0000000..b02c46e8 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/fetch/chromium/signal-gc.html
@@ -0,0 +1,37 @@ +<!doctype html> +<script src = "/resources/testharness.js"></script> +<script src = "/resources/testharnessreport.js"></script> +<script> +// This test verifies that chains of AbortSignal objects do not lose abort +// events due to collection of objects in the middle of the chain. It uses +// Request objects to perform the chaining, as they are currently the only place +// that the https://dom.spec.whatwg.org/#abortsignal-follow operation is used in +// Blink. +// +// This test is Blink-specific because it requires access to garbage collection. +promise_test(async () => { + assert_not_equals(typeof GCController, undefined, + 'this test requires garbage collection to be exposed'); + // |controller| will have a strong reference to controller.signal. + const controller = new AbortController(); + // |controller.signal| will hold a weak reference to |signal|. + let signal = new Request('/', { signal: controller.signal }).signal; + // |signal| will hold a weak reference to |request.signal|. + const request = new Request('/', { signal: signal }); + + // Allow |signal| to be collected. + signal = undefined; + + // Experimantely two collections is the right number for collection to + // reliably happen. If this test starts to flake, try increasing the number. + for (let i = 0; i < 2; ++i) { + GCController.collect(); + // Allow the Oilpan GC to run with an empty stack. + await new Promise(resolve => setTimeout(resolve, 0)); + } + + // Abort should still abort the request. + controller.abort(); + assert_true(request.signal.aborted, 'aborted should be true'); +}, 'aborts should not be lost due to garbage collection'); +</script>
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableMarkingVisitorTest.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableMarkingVisitorTest.cpp index 1bd9a08..78da3da9 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableMarkingVisitorTest.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptWrappableMarkingVisitorTest.cpp
@@ -501,6 +501,7 @@ DeathAwareScriptWrappable::Create(); Base* base = Base::Create(base_wrapper, mixin_wrapper); Mixin* mixin = static_cast<Mixin*>(base); + HeapObjectHeader* base_header = HeapObjectHeader::FromPayload(base); EXPECT_FALSE(base_header->IsWrapperHeaderMarked()); @@ -515,7 +516,7 @@ TraceWrapperMember<Mixin> mixin_handle = mixin; EXPECT_TRUE(base_header->IsWrapperHeaderMarked()); EXPECT_FALSE(visitor->MarkingDeque()->IsEmpty()); - EXPECT_TRUE(visitor->MarkingDequeContains(base)); + EXPECT_TRUE(visitor->MarkingDequeContains(mixin)); visitor->AdvanceTracing( 0, v8::EmbedderHeapTracer::AdvanceTracingActions(
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp b/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp index dfd1eb7..ecf0a5a 100644 --- a/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/V8EmbedderGraphBuilder.cpp
@@ -64,7 +64,7 @@ const WrapperDescriptor& wrapper_descriptor) const { // Add an edge from the current parent to this object. // Also push the object to the worklist in order to process its members. - const void* traceable = wrapper_descriptor.base_object_payload; + const void* traceable = wrapper_descriptor.traceable; Graph::Node* graph_node = GraphNode(traceable, wrapper_descriptor.name_callback(traceable)); graph_->AddEdge(current_parent_, graph_node); @@ -113,7 +113,7 @@ V8EmbedderGraphBuilder::WorklistItem V8EmbedderGraphBuilder::ToWorklistItem( Graph::Node* node, const WrapperDescriptor& wrapper_descriptor) const { - return {node, wrapper_descriptor.base_object_payload, + return {node, wrapper_descriptor.traceable, wrapper_descriptor.trace_wrappers_callback}; } @@ -123,7 +123,7 @@ auto item = worklist_.back(); worklist_.pop_back(); ParentScope parent(this, item.node); - item.trace_wrappers_callback(this, const_cast<void*>(item.traceable)); + item.trace_wrappers_callback(this, item.traceable); } }
diff --git a/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp b/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp index f20844dc..a0955681 100644 --- a/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp +++ b/third_party/WebKit/Source/core/animation/CSSNumberInterpolationType.cpp
@@ -8,6 +8,7 @@ #include "core/animation/NumberPropertyFunctions.h" #include "core/css/resolver/StyleBuilder.h" #include "core/css/resolver/StyleResolverState.h" +#include "platform/wtf/Optional.h" #include "platform/wtf/PtrUtil.h" namespace blink { @@ -17,25 +18,23 @@ public: static std::unique_ptr<InheritedNumberChecker> Create( const CSSProperty& property, - double number) { + Optional<double> number) { return WTF::WrapUnique(new InheritedNumberChecker(property, number)); } private: - InheritedNumberChecker(const CSSProperty& property, double number) + InheritedNumberChecker(const CSSProperty& property, Optional<double> number) : property_(property), number_(number) {} bool IsValid(const StyleResolverState& state, const InterpolationValue& underlying) const final { - double parent_number; - if (!NumberPropertyFunctions::GetNumber(property_, *state.ParentStyle(), - parent_number)) - return false; - return parent_number == number_; + Optional<double> parent_number = + NumberPropertyFunctions::GetNumber(property_, *state.ParentStyle()); + return number_ == parent_number; } const CSSProperty& property_; - const double number_; + const Optional<double> number_; }; const CSSValue* CSSNumberInterpolationType::CreateCSSValue( @@ -61,10 +60,11 @@ InterpolationValue CSSNumberInterpolationType::MaybeConvertInitial( const StyleResolverState&, ConversionCheckers& conversion_checkers) const { - double initial_number; - if (!NumberPropertyFunctions::GetInitialNumber(CssProperty(), initial_number)) + Optional<double> initial_number = + NumberPropertyFunctions::GetInitialNumber(CssProperty()); + if (!initial_number) return nullptr; - return CreateNumberValue(initial_number); + return CreateNumberValue(*initial_number); } InterpolationValue CSSNumberInterpolationType::MaybeConvertInherit( @@ -72,13 +72,13 @@ ConversionCheckers& conversion_checkers) const { if (!state.ParentStyle()) return nullptr; - double inherited_number; - if (!NumberPropertyFunctions::GetNumber(CssProperty(), *state.ParentStyle(), - inherited_number)) - return nullptr; + Optional<double> inherited = + NumberPropertyFunctions::GetNumber(CssProperty(), *state.ParentStyle()); conversion_checkers.push_back( - InheritedNumberChecker::Create(CssProperty(), inherited_number)); - return CreateNumberValue(inherited_number); + InheritedNumberChecker::Create(CssProperty(), inherited)); + if (!inherited) + return nullptr; + return CreateNumberValue(*inherited); } InterpolationValue CSSNumberInterpolationType::MaybeConvertValue( @@ -93,11 +93,11 @@ InterpolationValue CSSNumberInterpolationType::MaybeConvertStandardPropertyUnderlyingValue( const ComputedStyle& style) const { - double underlying_number; - if (!NumberPropertyFunctions::GetNumber(CssProperty(), style, - underlying_number)) + Optional<double> underlying_number = + NumberPropertyFunctions::GetNumber(CssProperty(), style); + if (!underlying_number) return nullptr; - return CreateNumberValue(underlying_number); + return CreateNumberValue(*underlying_number); } void CSSNumberInterpolationType::ApplyStandardPropertyValue(
diff --git a/third_party/WebKit/Source/core/animation/NumberPropertyFunctions.cpp b/third_party/WebKit/Source/core/animation/NumberPropertyFunctions.cpp index d087f5b2..96162580 100644 --- a/third_party/WebKit/Source/core/animation/NumberPropertyFunctions.cpp +++ b/third_party/WebKit/Source/core/animation/NumberPropertyFunctions.cpp
@@ -8,83 +8,67 @@ namespace blink { -bool NumberPropertyFunctions::GetInitialNumber(const CSSProperty& property, - double& result) { - return GetNumber(property, ComputedStyle::InitialStyle(), result); +Optional<double> NumberPropertyFunctions::GetInitialNumber( + const CSSProperty& property) { + return GetNumber(property, ComputedStyle::InitialStyle()); } -bool NumberPropertyFunctions::GetNumber(const CSSProperty& property, - const ComputedStyle& style, - double& result) { +Optional<double> NumberPropertyFunctions::GetNumber( + const CSSProperty& property, + const ComputedStyle& style) { switch (property.PropertyID()) { case CSSPropertyFillOpacity: - result = style.FillOpacity(); - return true; + return style.FillOpacity(); case CSSPropertyFlexGrow: - result = style.FlexGrow(); - return true; + return style.FlexGrow(); case CSSPropertyFlexShrink: - result = style.FlexShrink(); - return true; + return style.FlexShrink(); case CSSPropertyFloodOpacity: - result = style.FloodOpacity(); - return true; + return style.FloodOpacity(); case CSSPropertyOpacity: - result = style.Opacity(); - return true; + return style.Opacity(); case CSSPropertyOrder: - result = style.Order(); - return true; + return style.Order(); case CSSPropertyOrphans: - result = style.Orphans(); - return true; + return style.Orphans(); case CSSPropertyShapeImageThreshold: - result = style.ShapeImageThreshold(); - return true; + return style.ShapeImageThreshold(); case CSSPropertyStopOpacity: - result = style.StopOpacity(); - return true; + return style.StopOpacity(); case CSSPropertyStrokeMiterlimit: - result = style.StrokeMiterLimit(); - return true; + return style.StrokeMiterLimit(); case CSSPropertyStrokeOpacity: - result = style.StrokeOpacity(); - return true; + return style.StrokeOpacity(); case CSSPropertyWidows: - result = style.Widows(); - return true; + return style.Widows(); case CSSPropertyFontSizeAdjust: if (!style.HasFontSizeAdjust()) - return false; - result = style.FontSizeAdjust(); - return true; + return Optional<double>(); + return style.FontSizeAdjust(); case CSSPropertyColumnCount: if (style.HasAutoColumnCount()) - return false; - result = style.ColumnCount(); - return true; + return Optional<double>(); + return style.ColumnCount(); case CSSPropertyZIndex: if (style.HasAutoZIndex()) - return false; - result = style.ZIndex(); - return true; + return Optional<double>(); + return style.ZIndex(); case CSSPropertyLineHeight: { const Length& length = style.SpecifiedLineHeight(); // Numbers are represented by percentages. if (length.GetType() != kPercent) - return false; + return Optional<double>(); double value = length.Value(); // -100% represents the keyword "normal". if (value == -100) - return false; - result = value / 100; - return true; + return Optional<double>(); + return value / 100; } default: - return false; + return Optional<double>(); } }
diff --git a/third_party/WebKit/Source/core/animation/NumberPropertyFunctions.h b/third_party/WebKit/Source/core/animation/NumberPropertyFunctions.h index 136af7ff..0ba9a8a9 100644 --- a/third_party/WebKit/Source/core/animation/NumberPropertyFunctions.h +++ b/third_party/WebKit/Source/core/animation/NumberPropertyFunctions.h
@@ -6,6 +6,7 @@ #define NumberPropertyFunctions_h #include "core/CSSPropertyNames.h" +#include "platform/wtf/Optional.h" namespace blink { @@ -14,10 +15,8 @@ class NumberPropertyFunctions { public: - static bool GetInitialNumber(const CSSProperty&, double& result); - static bool GetNumber(const CSSProperty&, - const ComputedStyle&, - double& result); + static Optional<double> GetInitialNumber(const CSSProperty&); + static Optional<double> GetNumber(const CSSProperty&, const ComputedStyle&); static double ClampNumber(const CSSProperty&, double); static bool SetNumber(const CSSProperty&, ComputedStyle&, double); };
diff --git a/third_party/WebKit/Source/core/dom/AbortSignal.cpp b/third_party/WebKit/Source/core/dom/AbortSignal.cpp index 24fdb7c..eb39b3ca 100644 --- a/third_party/WebKit/Source/core/dom/AbortSignal.cpp +++ b/third_party/WebKit/Source/core/dom/AbortSignal.cpp
@@ -44,6 +44,28 @@ DispatchEvent(Event::Create(EventTypeNames::abort)); } +void AbortSignal::Follow(AbortSignal* parentSignal) { + if (aborted_flag_) + return; + if (parentSignal->aborted_flag_) + SignalAbort(); + + // Unlike the usual practice for AddAlgorithm(), we don't use a weak pointer + // here. To see why, consider the following object graph: + // + // controller --owns--> signal1 -?-> signal2 -?-> signal3 <--owns-- request + // + // It's easy to create chained signals like this using the Request + // constructor. If the -?-> pointers were weak, then |signal2| could be + // collected even though |controller| and |request| were still + // referenced. This would prevent controller.abort() from working. So the + // pointers need to be strong. This won't artificially extend the lifetime of + // |request|, because the pointer to it in the closure held by |signal3| is + // still weak. + parentSignal->AddAlgorithm( + WTF::Bind(&AbortSignal::SignalAbort, WrapPersistent(this))); +} + void AbortSignal::Trace(Visitor* visitor) { visitor->Trace(execution_context_); EventTargetWithInlineData::Trace(visitor);
diff --git a/third_party/WebKit/Source/core/dom/AbortSignal.h b/third_party/WebKit/Source/core/dom/AbortSignal.h index 89258f9..0bd48e2 100644 --- a/third_party/WebKit/Source/core/dom/AbortSignal.h +++ b/third_party/WebKit/Source/core/dom/AbortSignal.h
@@ -54,6 +54,11 @@ // event. Does nothing if called more than once. void SignalAbort(); + // The "follow" algorithm from the standard: + // https://dom.spec.whatwg.org/#abortsignal-follow + // |this| is the followingSignal described in the standard. + void Follow(AbortSignal* parentSignal); + virtual void Trace(Visitor*); private:
diff --git a/third_party/WebKit/Source/core/editing/Editor.h b/third_party/WebKit/Source/core/editing/Editor.h index 08564611..be7167cb 100644 --- a/third_party/WebKit/Source/core/editing/Editor.h +++ b/third_party/WebKit/Source/core/editing/Editor.h
@@ -61,8 +61,7 @@ enum class InsertMode { kSimple, kSmart }; enum class DragSourceType { kHTMLSource, kPlainTextSource }; enum class EditorParagraphSeparator { kIsDiv, kIsP }; - -enum EditorCommandSource { kCommandFromMenuOrKeyBinding, kCommandFromDOM }; +enum class EditorCommandSource { kMenuOrKeyBinding, kDOM }; class CORE_EXPORT Editor final : public GarbageCollectedFinalized<Editor> { public:
diff --git a/third_party/WebKit/Source/core/editing/FrameCaret.cpp b/third_party/WebKit/Source/core/editing/FrameCaret.cpp index c5067f7e..d5fb6be 100644 --- a/third_party/WebKit/Source/core/editing/FrameCaret.cpp +++ b/third_party/WebKit/Source/core/editing/FrameCaret.cpp
@@ -160,15 +160,6 @@ display_item_client_->InvalidatePaint(block, context); } -bool FrameCaret::CaretPositionIsValidForDocument( - const Document& document) const { - if (!IsActive()) - return true; - - return CaretPosition().GetDocument() == document && - !CaretPosition().IsOrphan(); -} - static IntRect AbsoluteBoundsForLocalRect(Node* node, const LayoutRect& rect) { LayoutBlock* caret_painter = CaretDisplayItemClient::CaretLayoutBlock(node); if (!caret_painter)
diff --git a/third_party/WebKit/Source/core/editing/FrameCaret.h b/third_party/WebKit/Source/core/editing/FrameCaret.h index fcc98f8..572b917 100644 --- a/third_party/WebKit/Source/core/editing/FrameCaret.h +++ b/third_party/WebKit/Source/core/editing/FrameCaret.h
@@ -39,7 +39,6 @@ class CaretDisplayItemClient; class DisplayItemClient; -class Document; class FrameCaret; class GraphicsContext; class LayoutBlock; @@ -99,7 +98,6 @@ bool ShouldBlinkCaret() const; void CaretBlinkTimerFired(TimerBase*); - bool CaretPositionIsValidForDocument(const Document&) const; void UpdateAppearance(); const Member<const SelectionEditor> selection_editor_;
diff --git a/third_party/WebKit/Source/core/editing/commands/DocumentExecCommand.cpp b/third_party/WebKit/Source/core/editing/commands/DocumentExecCommand.cpp index c4f330b..8a18dde 100644 --- a/third_party/WebKit/Source/core/editing/commands/DocumentExecCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/DocumentExecCommand.cpp
@@ -50,7 +50,8 @@ return Editor::Command(); document->UpdateStyleAndLayoutTree(); - return frame->GetEditor().CreateCommand(command_name, kCommandFromDOM); + return frame->GetEditor().CreateCommand(command_name, + EditorCommandSource::kDOM); } } // namespace
diff --git a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp index ed6bbf1d0..c4decde5 100644 --- a/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp +++ b/third_party/WebKit/Source/core/editing/commands/EditorCommand.cpp
@@ -316,10 +316,10 @@ // FIXME: We don't call shouldApplyStyle when the source is DOM; is there a // good reason for that? switch (source) { - case kCommandFromMenuOrKeyBinding: + case EditorCommandSource::kMenuOrKeyBinding: ApplyStyleToSelection(frame, style, input_type); return true; - case kCommandFromDOM: + case EditorCommandSource::kDOM: ApplyStyle(frame, style, input_type); return true; } @@ -443,10 +443,10 @@ // FIXME: We don't call shouldApplyStyle when the source is DOM; is there a // good reason for that? switch (source) { - case kCommandFromMenuOrKeyBinding: + case EditorCommandSource::kMenuOrKeyBinding: frame.GetEditor().ApplyParagraphStyleToSelection(style, input_type); return true; - case kCommandFromDOM: + case EditorCommandSource::kDOM: frame.GetEditor().ApplyParagraphStyle(style, input_type); return true; } @@ -739,7 +739,7 @@ } static bool CanWriteClipboard(LocalFrame& frame, EditorCommandSource source) { - if (source == kCommandFromMenuOrKeyBinding) + if (source == EditorCommandSource::kMenuOrKeyBinding) return true; Settings* settings = frame.GetSettings(); bool default_value = @@ -756,7 +756,8 @@ // "Set target to be the element that contains the start of the selection in // document order, or the body element if there is no selection or cursor." // We treat hidden selections as "no selection or cursor". - if (source == kCommandFromMenuOrKeyBinding && frame.Selection().IsHidden()) + if (source == EditorCommandSource::kMenuOrKeyBinding && + frame.Selection().IsHidden()) return frame.Selection().GetDocument().body(); return FindEventTargetFrom( @@ -838,7 +839,8 @@ // Since copy is a read-only operation it succeeds anytime a selection // is *visible*. In contrast to cut or paste, the selection does not // need to be focused - being visible is enough. - if (source == kCommandFromMenuOrKeyBinding && frame.Selection().IsHidden()) + if (source == EditorCommandSource::kMenuOrKeyBinding && + frame.Selection().IsHidden()) return true; // TODO(editing-dev): The use of UpdateStyleAndLayoutIgnorePendingStylesheets @@ -911,7 +913,7 @@ // before we obtain the selection. frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return true; @@ -928,7 +930,7 @@ WriteSelectionToPasteboard(frame); } - if (source == kCommandFromMenuOrKeyBinding) { + if (source == EditorCommandSource::kMenuOrKeyBinding) { if (DispatchBeforeInputDataTransfer( FindEventTargetForClipboardEvent(frame, source), InputEvent::InputType::kDeleteByCut, @@ -987,12 +989,12 @@ EditorCommandSource source, const String&) { switch (source) { - case kCommandFromMenuOrKeyBinding: { + case EditorCommandSource::kMenuOrKeyBinding: { // Doesn't modify the text if the current selection isn't a range. PerformDelete(frame); return true; } - case kCommandFromDOM: + case EditorCommandSource::kDOM: // If the current selection is a caret, delete the preceding character. IE // performs forwardDelete, but we currently side with Firefox. Doesn't // scroll to make the selection visible, or modify the kill ring (this @@ -1251,11 +1253,11 @@ const String&) { EditingState editing_state; switch (source) { - case kCommandFromMenuOrKeyBinding: + case EditorCommandSource::kMenuOrKeyBinding: DeleteWithDirection(frame, DeleteDirection::kForward, TextGranularity::kCharacter, false, true); return true; - case kCommandFromDOM: + case EditorCommandSource::kDOM: // Doesn't scroll to make the selection visible, or modify the kill ring. // ForwardDelete is not implemented in IE or Firefox, so this behavior is // only needed for backward compatibility with ourselves, and for @@ -1334,11 +1336,11 @@ EditorCommandSource source, const String&) { switch (source) { - case kCommandFromMenuOrKeyBinding: + case EditorCommandSource::kMenuOrKeyBinding: return TargetFrame(frame, event) ->GetEventHandler() .HandleTextInputEvent("\n", event, kTextEventInputLineBreak); - case kCommandFromDOM: + case EditorCommandSource::kDOM: // Doesn't scroll to make the selection visible, or modify the kill ring. // InsertLineBreak is not implemented in IE or Firefox, so this behavior // is only needed for backward compatibility with ourselves, and for @@ -2025,7 +2027,7 @@ } static bool CanReadClipboard(LocalFrame& frame, EditorCommandSource source) { - if (source == kCommandFromMenuOrKeyBinding) + if (source == EditorCommandSource::kMenuOrKeyBinding) return true; Settings* settings = frame.GetSettings(); bool default_value = settings && @@ -2130,7 +2132,7 @@ // before we obtain the selection. frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return; @@ -2140,7 +2142,7 @@ const PasteMode paste_mode = frame.GetEditor().CanEditRichly() ? kAllMimeTypes : kPlainTextOnly; - if (source == kCommandFromMenuOrKeyBinding) { + if (source == EditorCommandSource::kMenuOrKeyBinding) { DataTransfer* data_transfer = DataTransfer::Create(DataTransfer::kCopyAndPaste, kDataTransferReadable, DataObject::CreateFromPasteboard(paste_mode)); @@ -2191,7 +2193,7 @@ return false; if (!frame.GetEditor().Behavior().SupportsGlobalSelection()) return false; - DCHECK_EQ(source, kCommandFromMenuOrKeyBinding); + DCHECK_EQ(source, EditorCommandSource::kMenuOrKeyBinding); bool old_selection_mode = Pasteboard::GeneralPasteboard()->IsSelectionMode(); Pasteboard::GeneralPasteboard()->SetSelectionMode(true); @@ -2215,7 +2217,7 @@ // before we obtain the selection. frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return false; @@ -2304,9 +2306,10 @@ Event*, EditorCommandSource source, const String&) { - const SetSelectionBy set_selection_by = source == kCommandFromMenuOrKeyBinding - ? SetSelectionBy::kUser - : SetSelectionBy::kSystem; + const SetSelectionBy set_selection_by = + source == EditorCommandSource::kMenuOrKeyBinding + ? SetSelectionBy::kUser + : SetSelectionBy::kSystem; frame.Selection().SelectAll(set_selection_by); return true; } @@ -2635,7 +2638,7 @@ EditorCommandSource source) { frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return false; @@ -2652,7 +2655,7 @@ EditorCommandSource source) { frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return false; @@ -2668,7 +2671,7 @@ EditorCommandSource source) { frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return false; const VisibleSelection& selection = @@ -2692,7 +2695,7 @@ static bool EnabledCut(LocalFrame& frame, Event*, EditorCommandSource source) { if (!CanWriteClipboard(frame, source)) return false; - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return false; return !DispatchCopyOrCutEvent(frame, source, EventTypeNames::beforecut) || @@ -2703,7 +2706,7 @@ Event* event, EditorCommandSource source) { frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return false; const SelectionInDOMTree selection = @@ -2716,10 +2719,10 @@ Event* event, EditorCommandSource source) { switch (source) { - case kCommandFromMenuOrKeyBinding: + case EditorCommandSource::kMenuOrKeyBinding: return frame.Selection().SelectionHasFocus() && frame.GetEditor().CanDelete(); - case kCommandFromDOM: + case EditorCommandSource::kDOM: // "Delete" from DOM is like delete/backspace keypress, affects selected // range if non-empty, otherwise removes a character return EnabledInEditableText(frame, event, source); @@ -2732,7 +2735,7 @@ Event*, EditorCommandSource source) { frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return false; const VisibleSelection& selection = @@ -2746,7 +2749,7 @@ EditorCommandSource source) { if (!CanReadClipboard(frame, source)) return false; - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return false; return frame.GetEditor().CanPaste(); @@ -2756,7 +2759,7 @@ Event*, EditorCommandSource source) { frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return false; return frame.Selection() @@ -2771,7 +2774,7 @@ Event*, EditorCommandSource source) { frame.GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); - if (source == kCommandFromMenuOrKeyBinding && + if (source == EditorCommandSource::kMenuOrKeyBinding && !frame.Selection().SelectionHasFocus()) return false; const VisibleSelection& selection = @@ -2812,7 +2815,8 @@ return true; // Hidden selection appears as no selection to users, in which case user- // triggered SelectAll should be enabled and act as if there is no selection. - if (source == kCommandFromMenuOrKeyBinding && frame.Selection().IsHidden()) + if (source == EditorCommandSource::kMenuOrKeyBinding && + frame.Selection().IsHidden()) return true; if (Node* root = HighestEditableRoot(selection.Start())) { if (!root->hasChildren()) @@ -3471,8 +3475,8 @@ } Editor::Command Editor::CreateCommand(const String& command_name) { - return Command(InternalCommand(command_name), kCommandFromMenuOrKeyBinding, - frame_); + return Command(InternalCommand(command_name), + EditorCommandSource::kMenuOrKeyBinding, frame_); } Editor::Command Editor::CreateCommand(const String& command_name, @@ -3569,7 +3573,7 @@ return false; } - if (source_ == kCommandFromMenuOrKeyBinding) { + if (source_ == EditorCommandSource::kMenuOrKeyBinding) { InputEvent::InputType input_type = InputTypeFromCommandType(command_->command_type, *frame_); if (input_type != InputEvent::InputType::kNone) { @@ -3598,9 +3602,9 @@ if (!command_) return false; switch (source_) { - case kCommandFromMenuOrKeyBinding: + case EditorCommandSource::kMenuOrKeyBinding: return true; - case kCommandFromDOM: + case EditorCommandSource::kDOM: return command_->is_supported_from_dom(frame_.Get()); } NOTREACHED();
diff --git a/third_party/WebKit/Source/core/events/PointerEventFactory.cpp b/third_party/WebKit/Source/core/events/PointerEventFactory.cpp index 079816a..8258bb3 100644 --- a/third_party/WebKit/Source/core/events/PointerEventFactory.cpp +++ b/third_party/WebKit/Source/core/events/PointerEventFactory.cpp
@@ -241,9 +241,7 @@ if (type == EventTypeNames::pointermove) { HeapVector<Member<PointerEvent>> coalesced_pointer_events; for (const auto& coalesced_event : coalesced_events) { - // TODO(crbug.com/733774): Disabled the DCHECK on the id of the events - // because it failed on some versions of Mac OS. - // DCHECK_EQ(web_pointer_event.id, coalesced_event.id); + DCHECK_EQ(web_pointer_event.id, coalesced_event.id); DCHECK_EQ(web_pointer_event.GetType(), coalesced_event.GetType()); DCHECK_EQ(web_pointer_event.pointer_type, coalesced_event.pointer_type);
diff --git a/third_party/WebKit/Source/core/fetch/FetchManager.cpp b/third_party/WebKit/Source/core/fetch/FetchManager.cpp index 0cce3d0..da44386 100644 --- a/third_party/WebKit/Source/core/fetch/FetchManager.cpp +++ b/third_party/WebKit/Source/core/fetch/FetchManager.cpp
@@ -200,6 +200,7 @@ FetchManager::Loader* loader, String integrity_metadata, const KURL& url, + network::mojom::FetchResponseType response_type, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : handle_(std::move(handle)), updater_(updater), @@ -207,6 +208,7 @@ loader_(loader), integrity_metadata_(integrity_metadata), url_(url), + response_type_(response_type), finished_(false) { reader_ = handle_->ObtainReader(this, std::move(task_runner)); } @@ -239,11 +241,23 @@ finished_ = true; if (r == WebDataConsumerHandle::kDone) { SubresourceIntegrity::ReportInfo report_info; - bool check_result = SubresourceIntegrity::CheckSubresourceIntegrity( - integrity_metadata_, - SubresourceIntegrityHelper::GetFeatures( - loader_->GetExecutionContext()), - buffer_.data(), buffer_.size(), url_, report_info); + bool check_result = true; + if (response_type_ != network::mojom::FetchResponseType::kBasic && + response_type_ != network::mojom::FetchResponseType::kCORS && + response_type_ != network::mojom::FetchResponseType::kDefault) { + report_info.AddConsoleErrorMessage( + "Subresource Integrity: The resource '" + url_.ElidedString() + + "' has an integrity attribute, but the response is not " + "eligible for integrity validation."); + check_result = false; + } + if (check_result) { + check_result = SubresourceIntegrity::CheckSubresourceIntegrity( + integrity_metadata_, + SubresourceIntegrityHelper::GetFeatures( + loader_->GetExecutionContext()), + buffer_.data(), buffer_.size(), url_, report_info); + } SubresourceIntegrityHelper::DoReport(*loader_->GetExecutionContext(), report_info); if (check_result) { @@ -284,6 +298,7 @@ Member<FetchManager::Loader> loader_; String integrity_metadata_; KURL url_; + const network::mojom::FetchResponseType response_type_; std::unique_ptr<WebDataConsumerHandle::Reader> reader_; Vector<char> buffer_; bool finished_; @@ -521,7 +536,7 @@ DCHECK(!integrity_verifier_); integrity_verifier_ = new SRIVerifier( std::move(handle), sri_consumer, r, this, request_->Integrity(), - response.Url(), + response.Url(), r->GetResponse()->GetType(), resolver_->GetExecutionContext()->GetTaskRunner(TaskType::kNetworking)); } }
diff --git a/third_party/WebKit/Source/core/fetch/Request.cpp b/third_party/WebKit/Source/core/fetch/Request.cpp index b9f8b89..db3820d 100644 --- a/third_party/WebKit/Source/core/fetch/Request.cpp +++ b/third_party/WebKit/Source/core/fetch/Request.cpp
@@ -13,7 +13,6 @@ #include "core/fileapi/PublicURLManager.h" #include "core/loader/ThreadableLoader.h" #include "platform/bindings/V8PrivateProperty.h" -#include "platform/heap/Persistent.h" #include "platform/loader/cors/CORS.h" #include "platform/loader/fetch/FetchUtils.h" #include "platform/loader/fetch/ResourceLoaderOptions.h" @@ -23,7 +22,6 @@ #include "platform/runtime_enabled_features.h" #include "platform/weborigin/OriginAccessEntry.h" #include "platform/weborigin/Referrer.h" -#include "platform/wtf/Functional.h" #include "public/platform/WebURLRequest.h" #include "public/platform/modules/serviceworker/WebServiceWorkerRequest.h" @@ -375,17 +373,9 @@ // "Set |r|'s Headers object's guard to "request-no-cors"." r->getHeaders()->SetGuard(Headers::kRequestNoCORSGuard); } - // "If |signal| is not null, then add the following abort steps to signal: - // 1. Signal abort on r’s signal." - // TODO(ricea): Use the new "followingSignal ... is made to follow" algorithm - // that has been added to the DOM standard. + // "If |signal| is not null, then make |r|’s signal follow |signal|." if (signal) { - if (signal->aborted()) { - r->signal_->SignalAbort(); - } else { - signal->AddAlgorithm(WTF::Bind(&AbortSignal::SignalAbort, - WrapWeakPersistent(r->signal_.Get()))); - } + r->signal_->Follow(signal); } // "Fill |r|'s Headers object with |headers|. Rethrow any exceptions." if (!init.GetHeaders().IsNull()) { @@ -746,12 +736,7 @@ Headers* headers = Headers::Create(request->HeaderList()); headers->SetGuard(headers_->GetGuard()); auto* signal = new AbortSignal(ExecutionContext::From(script_state)); - if (signal_->aborted()) { - signal->SignalAbort(); - } else { - signal_->AddAlgorithm( - WTF::Bind(&AbortSignal::SignalAbort, WrapWeakPersistent(signal))); - } + signal->Follow(signal_); return new Request(script_state, request, headers, signal); }
diff --git a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp index 96321ed..d38674fb 100644 --- a/third_party/WebKit/Source/core/frame/LocalFrameView.cpp +++ b/third_party/WebKit/Source/core/frame/LocalFrameView.cpp
@@ -5459,6 +5459,8 @@ if (frame_->FrameScheduler()) { frame_->FrameScheduler()->SetFrameVisible(!hidden_for_throttling_); frame_->FrameScheduler()->SetCrossOrigin(frame_->IsCrossOriginSubframe()); + frame_->FrameScheduler()->TraceUrlChange( + frame_->GetDocument()->Url().GetString()); } #if DCHECK_IS_ON()
diff --git a/third_party/WebKit/Source/core/html/canvas/CanvasContextCreationAttributesCore.cpp b/third_party/WebKit/Source/core/html/canvas/CanvasContextCreationAttributesCore.cpp index 51827a4..b87d129 100644 --- a/third_party/WebKit/Source/core/html/canvas/CanvasContextCreationAttributesCore.cpp +++ b/third_party/WebKit/Source/core/html/canvas/CanvasContextCreationAttributesCore.cpp
@@ -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 "CanvasContextCreationAttributesCore.h" +#include "core/html/canvas/CanvasContextCreationAttributesCore.h" namespace blink {
diff --git a/third_party/WebKit/Source/core/loader/EmptyClients.cpp b/third_party/WebKit/Source/core/loader/EmptyClients.cpp index f4a685d..f7efa11 100644 --- a/third_party/WebKit/Source/core/loader/EmptyClients.cpp +++ b/third_party/WebKit/Source/core/loader/EmptyClients.cpp
@@ -80,6 +80,7 @@ void SetPaused(bool) override {} void SetCrossOrigin(bool) override {} bool IsCrossOrigin() const override { return false; } + void TraceUrlChange(const String&) override {} WebFrameScheduler::FrameType GetFrameType() const override { return WebFrameScheduler::FrameType::kSubframe; }
diff --git a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinatorContext.cpp b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinatorContext.cpp index 16ba650a..5e40697 100644 --- a/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinatorContext.cpp +++ b/third_party/WebKit/Source/core/page/scrolling/ScrollingCoordinatorContext.cpp
@@ -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 "ScrollingCoordinatorContext.h" +#include "core/page/scrolling/ScrollingCoordinatorContext.h" #include "core/paint/PaintLayer.h"
diff --git a/third_party/WebKit/Source/platform/WebFrameScheduler.h b/third_party/WebKit/Source/platform/WebFrameScheduler.h index b56a1a7..bd6cc93e 100644 --- a/third_party/WebKit/Source/platform/WebFrameScheduler.h +++ b/third_party/WebKit/Source/platform/WebFrameScheduler.h
@@ -7,6 +7,7 @@ #include "base/memory/scoped_refptr.h" #include "base/single_thread_task_runner.h" +#include "platform/wtf/text/WTFString.h" #include "public/platform/TaskType.h" #include "public/platform/WebScopedVirtualTimePauser.h" @@ -94,6 +95,7 @@ // frames. virtual void SetCrossOrigin(bool) = 0; virtual bool IsCrossOrigin() const = 0; + virtual void TraceUrlChange(const String&) = 0; // Returns the frame type, which currently determines whether this frame is // the top level frame, i.e. a main frame.
diff --git a/third_party/WebKit/Source/platform/bindings/ScriptWrappableMarkingVisitor.cpp b/third_party/WebKit/Source/platform/bindings/ScriptWrappableMarkingVisitor.cpp index df42b6c..e27a426 100644 --- a/third_party/WebKit/Source/platform/bindings/ScriptWrappableMarkingVisitor.cpp +++ b/third_party/WebKit/Source/platform/bindings/ScriptWrappableMarkingVisitor.cpp
@@ -254,8 +254,8 @@ void ScriptWrappableMarkingVisitor::Visit( const WrapperDescriptor& wrapper_descriptor) const { - HeapObjectHeader* header = - HeapObjectHeader::FromPayload(wrapper_descriptor.base_object_payload); + HeapObjectHeader* header = wrapper_descriptor.heap_object_header_callback( + wrapper_descriptor.traceable); if (header->IsWrapperHeaderMarked()) return; MarkWrapperHeader(header);
diff --git a/third_party/WebKit/Source/platform/bindings/ScriptWrappableMarkingVisitor.h b/third_party/WebKit/Source/platform/bindings/ScriptWrappableMarkingVisitor.h index 5f5b2293..fe437fc6 100644 --- a/third_party/WebKit/Source/platform/bindings/ScriptWrappableMarkingVisitor.h +++ b/third_party/WebKit/Source/platform/bindings/ScriptWrappableMarkingVisitor.h
@@ -66,8 +66,7 @@ return; // If the wrapper is already marked we can bail out here. - if (TraceTrait<T>::GetHeapObjectHeader(const_cast<T*>(dst_object)) - ->IsWrapperHeaderMarked()) + if (TraceTrait<T>::GetHeapObjectHeader(dst_object)->IsWrapperHeaderMarked()) return; CurrentVisitor(thread_state->GetIsolate()) @@ -110,17 +109,19 @@ class MarkingDequeItem { public: explicit MarkingDequeItem(const WrapperDescriptor& wrapper_descriptor) - : raw_object_pointer_(wrapper_descriptor.base_object_payload), - trace_wrappers_callback_(wrapper_descriptor.trace_wrappers_callback) { - DCHECK(raw_object_pointer_); + : trace_wrappers_callback_(wrapper_descriptor.trace_wrappers_callback), + heap_object_header_callback_( + wrapper_descriptor.heap_object_header_callback), + raw_object_pointer_(wrapper_descriptor.traceable) { DCHECK(trace_wrappers_callback_); + DCHECK(heap_object_header_callback_); + DCHECK(raw_object_pointer_); } // Traces wrappers if the underlying object has not yet been invalidated. inline void TraceWrappers(ScriptWrappableVisitor* visitor) const { if (raw_object_pointer_) { - trace_wrappers_callback_(visitor, - const_cast<void*>(raw_object_pointer_)); + trace_wrappers_callback_(visitor, raw_object_pointer_); } } @@ -138,11 +139,13 @@ private: inline const HeapObjectHeader* GetHeapObjectHeader() { - return HeapObjectHeader::FromPayload(raw_object_pointer_); + DCHECK(raw_object_pointer_); + return heap_object_header_callback_(raw_object_pointer_); } - const void* raw_object_pointer_; TraceWrappersCallback trace_wrappers_callback_; + HeapObjectHeaderCallback heap_object_header_callback_; + const void* raw_object_pointer_; }; void MarkWrapperHeader(HeapObjectHeader*) const;
diff --git a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h index 8a736a1..6335b21 100644 --- a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h +++ b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h
@@ -17,6 +17,7 @@ template <typename T> class DOMWrapperMap; +class HeapObjectHeader; class ScriptWrappable; class ScriptWrappableVisitor; template <typename T> @@ -26,17 +27,18 @@ template <typename T> class TraceWrapperV8Reference; +using HeapObjectHeaderCallback = HeapObjectHeader* (*)(const void*); using MissedWriteBarrierCallback = void (*)(); +using TraceWrappersCallback = void (*)(const ScriptWrappableVisitor*, + const void* self); using NameCallback = const char* (*)(const void* self); -#define DEFINE_TRAIT_FOR_TRACE_WRAPPERS(ClassName) \ - template <> \ - inline void TraceTrait<ClassName>::TraceWrappers( \ - ScriptWrappableVisitor* visitor, void* t) { \ - static_assert(sizeof(ClassName), "type needs to be defined"); \ - static_assert(IsGarbageCollectedType<ClassName>::value, \ - "only objects deriving from GarbageCollected can be used"); \ - static_cast<ClassName*>(t)->TraceWrappers(visitor); \ +#define DEFINE_TRAIT_FOR_TRACE_WRAPPERS(ClassName) \ + template <> \ + inline void TraceTrait<ClassName>::TraceMarkedWrapper( \ + const ScriptWrappableVisitor* visitor, const void* t) { \ + const ClassName* traceable = ToWrapperTracingType(t); \ + traceable->TraceWrappers(visitor); \ } // WrapperDescriptor contains enough information to visit a @@ -44,8 +46,9 @@ // It is passed to ScriptWrappableVisitor::Visit method. struct WrapperDescriptor { STACK_ALLOCATED(); - const void* base_object_payload; + const void* traceable; TraceWrappersCallback trace_wrappers_callback; + HeapObjectHeaderCallback heap_object_header_callback; MissedWriteBarrierCallback missed_write_barrier_callback; NameCallback name_callback; }; @@ -122,9 +125,8 @@ template <typename T> static WrapperDescriptor WrapperDescriptorFor(const T* traceable) { - TraceWrapperDescriptor desc = - TraceTrait<T>::GetTraceWrapperDescriptor(const_cast<T*>(traceable)); - return {desc.base_object_payload, desc.callback, + return {traceable, TraceTrait<T>::TraceMarkedWrapper, + TraceTrait<T>::GetHeapObjectHeader, ScriptWrappableVisitor::MissedWriteBarrier<T>, ScriptWrappableVisitor::NameCallback<T>}; } @@ -146,7 +148,6 @@ template <typename T> static const char* NameCallback(const void* traceable) { - // Mixns never inherit from TraceWrapperBase. return NameInHeapSnapshot(static_cast<const T*>(traceable)); }
diff --git a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitorVerifier.h b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitorVerifier.h index 05d926f..5d198a41 100644 --- a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitorVerifier.h +++ b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitorVerifier.h
@@ -16,8 +16,9 @@ protected: void Visit(const TraceWrapperV8Reference<v8::Value>&) const final {} void Visit(const WrapperDescriptor& wrapper_descriptor) const final { - if (!HeapObjectHeader::FromPayload(wrapper_descriptor.base_object_payload) - ->IsWrapperHeaderMarked()) { + HeapObjectHeader* header = wrapper_descriptor.heap_object_header_callback( + wrapper_descriptor.traceable); + if (!header->IsWrapperHeaderMarked()) { // If this branch is hit, it means that a white (not discovered by // traceWrappers) object was assigned as a member to a black object // (already processed by traceWrappers). Black object will not be
diff --git a/third_party/WebKit/Source/platform/blob/BlobBytesProviderTest.cpp b/third_party/WebKit/Source/platform/blob/BlobBytesProviderTest.cpp index e369c77..2b811090 100644 --- a/third_party/WebKit/Source/platform/blob/BlobBytesProviderTest.cpp +++ b/third_party/WebKit/Source/platform/blob/BlobBytesProviderTest.cpp
@@ -78,9 +78,9 @@ auto provider = std::make_unique<BlobBytesProvider>(test_data1_); Vector<uint8_t> received_bytes; provider->RequestAsReply( - base::Bind([](Vector<uint8_t>* bytes_out, - const Vector<uint8_t>& bytes) { *bytes_out = bytes; }, - &received_bytes)); + base::BindOnce([](Vector<uint8_t>* bytes_out, + const Vector<uint8_t>& bytes) { *bytes_out = bytes; }, + &received_bytes)); EXPECT_EQ(test_bytes1_, received_bytes); received_bytes.clear(); @@ -88,9 +88,9 @@ provider->AppendData(test_data2_); provider->AppendData(test_data3_); provider->RequestAsReply( - base::Bind([](Vector<uint8_t>* bytes_out, - const Vector<uint8_t>& bytes) { *bytes_out = bytes; }, - &received_bytes)); + base::BindOnce([](Vector<uint8_t>* bytes_out, + const Vector<uint8_t>& bytes) { *bytes_out = bytes; }, + &received_bytes)); EXPECT_EQ(combined_bytes_, received_bytes); } @@ -129,7 +129,7 @@ source_offset, source_length, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), file_offset, - base::Bind( + base::BindOnce( [](WTF::Optional<WTF::Time>* received_modified, WTF::Optional<WTF::Time> modified) { *received_modified = modified; @@ -206,7 +206,7 @@ test_provider_->RequestAsFile( test.offset, test.size, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), - file_offset, base::Bind([](WTF::Optional<WTF::Time> last_modified) { + file_offset, base::BindOnce([](WTF::Optional<WTF::Time> last_modified) { EXPECT_TRUE(last_modified); })); @@ -252,7 +252,7 @@ provider->RequestAsFile( i, 16, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_WRITE), combined_bytes_.size() - i - 16, - base::Bind([](WTF::Optional<WTF::Time> last_modified) { + base::BindOnce([](WTF::Optional<WTF::Time> last_modified) { EXPECT_TRUE(last_modified); })); expected_data.insert(0, combined_bytes_.data() + i, 16); @@ -276,7 +276,7 @@ provider->RequestAsFile( 0, 16, base::File(), 0, - base::Bind([](WTF::Optional<WTF::Time> last_modified) { + base::BindOnce([](WTF::Optional<WTF::Time> last_modified) { EXPECT_FALSE(last_modified); })); } @@ -288,7 +288,7 @@ base::CreateTemporaryFile(&path); provider->RequestAsFile( 0, 16, base::File(path, base::File::FLAG_OPEN | base::File::FLAG_READ), 0, - base::Bind([](WTF::Optional<WTF::Time> last_modified) { + base::BindOnce([](WTF::Optional<WTF::Time> last_modified) { EXPECT_FALSE(last_modified); })); @@ -313,7 +313,7 @@ mojo::SimpleWatcher::ArmingPolicy::AUTOMATIC); watcher.Watch( pipe.consumer_handle.get(), MOJO_HANDLE_SIGNAL_READABLE, - base::Bind( + base::BindRepeating( [](mojo::DataPipeConsumerHandle pipe, base::Closure quit_closure, Vector<uint8_t>* bytes_out, MojoResult result) { if (result == MOJO_RESULT_CANCELLED ||
diff --git a/third_party/WebKit/Source/platform/blob/BlobDataTest.cpp b/third_party/WebKit/Source/platform/blob/BlobDataTest.cpp index a0ce583..3c6e24a 100644 --- a/third_party/WebKit/Source/platform/blob/BlobDataTest.cpp +++ b/third_party/WebKit/Source/platform/blob/BlobDataTest.cpp
@@ -159,7 +159,7 @@ Vector<uint8_t> received_bytes; mojom::blink::BytesProviderPtr data( std::move(actual->get_bytes()->data)); - data->RequestAsReply(base::Bind( + data->RequestAsReply(base::BindOnce( [](base::Closure quit_closure, Vector<uint8_t>* bytes_out, const Vector<uint8_t>& bytes) { *bytes_out = bytes; @@ -196,7 +196,7 @@ base::RunLoop loop; String received_uuid; mojom::blink::BlobPtr blob(std::move(actual->get_blob()->blob)); - blob->GetInternalUUID(base::Bind( + blob->GetInternalUUID(base::BindOnce( [](base::Closure quit_closure, String* uuid_out, const String& uuid) { *uuid_out = uuid;
diff --git a/third_party/WebKit/Source/platform/fonts/FontMetrics.cpp b/third_party/WebKit/Source/platform/fonts/FontMetrics.cpp index 3b94970e..cd202ee 100644 --- a/third_party/WebKit/Source/platform/fonts/FontMetrics.cpp +++ b/third_party/WebKit/Source/platform/fonts/FontMetrics.cpp
@@ -27,7 +27,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "FontMetrics.h" +#include "platform/fonts/FontMetrics.h" #include "build/build_config.h" #include "platform/fonts/FontPlatformData.h"
diff --git a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp index 9048e5d..8c9e85a1 100644 --- a/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp +++ b/third_party/WebKit/Source/platform/graphics/compositing/PaintArtifactCompositor.cpp
@@ -193,8 +193,8 @@ // does not scroll. scroll_layer->SetBounds(bounds); scroll_layer->set_did_scroll_callback( - base::Bind(&blink::WebLayerScrollClient::DidScroll, - base::Unretained(&scroll_client_))); + base::BindRepeating(&blink::WebLayerScrollClient::DidScroll, + base::Unretained(&scroll_client_))); return scroll_layer; }
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.cpp b/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.cpp index 26be6ae..4347e22d 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.cpp +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.cpp
@@ -13,11 +13,17 @@ namespace { +// Returns -1 if |maybe_ancestor| is found in the ancestor chain, or returns +// the depth of the node from the root. template <typename NodeType> -unsigned NodeDepth(const NodeType& node) { - unsigned depth = 0; - for (const NodeType* n = &node; n; n = n->Parent()) +int NodeDepthOrFoundAncestor(const NodeType& node, + const NodeType& maybe_ancestor) { + int depth = 0; + for (const NodeType* n = &node; n; n = n->Parent()) { + if (n == &maybe_ancestor) + return -1; depth++; + } return depth; } @@ -25,8 +31,12 @@ const NodeType& LowestCommonAncestorTemplate(const NodeType& a, const NodeType& b) { // Measure both depths. - unsigned depth_a = NodeDepth(a); - unsigned depth_b = NodeDepth(b); + auto depth_a = NodeDepthOrFoundAncestor(a, b); + if (depth_a == -1) + return b; + auto depth_b = NodeDepthOrFoundAncestor(b, a); + if (depth_b == -1) + return a; const auto* a_ptr = &a; const auto* b_ptr = &b; @@ -56,25 +66,25 @@ } // namespace -const TransformPaintPropertyNode& LowestCommonAncestor( +const TransformPaintPropertyNode& LowestCommonAncestorInternal( const TransformPaintPropertyNode& a, const TransformPaintPropertyNode& b) { return LowestCommonAncestorTemplate(a, b); } -const ClipPaintPropertyNode& LowestCommonAncestor( +const ClipPaintPropertyNode& LowestCommonAncestorInternal( const ClipPaintPropertyNode& a, const ClipPaintPropertyNode& b) { return LowestCommonAncestorTemplate(a, b); } -const EffectPaintPropertyNode& LowestCommonAncestor( +const EffectPaintPropertyNode& LowestCommonAncestorInternal( const EffectPaintPropertyNode& a, const EffectPaintPropertyNode& b) { return LowestCommonAncestorTemplate(a, b); } -const ScrollPaintPropertyNode& LowestCommonAncestor( +const ScrollPaintPropertyNode& LowestCommonAncestorInternal( const ScrollPaintPropertyNode& a, const ScrollPaintPropertyNode& b) { return LowestCommonAncestorTemplate(a, b);
diff --git a/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.h b/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.h index 9c0fd65a..1d04571 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.h +++ b/third_party/WebKit/Source/platform/graphics/paint/PaintPropertyNode.h
@@ -24,16 +24,31 @@ class TransformPaintPropertyNode; // Returns the lowest common ancestor in the paint property tree. -PLATFORM_EXPORT const ClipPaintPropertyNode& LowestCommonAncestor( +template <typename NodeType> +const NodeType& LowestCommonAncestor(const NodeType& a, const NodeType& b) { + // Fast path of common cases. + if (&a == &b || !a.Parent() || b.Parent() == &a) { + DCHECK(a.IsAncestorOf(b)); + return a; + } + if (!b.Parent() || a.Parent() == &b) { + DCHECK(b.IsAncestorOf(a)); + return b; + } + + return LowestCommonAncestorInternal(a, b); +} + +PLATFORM_EXPORT const ClipPaintPropertyNode& LowestCommonAncestorInternal( const ClipPaintPropertyNode&, const ClipPaintPropertyNode&); -PLATFORM_EXPORT const EffectPaintPropertyNode& LowestCommonAncestor( +PLATFORM_EXPORT const EffectPaintPropertyNode& LowestCommonAncestorInternal( const EffectPaintPropertyNode&, const EffectPaintPropertyNode&); -PLATFORM_EXPORT const ScrollPaintPropertyNode& LowestCommonAncestor( +PLATFORM_EXPORT const ScrollPaintPropertyNode& LowestCommonAncestorInternal( const ScrollPaintPropertyNode&, const ScrollPaintPropertyNode&); -PLATFORM_EXPORT const TransformPaintPropertyNode& LowestCommonAncestor( +PLATFORM_EXPORT const TransformPaintPropertyNode& LowestCommonAncestorInternal( const TransformPaintPropertyNode&, const TransformPaintPropertyNode&);
diff --git a/third_party/WebKit/Source/platform/heap/BlinkGC.h b/third_party/WebKit/Source/platform/heap/BlinkGC.h index 3034a01..cee5c09b3 100644 --- a/third_party/WebKit/Source/platform/heap/BlinkGC.h +++ b/third_party/WebKit/Source/platform/heap/BlinkGC.h
@@ -16,7 +16,6 @@ class MarkingVisitor; class Visitor; -class ScriptWrappableVisitor; using Address = uint8_t*; @@ -24,7 +23,6 @@ using VisitorCallback = void (*)(Visitor*, void*); using MarkingVisitorCallback = void (*)(MarkingVisitor*, void*); using TraceCallback = VisitorCallback; -using TraceWrappersCallback = void (*)(ScriptWrappableVisitor*, void*); using WeakCallback = VisitorCallback; using EphemeronCallback = VisitorCallback;
diff --git a/third_party/WebKit/Source/platform/heap/GarbageCollected.h b/third_party/WebKit/Source/platform/heap/GarbageCollected.h index 6dc9902..21fcf87 100644 --- a/third_party/WebKit/Source/platform/heap/GarbageCollected.h +++ b/third_party/WebKit/Source/platform/heap/GarbageCollected.h
@@ -16,6 +16,7 @@ template <typename T> class GarbageCollected; class HeapObjectHeader; +class ScriptWrappableVisitor; // GC_PLUGIN_IGNORE is used to make the plugin ignore a particular class or // field when checking for proper usage. When using GC_PLUGIN_IGNORE @@ -53,11 +54,6 @@ bool can_trace_eagerly; }; -struct TraceWrapperDescriptor { - void* base_object_payload; - TraceWrappersCallback callback; -}; - // The GarbageCollectedMixin interface and helper macro // USING_GARBAGE_COLLECTED_MIXIN can be used to automatically define // TraceTrait/ObjectAliveTrait on non-leftmost deriving classes @@ -75,39 +71,43 @@ // }; // // With the helper, as long as we are using Member<B>, TypeTrait<B> will -// dispatch dynamically to retrieve the necessary tracing and header methods. +// dispatch adjustAndMark dynamically to find collect addr of the object header. // Note that this is only enabled for Member<B>. For Member<A> which we can -// compute the necessary methods and pointers statically and this dynamic -// dispatch is not used. +// compute the object header addr statically, this dynamic dispatch is not used. +// class PLATFORM_EXPORT GarbageCollectedMixin { public: typedef int IsGarbageCollectedMixinMarker; virtual void Trace(Visitor*) {} - virtual HeapObjectHeader* GetHeapObjectHeader() const = 0; virtual TraceDescriptor GetTraceDescriptor() const = 0; - virtual TraceWrapperDescriptor GetTraceWrapperDescriptor() const = 0; + virtual HeapObjectHeader* GetHeapObjectHeader() const = 0; + virtual void AdjustAndTraceMarkedWrapper( + const ScriptWrappableVisitor*) const = 0; }; -#define DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(TYPE) \ - public: \ - HeapObjectHeader* GetHeapObjectHeader() const override { \ - static_assert( \ - WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type, \ - blink::GarbageCollected>::value, \ - "only garbage collected objects can have garbage collected mixins"); \ - return HeapObjectHeader::FromPayload(static_cast<const TYPE*>(this)); \ - } \ - \ - TraceDescriptor GetTraceDescriptor() const override { \ - return {const_cast<TYPE*>(static_cast<const TYPE*>(this)), \ - TraceTrait<TYPE>::Trace, TraceEagerlyTrait<TYPE>::value}; \ - } \ - \ - TraceWrapperDescriptor GetTraceWrapperDescriptor() const override { \ - return {const_cast<TYPE*>(static_cast<const TYPE*>(this)), \ - TraceTrait<TYPE>::TraceWrappers}; \ - } \ - \ +#define DEFINE_GARBAGE_COLLECTED_MIXIN_METHODS(TYPE) \ + public: \ + TraceDescriptor GetTraceDescriptor() const override { \ + typedef WTF::IsSubclassOfTemplate<typename std::remove_const<TYPE>::type, \ + blink::GarbageCollected> \ + IsSubclassOfGarbageCollected; \ + static_assert( \ + IsSubclassOfGarbageCollected::value, \ + "only garbage collected objects can have garbage collected mixins"); \ + return {const_cast<TYPE*>(static_cast<const TYPE*>(this)), \ + TraceTrait<TYPE>::Trace, TraceEagerlyTrait<TYPE>::value}; \ + } \ + \ + void AdjustAndTraceMarkedWrapper(const ScriptWrappableVisitor* visitor) \ + const override { \ + const TYPE* base = static_cast<const TYPE*>(this); \ + TraceTrait<TYPE>::TraceMarkedWrapper(visitor, base); \ + } \ + \ + HeapObjectHeader* GetHeapObjectHeader() const override { \ + return HeapObjectHeader::FromPayload(static_cast<const TYPE*>(this)); \ + } \ + \ private: // A C++ object's vptr will be initialized to its leftmost base's vtable after @@ -212,13 +212,14 @@ // // ambiguous. USING_GARBAGE_COLLECTED_MIXIN(TYPE) overrides them later // // and provides the implementations. // }; -#define MERGE_GARBAGE_COLLECTED_MIXINS() \ - public: \ - HeapObjectHeader* GetHeapObjectHeader() const override = 0; \ - TraceDescriptor GetTraceDescriptor() const override = 0; \ - TraceWrapperDescriptor GetTraceWrapperDescriptor() const override = 0; \ - \ - private: \ +#define MERGE_GARBAGE_COLLECTED_MIXINS() \ + public: \ + TraceDescriptor GetTraceDescriptor() const override = 0; \ + HeapObjectHeader* GetHeapObjectHeader() const override = 0; \ + void AdjustAndTraceMarkedWrapper(const ScriptWrappableVisitor*) \ + const override = 0; \ + \ + private: \ using merge_garbage_collected_mixins_requires_semicolon = void // Base class for objects allocated in the Blink garbage-collected heap.
diff --git a/third_party/WebKit/Source/platform/heap/HeapAllocator.h b/third_party/WebKit/Source/platform/heap/HeapAllocator.h index 85b3488..1467adb 100644 --- a/third_party/WebKit/Source/platform/heap/HeapAllocator.h +++ b/third_party/WebKit/Source/platform/heap/HeapAllocator.h
@@ -181,12 +181,6 @@ } template <typename VisitorDispatcher> - static void RegisterDelayedMarkNoTracing(VisitorDispatcher visitor, - const void* object) { - visitor->RegisterDelayedMarkNoTracing(object); - } - - template <typename VisitorDispatcher> static void RegisterWeakMembers(VisitorDispatcher visitor, const void* closure, WeakCallback callback) { @@ -211,12 +205,6 @@ #endif template <typename T, typename VisitorDispatcher> - static void RegisterBackingStoreReference(VisitorDispatcher visitor, - T** slot) { - visitor->RegisterBackingStoreReference(slot); - } - - template <typename T, typename VisitorDispatcher> static void RegisterBackingStoreCallback(VisitorDispatcher visitor, T* backing_store, MovingObjectCallback callback, @@ -282,22 +270,31 @@ #endif // BUILDFLAG(BLINK_HEAP_INCREMENTAL_MARKING) } - template <typename T, typename VisitorDispatcher> - static void TraceVectorBacking(VisitorDispatcher visitor, + template <typename T> + static void TraceVectorBacking(Visitor* visitor, T* backing, T** backing_slot) { - HeapVectorBacking<T>* vector_backing = - reinterpret_cast<HeapVectorBacking<T>*>(backing); - visitor->RegisterBackingStoreReference(backing_slot); - visitor->Trace(vector_backing); + visitor->TraceBackingStoreStrongly( + reinterpret_cast<HeapVectorBacking<T>*>(backing), + reinterpret_cast<HeapVectorBacking<T>**>(backing_slot)); } - template <typename T, typename HashTable, typename VisitorDispatcher> - static void TraceHashTableBacking(VisitorDispatcher visitor, T* backing) { - HeapHashTableBacking<HashTable>* hashtable_backing = - reinterpret_cast<HeapHashTableBacking<HashTable>*>(backing); - // Backing store reference is registered by the caller. - visitor->Trace(hashtable_backing); + template <typename T, typename HashTable> + static void TraceHashTableBackingStrongly(Visitor* visitor, + T* backing, + T** backing_slot) { + visitor->TraceBackingStoreStrongly( + reinterpret_cast<HeapHashTableBacking<HashTable>*>(backing), + reinterpret_cast<HeapHashTableBacking<HashTable>**>(backing_slot)); + } + + template <typename T, typename HashTable> + static void TraceHashTableBackingWeakly(Visitor* visitor, + T* backing, + T** backing_slot) { + visitor->TraceBackingStoreWeakly( + reinterpret_cast<HeapHashTableBacking<HashTable>*>(backing), + reinterpret_cast<HeapHashTableBacking<HashTable>**>(backing_slot)); } private:
diff --git a/third_party/WebKit/Source/platform/heap/MarkingVerifier.h b/third_party/WebKit/Source/platform/heap/MarkingVerifier.h index 25a43e2..1c20563 100644 --- a/third_party/WebKit/Source/platform/heap/MarkingVerifier.h +++ b/third_party/WebKit/Source/platform/heap/MarkingVerifier.h
@@ -49,11 +49,15 @@ } // Unused overrides. - void RegisterBackingStoreReference(void* slot) final {} + void VisitBackingStoreStrongly(void* object, + void** object_slot, + TraceDescriptor desc) final {} + void VisitBackingStoreWeakly(void* object, + void** object_slot, + TraceDescriptor desc) final {} void RegisterBackingStoreCallback(void* backing_store, MovingObjectCallback, void* callback_data) final {} - void RegisterDelayedMarkNoTracing(const void* pointer) final {} void RegisterWeakCallback(void* closure, WeakCallback) final {} private:
diff --git a/third_party/WebKit/Source/platform/heap/MarkingVisitor.h b/third_party/WebKit/Source/platform/heap/MarkingVisitor.h index 9c07fe7..7d2b146 100644 --- a/third_party/WebKit/Source/platform/heap/MarkingVisitor.h +++ b/third_party/WebKit/Source/platform/heap/MarkingVisitor.h
@@ -96,11 +96,30 @@ Mark(desc.base_object_payload, desc.callback); } - void RegisterBackingStoreReference(void* slot) final; + void VisitBackingStoreStrongly(void* object, + void** object_slot, + TraceDescriptor desc) final { + RegisterBackingStoreReference(object_slot); + Visit(object, desc); + } + + // Used to delay the marking of objects until the usual marking including + // ephemeron iteration is done. This is used to delay the marking of + // collection backing stores until we know if they are reachable from + // locations other than the collection front object. If collection backings + // are reachable from other locations we strongify them to avoid issues with + // iterators and weak processing. + void VisitBackingStoreWeakly(void* object, + void** object_slot, + TraceDescriptor desc) final { + DCHECK(GetMarkingMode() != kWeakProcessing); + RegisterBackingStoreReference(object_slot); + Heap().PushPostMarkingCallback(object, &MarkNoTracingCallback); + } + void RegisterBackingStoreCallback(void* backing_store, MovingObjectCallback, void* callback_data) final; - void RegisterDelayedMarkNoTracing(const void* pointer) final; bool RegisterWeakTable(const void* closure, EphemeronCallback iteration_callback, EphemeronCallback iteration_done_callback) final; @@ -112,6 +131,8 @@ private: static void MarkNoTracingCallback(Visitor*, void*); + void RegisterBackingStoreReference(void* slot); + const MarkingMode marking_mode_; }; @@ -148,13 +169,6 @@ MarkHeader(header, reinterpret_cast<TraceCallback>(0)); } -inline void MarkingVisitor::RegisterDelayedMarkNoTracing( - const void* object_pointer) { - DCHECK(GetMarkingMode() != kWeakProcessing); - Heap().PushPostMarkingCallback(const_cast<void*>(object_pointer), - &MarkNoTracingCallback); -} - inline bool MarkingVisitor::EnsureMarked(const void* object_pointer) { if (!object_pointer) return false;
diff --git a/third_party/WebKit/Source/platform/heap/TraceTraits.h b/third_party/WebKit/Source/platform/heap/TraceTraits.h index 10ab493..85590c9 100644 --- a/third_party/WebKit/Source/platform/heap/TraceTraits.h +++ b/third_party/WebKit/Source/platform/heap/TraceTraits.h
@@ -54,16 +54,20 @@ return {self, TraceTrait<T>::Trace, TraceEagerlyTrait<T>::value}; } - static TraceWrapperDescriptor GetTraceWrapperDescriptor(void* self) { - return {self, TraceTrait<T>::TraceWrappers}; - } - - static HeapObjectHeader* GetHeapObjectHeader(void* self) { + static HeapObjectHeader* GetHeapObjectHeader(const T* self) { #if DCHECK_IS_ON() HeapObjectHeader::CheckFromPayload(self); #endif return HeapObjectHeader::FromPayload(self); } + + static void TraceMarkedWrapper(const ScriptWrappableVisitor* visitor, + const T* self) { + // The term *mark* is misleading here as we effectively trace through the + // API boundary, i.e., tell V8 that an object is alive. Actual marking + // will be done in V8. + visitor->DispatchTraceWrappers(self); + } }; template <typename T> @@ -71,19 +75,18 @@ STATIC_ONLY(AdjustAndMarkTrait); public: - static TraceDescriptor GetTraceDescriptor(const T* self) { + static HeapObjectHeader* GetHeapObjectHeader(const T* self) { + return self->GetHeapObjectHeader(); + } + + static TraceDescriptor GetTraceDescriptor(T* self) { DCHECK(self); return self->GetTraceDescriptor(); } - static TraceWrapperDescriptor GetTraceWrapperDescriptor(const T* self) { - DCHECK(self); - return self->GetTraceWrapperDescriptor(); - } - - static HeapObjectHeader* GetHeapObjectHeader(const T* self) { - DCHECK(self); - return self->GetHeapObjectHeader(); + static void TraceMarkedWrapper(const ScriptWrappableVisitor* visitor, + const T* self) { + self->AdjustAndTraceMarkedWrapper(visitor); } }; @@ -170,11 +173,10 @@ } }; -// The TraceTrait is used to specify how to trace and object for Oilpan and -// wrapper tracing. +// The TraceTrait is used to specify how to mark an object pointer and +// how to trace all of the pointers in the object. // -// -// By default, the 'Trace' method implemented on an object itself is +// By default, the 'trace' method implemented on an object itself is // used to trace the pointers to other heap objects inside the object. // // However, the TraceTrait can be specialized to use a different @@ -191,17 +193,17 @@ return AdjustAndMarkTrait<T>::GetTraceDescriptor(static_cast<T*>(self)); } - static TraceWrapperDescriptor GetTraceWrapperDescriptor(void* self) { - return AdjustAndMarkTrait<T>::GetTraceWrapperDescriptor( - static_cast<T*>(self)); - } - - static HeapObjectHeader* GetHeapObjectHeader(void* self) { - return AdjustAndMarkTrait<T>::GetHeapObjectHeader(static_cast<T*>(self)); - } - static void Trace(Visitor*, void* self); - static void TraceWrappers(ScriptWrappableVisitor*, void*); + static void TraceMarkedWrapper(const ScriptWrappableVisitor*, const void*); + static HeapObjectHeader* GetHeapObjectHeader(const void*); + + private: + static const T* ToWrapperTracingType(const void* t) { + static_assert(sizeof(T), "type needs to be defined"); + static_assert(IsGarbageCollectedType<T>::value, + "only objects deriving from GarbageCollected can be used"); + return reinterpret_cast<const T*>(t); + } }; template <typename T> @@ -214,13 +216,16 @@ } template <typename T> -void TraceTrait<T>::TraceWrappers(ScriptWrappableVisitor* visitor, void* self) { - static_assert(sizeof(T), "type needs to be defined"); - static_assert(IsGarbageCollectedType<T>::value, - "only objects deriving from GarbageCollected can be used"); - visitor->DispatchTraceWrappers(static_cast<T*>(self)); +void TraceTrait<T>::TraceMarkedWrapper(const ScriptWrappableVisitor* visitor, + const void* t) { + const T* traceable = ToWrapperTracingType(t); + AdjustAndMarkTrait<T>::TraceMarkedWrapper(visitor, traceable); } +template <typename T> +HeapObjectHeader* TraceTrait<T>::GetHeapObjectHeader(const void* t) { + return AdjustAndMarkTrait<T>::GetHeapObjectHeader(ToWrapperTracingType(t)); +} template <typename T, typename Traits> struct TraceTrait<HeapVectorBacking<T, Traits>> {
diff --git a/third_party/WebKit/Source/platform/heap/Visitor.h b/third_party/WebKit/Source/platform/heap/Visitor.h index 5e21119a..79e1d81 100644 --- a/third_party/WebKit/Source/platform/heap/Visitor.h +++ b/third_party/WebKit/Source/platform/heap/Visitor.h
@@ -113,6 +113,34 @@ const_cast<void*>(reinterpret_cast<const void*>(t)))); } + template <typename T> + void TraceBackingStoreStrongly(T* backing_store, T** backing_store_slot) { + static_assert(sizeof(T), "T must be fully defined"); + static_assert(IsGarbageCollectedType<T>::value, + "T needs to be a garbage collected object"); + + if (!backing_store) + return; + VisitBackingStoreStrongly(reinterpret_cast<void*>(backing_store), + reinterpret_cast<void**>(backing_store_slot), + TraceTrait<T>::GetTraceDescriptor( + reinterpret_cast<void*>(backing_store))); + } + + template <typename T> + void TraceBackingStoreWeakly(T* backing_store, T** backing_store_slot) { + static_assert(sizeof(T), "T must be fully defined"); + static_assert(IsGarbageCollectedType<T>::value, + "T needs to be a garbage collected object"); + + if (!backing_store) + return; + VisitBackingStoreWeakly(reinterpret_cast<void*>(backing_store), + reinterpret_cast<void**>(backing_store_slot), + TraceTrait<T>::GetTraceDescriptor( + reinterpret_cast<void*>(backing_store))); + } + // WeakMember version of the templated trace method. It doesn't keep // the traced thing alive, but will write null to the WeakMember later // if the pointed-to object is dead. It's lying for this to be const, @@ -174,21 +202,16 @@ // Visits an object through a strong reference. virtual void Visit(void*, TraceDescriptor) = 0; + // Visitors for collection backing stores. + virtual void VisitBackingStoreStrongly(void*, void**, TraceDescriptor) = 0; + virtual void VisitBackingStoreWeakly(void*, void**, TraceDescriptor) = 0; + // Registers backing store pointers so that they can be moved and properly // updated. - virtual void RegisterBackingStoreReference(void* slot) = 0; virtual void RegisterBackingStoreCallback(void* backing_store, MovingObjectCallback, void* callback_data) = 0; - // Used to delay the marking of objects until the usual marking including - // ephemeron iteration is done. This is used to delay the marking of - // collection backing stores until we know if they are reachable from - // locations other than the collection front object. If collection backings - // are reachable from other locations we strongify them to avoid issues with - // iterators and weak processing. - virtual void RegisterDelayedMarkNoTracing(const void* pointer) = 0; - // Used to register ephemeron callbacks. virtual bool RegisterWeakTable(const void* closure, EphemeronCallback iteration_callback,
diff --git a/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.h b/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.h index 044bba4..bff877d0 100644 --- a/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.h +++ b/third_party/WebKit/Source/platform/loader/SubresourceIntegrity.h
@@ -21,7 +21,7 @@ STATIC_ONLY(SubresourceIntegrity); public: - class ReportInfo final { + class PLATFORM_EXPORT ReportInfo final { public: enum class UseCounterFeature { kSRIElementWithMatchingIntegrityAttribute,
diff --git a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp index 85a3773a..11fca26 100644 --- a/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp +++ b/third_party/WebKit/Source/platform/loader/fetch/BufferingDataPipeWriter.cpp
@@ -19,10 +19,10 @@ base::SingleThreadTaskRunner* runner) : handle_(std::move(handle)), watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, runner) { - watcher_.Watch( - handle_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, - MOJO_WATCH_CONDITION_SATISFIED, - base::Bind(&BufferingDataPipeWriter::OnWritable, base::Unretained(this))); + watcher_.Watch(handle_.get(), MOJO_HANDLE_SIGNAL_WRITABLE, + MOJO_WATCH_CONDITION_SATISFIED, + base::BindRepeating(&BufferingDataPipeWriter::OnWritable, + base::Unretained(this))); } bool BufferingDataPipeWriter::Write(const char* buffer, uint32_t num_bytes) {
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5 index 4e20e9d..7b3ff5f 100644 --- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 +++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -292,6 +292,10 @@ status: "experimental", }, { + name: "CSSPartPseudoElement", + status: "test", + }, + { name: "CSSScrollSnapPoints", status: "experimental", },
diff --git a/third_party/WebKit/Source/platform/scheduler/BUILD.gn b/third_party/WebKit/Source/platform/scheduler/BUILD.gn index 5ac1b18d..1199be55 100644 --- a/third_party/WebKit/Source/platform/scheduler/BUILD.gn +++ b/third_party/WebKit/Source/platform/scheduler/BUILD.gn
@@ -17,7 +17,7 @@ "base/moveable_auto_lock.h", "base/real_time_domain.cc", "base/real_time_domain.h", - "base/sequence.h", + "base/sequenced_task_source.h", "base/task_queue.cc", "base/task_queue.h", "base/task_queue_impl.cc",
diff --git a/third_party/WebKit/Source/platform/scheduler/base/sequence.h b/third_party/WebKit/Source/platform/scheduler/base/sequenced_task_source.h similarity index 92% rename from third_party/WebKit/Source/platform/scheduler/base/sequence.h rename to third_party/WebKit/Source/platform/scheduler/base/sequenced_task_source.h index afe219d..c41bfb1 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/sequence.h +++ b/third_party/WebKit/Source/platform/scheduler/base/sequenced_task_source.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 THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_SEQUENCE_H_ -#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_SEQUENCE_H_ +#ifndef THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_SEQUENCED_TASK_SOURCE_H_ +#define THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_SEQUENCED_TASK_SOURCE_H_ #include "base/optional.h" #include "base/pending_task.h" @@ -16,8 +16,7 @@ // This is temporary interface for ThreadController to be able to run tasks // from TaskQueueManager. -// TODO(alexclarke): Rename to SequencedTaskSource. -class Sequence { +class SequencedTaskSource { public: // TODO(alexclarke): Move this enum elsewhere. enum class WorkType { kImmediate, kDelayed }; @@ -38,4 +37,4 @@ } // namespace scheduler } // namespace blink -#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_SEQUENCE_H_ +#endif // THIRD_PARTY_WEBKIT_SOURCE_PLATFORM_SCHEDULER_BASE_SEQUENCED_TASK_SOURCE_H_
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue.cc index 1569c4a..22b0330 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue.cc
@@ -250,12 +250,12 @@ if (observer) { // Observer is guaranteed to outlive TaskQueue and TaskQueueImpl lifecycle // is controlled by |this|. - impl_->SetOnNextWakeUpChangedCallback( - base::Bind(&TaskQueue::Observer::OnQueueNextWakeUpChanged, - base::Unretained(observer), base::Unretained(this))); + impl_->SetOnNextWakeUpChangedCallback(base::BindRepeating( + &TaskQueue::Observer::OnQueueNextWakeUpChanged, + base::Unretained(observer), base::Unretained(this))); } else { impl_->SetOnNextWakeUpChangedCallback( - base::Callback<void(base::TimeTicks)>()); + base::RepeatingCallback<void(base::TimeTicks)>()); } }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc index 4dce8ad5..bbc3b55c 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.cc
@@ -280,8 +280,8 @@ // TODO(altimin): Add a copy method to Task to capture metadata here. PushOntoImmediateIncomingQueueLocked( Task(TaskQueue::PostedTask( - base::Bind(&TaskQueueImpl::ScheduleDelayedWorkTask, - base::Unretained(this), base::Passed(&pending_task)), + base::BindOnce(&TaskQueueImpl::ScheduleDelayedWorkTask, + base::Unretained(this), std::move(pending_task)), FROM_HERE, base::TimeDelta(), base::Nestable::kNonNestable, pending_task.task_type()), base::TimeTicks(), thread_hop_task_sequence_number, @@ -904,13 +904,13 @@ void TaskQueueImpl::RequeueDeferredNonNestableTask( TaskQueueImpl::Task&& task, - Sequence::WorkType work_type) { + SequencedTaskSource::WorkType work_type) { DCHECK(task.nestable == base::Nestable::kNonNestable); // The re-queued tasks have to be pushed onto the front because we'd otherwise // violate the strict monotonically increasing enqueue order within the // WorkQueue. We can't assign them a new enqueue order here because that will // not behave correctly with fences and things will break (e.g Idle TQ). - if (work_type == Sequence::WorkType::kDelayed) { + if (work_type == SequencedTaskSource::WorkType::kDelayed) { main_thread_only().delayed_work_queue->PushNonNestableTaskToFront( std::move(task)); } else {
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h index b666025..1df5ad6 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_impl.h
@@ -21,7 +21,7 @@ #include "platform/scheduler/base/enqueue_order.h" #include "platform/scheduler/base/graceful_queue_shutdown_helper.h" #include "platform/scheduler/base/intrusive_heap.h" -#include "platform/scheduler/base/sequence.h" +#include "platform/scheduler/base/sequenced_task_source.h" #include "platform/scheduler/base/task_queue.h" #include "platform/wtf/Deque.h" @@ -144,7 +144,8 @@ TaskQueue::PostedTask task; }; - using OnNextWakeUpChangedCallback = base::Callback<void(base::TimeTicks)>; + using OnNextWakeUpChangedCallback = + base::RepeatingCallback<void(base::TimeTicks)>; using OnTaskStartedHandler = base::RepeatingCallback<void(const TaskQueue::Task&, base::TimeTicks)>; using OnTaskCompletedHandler = @@ -245,7 +246,7 @@ // Pushes |task| onto the front of the specified work queue. Caution must be // taken with this API because you could easily starve out other work. void RequeueDeferredNonNestableTask(TaskQueueImpl::Task&& task, - Sequence::WorkType work_type); + SequencedTaskSource::WorkType work_type); void PushImmediateIncomingTaskForTest(TaskQueueImpl::Task&& task); EnqueueOrder GetFenceForTest() const;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl.cc index cfcc01de..f313fe91 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl.cc
@@ -72,7 +72,7 @@ RegisterTimeDomain(main_thread_only().real_time_domain.get()); - controller_->SetSequence(this); + controller_->SetSequencedTaskSource(this); controller_->AddNestingObserver(this); }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl.h b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl.h index e1cb8c4..18b6903 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl.h
@@ -22,7 +22,7 @@ #include "platform/scheduler/base/enqueue_order.h" #include "platform/scheduler/base/graceful_queue_shutdown_helper.h" #include "platform/scheduler/base/moveable_auto_lock.h" -#include "platform/scheduler/base/sequence.h" +#include "platform/scheduler/base/sequenced_task_source.h" #include "platform/scheduler/base/task_queue_impl.h" #include "platform/scheduler/base/task_queue_manager.h" #include "platform/scheduler/base/task_queue_selector.h" @@ -69,7 +69,7 @@ // class PLATFORM_EXPORT TaskQueueManagerImpl : public TaskQueueManager, - public internal::Sequence, + public internal::SequencedTaskSource, public internal::TaskQueueSelector::Observer, public base::RunLoop::NestingObserver { public: @@ -109,7 +109,7 @@ size_t GetNumberOfPendingTasks() const override; bool HasImmediateWorkForTesting() const override; - // Implementation of Sequence: + // Implementation of SequencedTaskSource: base::Optional<base::PendingTask> TakeTask() override; void DidRunTask() override; base::TimeDelta DelayTillNextTask(LazyNow* lazy_now) override;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl_unittest.cc index 09a5985..5c33e0fb 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_impl_unittest.cc
@@ -1055,8 +1055,8 @@ std::vector<EnqueueOrder>* out_result) { out_result->push_back(countdown); if (--countdown) { - runner->PostTask(FROM_HERE, - Bind(&ReentrantTestTask, runner, countdown, out_result)); + runner->PostTask( + FROM_HERE, BindOnce(&ReentrantTestTask, runner, countdown, out_result)); } } @@ -1066,8 +1066,8 @@ Initialize(1u); std::vector<EnqueueOrder> run_order; - runners_[0]->PostTask(FROM_HERE, - Bind(&ReentrantTestTask, runners_[0], 3, &run_order)); + runners_[0]->PostTask( + FROM_HERE, BindOnce(&ReentrantTestTask, runners_[0], 3, &run_order)); test_task_runner_->RunUntilIdle(); EXPECT_THAT(run_order, ElementsAre(3, 2, 1)); @@ -1110,8 +1110,9 @@ void RePostingTestTask(scoped_refptr<base::SingleThreadTaskRunner> runner, int* run_count) { (*run_count)++; - runner->PostTask(FROM_HERE, Bind(&RePostingTestTask, - base::Unretained(runner.get()), run_count)); + runner->PostTask( + FROM_HERE, + BindOnce(&RePostingTestTask, base::Unretained(runner.get()), run_count)); } TEST_F(TaskQueueManagerTest, DoWorkCantPostItselfMultipleTimes) { @@ -3430,19 +3431,17 @@ manager_.reset(); thread->task_runner()->PostTask( - FROM_HERE, - base::BindOnce( - [](scoped_refptr<base::SingleThreadTaskRunner> task_queue, - std::unique_ptr<PostTaskInDestructor> test_object, - base::WaitableEvent* test_executed) { - task_queue->PostTask( - FROM_HERE, - base::BindOnce(&PostTaskInDestructor::Do, - base::Passed(std::move(test_object)))); - test_executed->Signal(); - }, - main_tq, std::make_unique<PostTaskInDestructor>(main_tq), - &test_executed)); + FROM_HERE, base::BindOnce( + [](scoped_refptr<base::SingleThreadTaskRunner> task_queue, + std::unique_ptr<PostTaskInDestructor> test_object, + base::WaitableEvent* test_executed) { + task_queue->PostTask( + FROM_HERE, base::BindOnce(&PostTaskInDestructor::Do, + std::move(test_object))); + test_executed->Signal(); + }, + main_tq, std::make_unique<PostTaskInDestructor>(main_tq), + &test_executed)); test_executed.Wait(); }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_perftest.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_perftest.cc index d04c510a5..0b6e09d 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_perftest.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_manager_perftest.cc
@@ -126,8 +126,9 @@ unsigned int delay = num_tasks_to_post_ % 2 ? 1 : (10 + num_tasks_to_post_ % 10); queues_[queue]->PostDelayedTask( - FROM_HERE, base::Bind(&TaskQueueManagerPerfTest::TestDelayedTask, - base::Unretained(this)), + FROM_HERE, + base::BindOnce(&TaskQueueManagerPerfTest::TestDelayedTask, + base::Unretained(this)), base::TimeDelta::FromMilliseconds(delay)); num_tasks_in_flight_++; num_tasks_to_post_--; @@ -141,7 +142,8 @@ TestDelayedTask(); } - void Benchmark(const std::string& trace, const base::Closure& test_task) { + void Benchmark(const std::string& trace, + const base::RepeatingClosure& test_task) { base::ThreadTicks start = base::ThreadTicks::Now(); base::ThreadTicks now; unsigned long long num_iterations = 0; @@ -180,8 +182,9 @@ max_tasks_in_flight_ = 200; Benchmark("run 10000 delayed tasks with one queue", - base::Bind(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, - base::Unretained(this), 10000)); + base::BindRepeating( + &TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, + base::Unretained(this), 10000)); } TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_FourQueues) { @@ -191,8 +194,9 @@ max_tasks_in_flight_ = 200; Benchmark("run 10000 delayed tasks with four queues", - base::Bind(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, - base::Unretained(this), 10000)); + base::BindRepeating( + &TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, + base::Unretained(this), 10000)); } TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_EightQueues) { @@ -202,8 +206,9 @@ max_tasks_in_flight_ = 200; Benchmark("run 10000 delayed tasks with eight queues", - base::Bind(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, - base::Unretained(this), 10000)); + base::BindRepeating( + &TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, + base::Unretained(this), 10000)); } TEST_F(TaskQueueManagerPerfTest, RunTenThousandDelayedTasks_ThirtyTwoQueues) { @@ -213,8 +218,9 @@ max_tasks_in_flight_ = 200; Benchmark("run 10000 delayed tasks with eight queues", - base::Bind(&TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, - base::Unretained(this), 10000)); + base::BindRepeating( + &TaskQueueManagerPerfTest::ResetAndCallTestDelayedTask, + base::Unretained(this), 10000)); } // TODO(alexclarke): Add additional tests with different mixes of non-delayed vs
diff --git a/third_party/WebKit/Source/platform/scheduler/base/task_queue_selector_unittest.cc b/third_party/WebKit/Source/platform/scheduler/base/task_queue_selector_unittest.cc index da76bff..ac997c7 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/task_queue_selector_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/task_queue_selector_unittest.cc
@@ -48,7 +48,8 @@ class TaskQueueSelectorTest : public ::testing::Test { public: TaskQueueSelectorTest() - : test_closure_(base::Bind(&TaskQueueSelectorTest::TestFunction)) {} + : test_closure_( + base::BindRepeating(&TaskQueueSelectorTest::TestFunction)) {} ~TaskQueueSelectorTest() override = default; TaskQueueSelectorForTest::PrioritizingSelector* prioritizing_selector() { @@ -133,7 +134,7 @@ } const size_t kTaskQueueCount = 5; - base::Closure test_closure_; + base::RepeatingClosure test_closure_; TaskQueueSelectorForTest selector_; std::unique_ptr<VirtualTimeDomain> virtual_time_domain_; std::vector<std::unique_ptr<TaskQueueImpl>> task_queues_;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/thread_controller.h b/third_party/WebKit/Source/platform/scheduler/base/thread_controller.h index da3e1274..36a832fa 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/thread_controller.h +++ b/third_party/WebKit/Source/platform/scheduler/base/thread_controller.h
@@ -20,7 +20,7 @@ namespace scheduler { namespace internal { -class Sequence; +class SequencedTaskSource; // Interface for TaskQueueManager to schedule work to be run. class PLATFORM_EXPORT ThreadController { @@ -63,9 +63,10 @@ // |run_time| and previously scheduled callbacks should be cancelled. virtual void CancelDelayedWork(base::TimeTicks run_time) = 0; - // Sets the sequence from which to take tasks after a Schedule*Work() call is - // made. Must be called before the first call to Schedule*Work(). - virtual void SetSequence(Sequence*) = 0; + // Sets the sequenced task source from which to take tasks after + // a Schedule*Work() call is made. + // Must be called before the first call to Schedule*Work(). + virtual void SetSequencedTaskSource(SequencedTaskSource*) = 0; // TODO(altimin): Get rid of the methods below. // These methods exist due to current integration of TaskQueueManager
diff --git a/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.cc b/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.cc index f92326d..a400478 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.cc
@@ -11,7 +11,6 @@ #include "base/time/tick_clock.h" #include "base/trace_event/trace_event.h" #include "platform/scheduler/base/lazy_now.h" -#include "platform/scheduler/base/sequence.h" namespace blink { namespace scheduler { @@ -29,10 +28,10 @@ weak_factory_(this) { immediate_do_work_closure_ = base::BindRepeating( &ThreadControllerImpl::DoWork, weak_factory_.GetWeakPtr(), - Sequence::WorkType::kImmediate); - delayed_do_work_closure_ = base::BindRepeating(&ThreadControllerImpl::DoWork, - weak_factory_.GetWeakPtr(), - Sequence::WorkType::kDelayed); + SequencedTaskSource::WorkType::kImmediate); + delayed_do_work_closure_ = base::BindRepeating( + &ThreadControllerImpl::DoWork, weak_factory_.GetWeakPtr(), + SequencedTaskSource::WorkType::kDelayed); } ThreadControllerImpl::~ThreadControllerImpl() = default; @@ -44,7 +43,8 @@ message_loop, message_loop->task_runner(), time_source)); } -void ThreadControllerImpl::SetSequence(Sequence* sequence) { +void ThreadControllerImpl::SetSequencedTaskSource( + SequencedTaskSource* sequence) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(sequence); DCHECK(!sequence_); @@ -138,13 +138,13 @@ task_annotator_.DidQueueTask("TaskQueueManager::PostTask", pending_task); } -void ThreadControllerImpl::DoWork(Sequence::WorkType work_type) { +void ThreadControllerImpl::DoWork(SequencedTaskSource::WorkType work_type) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(sequence_); { base::AutoLock lock(any_sequence_lock_); - if (work_type == Sequence::WorkType::kImmediate) + if (work_type == SequencedTaskSource::WorkType::kImmediate) any_sequence().immediate_do_work_posted = false; any_sequence().do_work_running_count++; }
diff --git a/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.h b/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.h index 69b776ee..1227ef3 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/base/thread_controller_impl.h
@@ -15,7 +15,7 @@ #include "base/sequence_checker.h" #include "base/single_thread_task_runner.h" #include "platform/PlatformExport.h" -#include "platform/scheduler/base/sequence.h" +#include "platform/scheduler/base/sequenced_task_source.h" namespace base { class MessageLoop; @@ -43,7 +43,7 @@ void ScheduleDelayedWork(base::TimeTicks now, base::TimeTicks run_timy) override; void CancelDelayedWork(base::TimeTicks run_time) override; - void SetSequence(Sequence* sequence) override; + void SetSequencedTaskSource(SequencedTaskSource* sequence) override; bool RunsTasksInCurrentSequence() override; base::TickClock* GetClock() override; void SetDefaultTaskRunner( @@ -69,7 +69,7 @@ base::RunLoop::NestingObserver* nesting_observer_ = nullptr; private: - void DoWork(Sequence::WorkType work_type); + void DoWork(SequencedTaskSource::WorkType work_type); struct AnySequence { AnySequence() = default; @@ -117,7 +117,7 @@ base::RepeatingClosure immediate_do_work_closure_; base::RepeatingClosure delayed_do_work_closure_; base::CancelableClosure cancelable_delayed_do_work_closure_; - Sequence* sequence_ = nullptr; // NOT OWNED + SequencedTaskSource* sequence_ = nullptr; // NOT OWNED base::debug::TaskAnnotator task_annotator_; base::WeakPtrFactory<ThreadControllerImpl> weak_factory_;
diff --git a/third_party/WebKit/Source/platform/scheduler/base/work_queue.h b/third_party/WebKit/Source/platform/scheduler/base/work_queue.h index d8a9d998..d6bbf632 100644 --- a/third_party/WebKit/Source/platform/scheduler/base/work_queue.h +++ b/third_party/WebKit/Source/platform/scheduler/base/work_queue.h
@@ -13,7 +13,7 @@ #include "base/trace_event/trace_event_argument.h" #include "platform/scheduler/base/enqueue_order.h" #include "platform/scheduler/base/intrusive_heap.h" -#include "platform/scheduler/base/sequence.h" +#include "platform/scheduler/base/sequenced_task_source.h" #include "platform/scheduler/base/task_queue_impl.h" namespace blink { @@ -33,7 +33,7 @@ // throttling mechanisms. class PLATFORM_EXPORT WorkQueue { public: - using QueueType = Sequence::WorkType; + using QueueType = SequencedTaskSource::WorkType; // Note |task_queue| can be null if queue_type is kNonNestable. WorkQueue(TaskQueueImpl* task_queue, const char* name, QueueType queue_type);
diff --git a/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper.cc b/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper.cc index 78aa610f..1114072b 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper.cc
@@ -25,8 +25,8 @@ void IdleCanceledDelayedTaskSweeper::PostIdleTask() { idle_task_runner_->PostDelayedIdleTask( FROM_HERE, base::TimeDelta::FromSeconds(kDelayedTaskSweepIntervalSeconds), - base::Bind(&IdleCanceledDelayedTaskSweeper::SweepIdleTask, - weak_factory_.GetWeakPtr())); + base::BindOnce(&IdleCanceledDelayedTaskSweeper::SweepIdleTask, + weak_factory_.GetWeakPtr())); } void IdleCanceledDelayedTaskSweeper::SweepIdleTask(base::TimeTicks deadline) {
diff --git a/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc index dbb826c..50852a48 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/idle_canceled_delayed_task_sweeper_unittest.cc
@@ -90,28 +90,28 @@ // Post one task we won't cancel. default_task_queue_->PostDelayedTask( FROM_HERE, - base::Bind(&TestClass::NopTask, class1.weak_factory_.GetWeakPtr()), + base::BindOnce(&TestClass::NopTask, class1.weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(100)); // And a bunch we will. default_task_queue_->PostDelayedTask( FROM_HERE, - base::Bind(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), + base::BindOnce(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(101)); default_task_queue_->PostDelayedTask( FROM_HERE, - base::Bind(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), + base::BindOnce(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(102)); default_task_queue_->PostDelayedTask( FROM_HERE, - base::Bind(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), + base::BindOnce(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(103)); default_task_queue_->PostDelayedTask( FROM_HERE, - base::Bind(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), + base::BindOnce(&TestClass::NopTask, class2.weak_factory_.GetWeakPtr()), base::TimeDelta::FromSeconds(104)); // Cancel the last four tasks.
diff --git a/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc b/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc index d095066..3c5a19b 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/idle_helper.cc
@@ -30,9 +30,9 @@ is_shutdown_(false), weak_factory_(this) { weak_idle_helper_ptr_ = weak_factory_.GetWeakPtr(); - enable_next_long_idle_period_closure_.Reset( - base::Bind(&IdleHelper::EnableLongIdlePeriod, weak_idle_helper_ptr_)); - on_idle_task_posted_closure_.Reset(base::Bind( + enable_next_long_idle_period_closure_.Reset(base::BindRepeating( + &IdleHelper::EnableLongIdlePeriod, weak_idle_helper_ptr_)); + on_idle_task_posted_closure_.Reset(base::BindRepeating( &IdleHelper::OnIdleTaskPostedOnMainThread, weak_idle_helper_ptr_)); idle_task_runner_ =
diff --git a/third_party/WebKit/Source/platform/scheduler/child/idle_helper_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/idle_helper_unittest.cc index 99e5d289..1d4535f 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/idle_helper_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/idle_helper_unittest.cc
@@ -56,10 +56,10 @@ int max_reentrant_count) { vector->push_back((*reentrant_count)++); if (*reentrant_count < max_reentrant_count) { - task_runner->PostTask( - FROM_HERE, - base::Bind(AppendToVectorReentrantTask, base::Unretained(task_runner), - vector, reentrant_count, max_reentrant_count)); + task_runner->PostTask(FROM_HERE, + base::BindOnce(AppendToVectorReentrantTask, + base::Unretained(task_runner), vector, + reentrant_count, max_reentrant_count)); } } @@ -78,9 +78,9 @@ base::TimeTicks deadline) { if ((*run_count + 1) < g_max_idle_task_reposts) { idle_task_runner->PostIdleTask( - FROM_HERE, - base::Bind(&RepostingIdleTestTask, base::Unretained(idle_task_runner), - run_count, deadline_out)); + FROM_HERE, base::BindOnce(&RepostingIdleTestTask, + base::Unretained(idle_task_runner), run_count, + deadline_out)); } *deadline_out = deadline; (*run_count)++; @@ -95,9 +95,9 @@ base::TimeTicks deadline) { if ((*run_count + 1) < g_max_idle_task_reposts) { idle_task_runner->PostIdleTask( - FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask, - base::Unretained(idle_task_runner), run_count, - clock, advance_time, deadlines)); + FROM_HERE, base::BindOnce(&RepostingUpdateClockIdleTestTask, + base::Unretained(idle_task_runner), run_count, + clock, advance_time, deadlines)); } deadlines->push_back(deadline); (*run_count)++; @@ -109,8 +109,9 @@ base::TimeDelta delay) { if (num_repeats > 1) { task_runner->PostDelayedTask( - FROM_HERE, base::Bind(&RepeatingTask, base::Unretained(task_runner), - num_repeats - 1, delay), + FROM_HERE, + base::BindOnce(&RepeatingTask, base::Unretained(task_runner), + num_repeats - 1, delay), delay); } } @@ -332,7 +333,7 @@ clock_.Advance(base::TimeDelta::FromMilliseconds(100)); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); RunUntilIdle(); EXPECT_EQ(0, run_count); @@ -350,7 +351,7 @@ clock_.Advance(base::TimeDelta::FromMilliseconds(100)); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); RunUntilIdle(); EXPECT_EQ(0, run_count); @@ -369,9 +370,9 @@ g_max_idle_task_reposts = 2; idle_task_runner_->PostIdleTask( - FROM_HERE, - base::Bind(&RepostingIdleTestTask, base::RetainedRef(idle_task_runner_), - &run_count, &actual_deadline)); + FROM_HERE, base::BindOnce(&RepostingIdleTestTask, + base::RetainedRef(idle_task_runner_), + &run_count, &actual_deadline)); idle_helper_->StartIdlePeriod( IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(), clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10)); @@ -395,10 +396,10 @@ // Post two UpdateClockToDeadlineIdleTestTask tasks. idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count)); + base::BindOnce(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count)); idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count)); + base::BindOnce(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count)); idle_helper_->StartIdlePeriod( IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(), @@ -509,26 +510,28 @@ std::vector<std::string> order; idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("1"))); + base::BindOnce(&AppendToVectorIdleTestTask, &order, std::string("1"))); idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("2"))); + base::BindOnce(&AppendToVectorIdleTestTask, &order, std::string("2"))); std::vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>> tasks_to_post_from_nested_loop; tasks_to_post_from_nested_loop.push_back(std::make_pair( - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("3")), + base::BindOnce(&AppendToVectorIdleTestTask, &order, std::string("3")), false)); tasks_to_post_from_nested_loop.push_back(std::make_pair( - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("4")), true)); + base::BindOnce(&AppendToVectorIdleTestTask, &order, std::string("4")), + true)); tasks_to_post_from_nested_loop.push_back(std::make_pair( - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("5")), true)); + base::BindOnce(&AppendToVectorIdleTestTask, &order, std::string("5")), + true)); default_task_runner_->PostTask( FROM_HERE, - base::Bind(&IdleHelperWithMessageLoopTest::PostFromNestedRunloop, - base::Unretained(this), - base::Unretained(&tasks_to_post_from_nested_loop))); + base::BindOnce(&IdleHelperWithMessageLoopTest::PostFromNestedRunloop, + base::Unretained(this), + base::Unretained(&tasks_to_post_from_nested_loop))); idle_helper_->StartIdlePeriod( IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(), @@ -547,7 +550,7 @@ int run_count = 0; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); EXPECT_CALL(*idle_helper_, CanEnterLongIdlePeriod(_, _)) .Times(1) @@ -570,8 +573,8 @@ int run_count = 0; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); + default_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NullTask), pending_task_delay); idle_helper_->EnableLongIdlePeriod(); @@ -585,7 +588,7 @@ base::TimeTicks deadline_in_task; int run_count = 0; - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), + default_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NullTask), pending_task_delay); // Advance clock until after delayed task was meant to be run. @@ -594,7 +597,7 @@ // Post an idle task and then EnableLongIdlePeriod. Since there is a late // pending delayed task this shouldn't actually start an idle period. idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); idle_helper_->EnableLongIdlePeriod(); RunUntilIdle(); EXPECT_EQ(0, run_count); @@ -619,9 +622,10 @@ base::TimeTicks clock_before(clock_.NowTicks()); base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10)); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask, - base::RetainedRef(idle_task_runner_), &run_count, - &clock_, idle_task_runtime, &actual_deadlines)); + FROM_HERE, + base::BindOnce(&RepostingUpdateClockIdleTestTask, + base::RetainedRef(idle_task_runner_), &run_count, &clock_, + idle_task_runtime, &actual_deadlines)); // Check each idle task runs in their own idle period. idle_helper_->EnableLongIdlePeriod(); @@ -635,12 +639,13 @@ g_max_idle_task_reposts = 5; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask, - base::RetainedRef(idle_task_runner_), &run_count, - &clock_, idle_task_runtime, &actual_deadlines)); - idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&EndIdlePeriodIdleTask, base::Unretained(idle_helper_.get()))); + base::BindOnce(&RepostingUpdateClockIdleTestTask, + base::RetainedRef(idle_task_runner_), &run_count, &clock_, + idle_task_runtime, &actual_deadlines)); + idle_task_runner_->PostIdleTask( + FROM_HERE, base::BindOnce(&EndIdlePeriodIdleTask, + base::Unretained(idle_helper_.get()))); // Ensure that reposting tasks stop after EndIdlePeriod is called. RunUntilIdle(); @@ -670,7 +675,7 @@ EXPECT_CALL(*idle_helper_, OnIdlePeriodStarted()).Times(AnyNumber()); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); // Make sure Idle tasks don't run until the delay has occurred. idle_helper_->EnableLongIdlePeriod(); @@ -701,9 +706,10 @@ // they have max deadlines. g_max_idle_task_reposts = 2; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask, - base::RetainedRef(idle_task_runner_), &run_count, - &clock_, idle_task_runtime, &actual_deadlines)); + FROM_HERE, + base::BindOnce(&RepostingUpdateClockIdleTestTask, + base::RetainedRef(idle_task_runner_), &run_count, &clock_, + idle_task_runtime, &actual_deadlines)); idle_helper_->EnableLongIdlePeriod(); RunUntilIdle(); @@ -725,14 +731,14 @@ retry_enable_long_idle_period_delay()); // Post delayed task to ensure idle period doesn't have a max deadline. - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), + default_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NullTask), pending_task_delay); g_max_idle_task_reposts = 2; idle_task_runner_->PostIdleTask( - FROM_HERE, - base::Bind(&RepostingIdleTestTask, base::RetainedRef(idle_task_runner_), - &run_count, &actual_deadline)); + FROM_HERE, base::BindOnce(&RepostingIdleTestTask, + base::RetainedRef(idle_task_runner_), + &run_count, &actual_deadline)); idle_helper_->EnableLongIdlePeriod(); RunUntilIdle(); EXPECT_EQ(1, run_count); @@ -772,9 +778,10 @@ base::TimeTicks clock_before(clock_.NowTicks()); base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10)); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask, - base::RetainedRef(idle_task_runner_), &run_count, - &clock_, idle_task_runtime, &actual_deadlines)); + FROM_HERE, + base::BindOnce(&RepostingUpdateClockIdleTestTask, + base::RetainedRef(idle_task_runner_), &run_count, &clock_, + idle_task_runtime, &actual_deadlines)); RunUntilIdle(); EXPECT_EQ(2, run_count); EXPECT_THAT(actual_deadlines, @@ -796,7 +803,7 @@ int run_count = 0; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); idle_helper_->Shutdown(); // We shouldn't be able to enter a long idle period when shutdown @@ -824,9 +831,9 @@ // Should return false for short idle periods. idle_task_runner_->PostIdleTask( - FROM_HERE, - base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, idle_helper_.get(), - &can_exceed_idle_deadline, &run_count)); + FROM_HERE, base::BindOnce(&TestCanExceedIdleDeadlineIfRequiredTask, + idle_helper_.get(), &can_exceed_idle_deadline, + &run_count)); idle_helper_->StartIdlePeriod( IdleHelper::IdlePeriodState::kInShortIdlePeriod, clock_.NowTicks(), clock_.NowTicks() + base::TimeDelta::FromMilliseconds(10)); @@ -836,12 +843,12 @@ // Should return false for a long idle period which is shortened due to a // pending delayed task. - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), + default_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NullTask), base::TimeDelta::FromMilliseconds(10)); idle_task_runner_->PostIdleTask( - FROM_HERE, - base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, idle_helper_.get(), - &can_exceed_idle_deadline, &run_count)); + FROM_HERE, base::BindOnce(&TestCanExceedIdleDeadlineIfRequiredTask, + idle_helper_.get(), &can_exceed_idle_deadline, + &run_count)); idle_helper_->EnableLongIdlePeriod(); RunUntilIdle(); EXPECT_EQ(2, run_count); @@ -851,9 +858,9 @@ // CanExceedIdleDeadlineIfRequired should return true. clock_.Advance(maximum_idle_period_duration()); idle_task_runner_->PostIdleTask( - FROM_HERE, - base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, idle_helper_.get(), - &can_exceed_idle_deadline, &run_count)); + FROM_HERE, base::BindOnce(&TestCanExceedIdleDeadlineIfRequiredTask, + idle_helper_.get(), &can_exceed_idle_deadline, + &run_count)); RunUntilIdle(); EXPECT_EQ(3, run_count); EXPECT_TRUE(can_exceed_idle_deadline); @@ -884,7 +891,7 @@ void MakeNonQuiescent() { // Run an arbitrary task so we're deemed to be not quiescent. - default_task_runner_->PostTask(FROM_HERE, base::Bind(NullTask)); + default_task_runner_->PostTask(FROM_HERE, base::BindOnce(NullTask)); RunUntilIdle(); } @@ -916,9 +923,9 @@ int run_count = 0; g_max_idle_task_reposts = 1; idle_task_runner_->PostIdleTask( - FROM_HERE, - base::Bind(&RepostingIdleTestTask, base::RetainedRef(idle_task_runner_), - &run_count, &actual_deadline)); + FROM_HERE, base::BindOnce(&RepostingIdleTestTask, + base::RetainedRef(idle_task_runner_), + &run_count, &actual_deadline)); idle_helper_->EnableLongIdlePeriod(); RunUntilIdle(); @@ -938,9 +945,9 @@ int run_count = 0; g_max_idle_task_reposts = 1; idle_task_runner_->PostIdleTask( - FROM_HERE, - base::Bind(&RepostingIdleTestTask, base::RetainedRef(idle_task_runner_), - &run_count, &actual_deadline)); + FROM_HERE, base::BindOnce(&RepostingIdleTestTask, + base::RetainedRef(idle_task_runner_), + &run_count, &actual_deadline)); idle_helper_->EnableLongIdlePeriod(); RunUntilIdle(); @@ -957,9 +964,9 @@ // Run a repeating task so we're deemed to be busy for the next 400ms. default_task_runner_->PostTask( - FROM_HERE, - base::Bind(&RepeatingTask, base::Unretained(default_task_runner_.get()), - 10, base::TimeDelta::FromMilliseconds(40))); + FROM_HERE, base::BindOnce(&RepeatingTask, + base::Unretained(default_task_runner_.get()), + 10, base::TimeDelta::FromMilliseconds(40))); int run_count = 0; // In this scenario EnableLongIdlePeriod deems us not to be quiescent 5x in @@ -969,7 +976,7 @@ 5 * kQuiescenceDelayMs + kLongIdlePeriodMs); base::TimeTicks deadline_in_task; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); idle_helper_->EnableLongIdlePeriod(); RunUntilIdle(); @@ -981,12 +988,12 @@ QuescienceCheckedForAfterLongIdlePeriodEnds) { mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); - idle_task_runner_->PostIdleTask(FROM_HERE, base::Bind(&NullIdleTask)); + idle_task_runner_->PostIdleTask(FROM_HERE, base::BindOnce(&NullIdleTask)); idle_helper_->EnableLongIdlePeriod(); RunUntilIdle(); // Post a normal task to make the scheduler non-quiescent. - default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); + default_task_runner_->PostTask(FROM_HERE, base::BindOnce(&NullTask)); RunUntilIdle(); // Post an idle task. The idle task won't run initially because the system is @@ -997,7 +1004,7 @@ clock_.NowTicks() + base::TimeDelta::FromMilliseconds(kQuiescenceDelayMs + kLongIdlePeriodMs); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); idle_helper_->EnableLongIdlePeriod(); RunUntilIdle(); @@ -1010,7 +1017,7 @@ base::TimeTicks deadline_in_task; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); base::TimeDelta half_a_ms(base::TimeDelta::FromMicroseconds(50)); base::TimeTicks less_than_min_deadline( @@ -1040,8 +1047,8 @@ minimum_idle_period_duration() + half_a_ms); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); + default_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NullTask), less_than_min_deadline_duration); idle_helper_->EnableLongIdlePeriod(); @@ -1053,7 +1060,7 @@ RunUntilIdle(); EXPECT_EQ(0, run_count); - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), + default_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NullTask), more_than_min_deadline_duration); idle_helper_->EnableLongIdlePeriod(); RunUntilIdle(); @@ -1069,10 +1076,10 @@ base::TimeTicks deadline_in_task; idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&ShutdownIdleTask, base::Unretained(idle_helper_.get()), - &shutdown_task_run)); + base::BindOnce(&ShutdownIdleTask, base::Unretained(idle_helper_.get()), + &shutdown_task_run)); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); // Delayed call to IdleHelper::EnableLongIdlePeriod enables idle tasks. idle_helper_->EnableLongIdlePeriod(); @@ -1098,7 +1105,7 @@ // task queue until the delay is up. idle_task_runner_->PostDelayedIdleTask( FROM_HERE, base::TimeDelta::FromMilliseconds(200), - base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); EXPECT_EQ(0u, idle_queue()->GetNumberOfPendingTasks()); clock_.Advance(base::TimeDelta::FromMilliseconds(100)); @@ -1138,7 +1145,7 @@ clock_.Advance(base::TimeDelta::FromMilliseconds(100)); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); RunUntilIdle(); EXPECT_EQ(0, run_count); @@ -1169,9 +1176,9 @@ clock_.Advance(base::TimeDelta::FromMilliseconds(100)); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); RunUntilIdle(); EXPECT_EQ(0, run_count);
diff --git a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper_unittest.cc index afa91c0..e7916837 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/scheduler_helper_unittest.cc
@@ -39,10 +39,10 @@ int max_reentrant_count) { vector->push_back((*reentrant_count)++); if (*reentrant_count < max_reentrant_count) { - task_runner->PostTask( - FROM_HERE, - base::Bind(AppendToVectorReentrantTask, base::Unretained(task_runner), - vector, reentrant_count, max_reentrant_count)); + task_runner->PostTask(FROM_HERE, + base::BindOnce(AppendToVectorReentrantTask, + base::Unretained(task_runner), vector, + reentrant_count, max_reentrant_count)); } } @@ -93,13 +93,13 @@ TEST_F(SchedulerHelperTest, TestPostDefaultTask) { std::vector<std::string> run_order; default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "D1")); + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, &run_order, "D1")); default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "D2")); + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, &run_order, "D2")); default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "D3")); + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, &run_order, "D3")); default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "D4")); + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, &run_order, "D4")); RunUntilIdle(); EXPECT_THAT(run_order, @@ -111,9 +111,9 @@ int count = 0; std::vector<int> run_order; default_task_runner_->PostTask( - FROM_HERE, base::Bind(AppendToVectorReentrantTask, - base::RetainedRef(default_task_runner_), &run_order, - &count, 5)); + FROM_HERE, base::BindOnce(AppendToVectorReentrantTask, + base::RetainedRef(default_task_runner_), + &run_order, &count, 5)); RunUntilIdle(); EXPECT_THAT(run_order, ::testing::ElementsAre(0, 1, 2, 3, 4)); @@ -129,11 +129,11 @@ TEST_F(SchedulerHelperTest, GetNumberOfPendingTasks) { std::vector<std::string> run_order; scheduler_helper_->DefaultWorkerTaskQueue()->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "D1")); + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, &run_order, "D1")); scheduler_helper_->DefaultWorkerTaskQueue()->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "D2")); + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, &run_order, "D2")); scheduler_helper_->ControlWorkerTaskQueue()->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "C1")); + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, &run_order, "C1")); EXPECT_EQ(3U, scheduler_helper_->GetNumberOfPendingTasks()); RunUntilIdle(); EXPECT_EQ(0U, scheduler_helper_->GetNumberOfPendingTasks()); @@ -153,8 +153,8 @@ MockTaskObserver observer; scheduler_helper_->AddTaskObserver(&observer); - scheduler_helper_->DefaultWorkerTaskQueue()->PostTask(FROM_HERE, - base::Bind(&NopTask)); + scheduler_helper_->DefaultWorkerTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&NopTask)); EXPECT_CALL(observer, WillProcessTask(_)).Times(1); EXPECT_CALL(observer, DidProcessTask(_)).Times(1); @@ -165,8 +165,8 @@ MockTaskObserver observer; scheduler_helper_->AddTaskObserver(&observer); - scheduler_helper_->ControlWorkerTaskQueue()->PostTask(FROM_HERE, - base::Bind(&NopTask)); + scheduler_helper_->ControlWorkerTaskQueue()->PostTask( + FROM_HERE, base::BindOnce(&NopTask)); EXPECT_CALL(observer, WillProcessTask(_)).Times(0); EXPECT_CALL(observer, DidProcessTask(_)).Times(0);
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc index 71d2ffa..808b2b5 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler.cc
@@ -35,8 +35,8 @@ base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); thread_task_runner_->PostTask( - FROM_HERE, base::Bind(&WebThreadImplForWorkerScheduler::InitOnThread, - base::Unretained(this), &completion)); + FROM_HERE, base::BindOnce(&WebThreadImplForWorkerScheduler::InitOnThread, + base::Unretained(this), &completion)); completion.Wait(); } @@ -49,8 +49,8 @@ base::WaitableEvent::InitialState::NOT_SIGNALED); thread_task_runner_->PostTask( FROM_HERE, - base::Bind(&WebThreadImplForWorkerScheduler::ShutdownOnThread, - base::Unretained(this), &completion)); + base::BindOnce(&WebThreadImplForWorkerScheduler::ShutdownOnThread, + base::Unretained(this), &completion)); completion.Wait(); } thread_->Stop();
diff --git a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc index 47c51e9..30b3927d8 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/webthread_impl_for_worker_scheduler_unittest.cc
@@ -79,21 +79,22 @@ } void RunOnWorkerThread(const base::Location& from_here, - const base::Closure& task) { + base::OnceClosure task) { base::WaitableEvent completion( base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); thread_->GetTaskRunner()->PostTask( from_here, - base::Bind(&WebThreadImplForWorkerSchedulerTest::RunOnWorkerThreadTask, - base::Unretained(this), task, &completion)); + base::BindOnce( + &WebThreadImplForWorkerSchedulerTest::RunOnWorkerThreadTask, + base::Unretained(this), std::move(task), &completion)); completion.Wait(); } protected: - void RunOnWorkerThreadTask(const base::Closure& task, + void RunOnWorkerThreadTask(base::OnceClosure task, base::WaitableEvent* completion) { - task.Run(); + std::move(task).Run(); completion->Signal(); } @@ -163,12 +164,12 @@ TestObserver observer(&calls); RunOnWorkerThread(FROM_HERE, - base::Bind(&AddTaskObserver, thread_.get(), &observer)); + base::BindOnce(&AddTaskObserver, thread_.get(), &observer)); PostCrossThreadTask( *thread_->GetTaskRunner(), FROM_HERE, CrossThreadBind(&RunTestTask, WTF::CrossThreadUnretained(&calls))); - RunOnWorkerThread(FROM_HERE, - base::Bind(&RemoveTaskObserver, thread_.get(), &observer)); + RunOnWorkerThread( + FROM_HERE, base::BindOnce(&RemoveTaskObserver, thread_.get(), &observer)); // We need to be careful what we test here. We want to make sure the // observers are un in the expected order before and after the task. @@ -186,7 +187,8 @@ EXPECT_CALL(task, Run()).Times(0); EXPECT_CALL(delayed_task, Run()).Times(0); - RunOnWorkerThread(FROM_HERE, base::Bind(&ShutdownOnThread, thread_.get())); + RunOnWorkerThread(FROM_HERE, + base::BindOnce(&ShutdownOnThread, thread_.get())); PostCrossThreadTask( *thread_->GetTaskRunner(), FROM_HERE, CrossThreadBind(&MockTask::Run, WTF::CrossThreadUnretained(&task)));
diff --git a/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl.cc index 99e91f10..36e8e2f 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl.cc
@@ -59,7 +59,7 @@ idle_canceled_delayed_task_sweeper_(helper_.get(), idle_helper_.IdleTaskRunner()), load_tracker_(helper_->NowTicks(), - base::Bind(&ReportWorkerTaskLoad), + base::BindRepeating(&ReportWorkerTaskLoad), kUnspecifiedWorkerThreadLoadTrackerReportingInterval), throttling_state_( proxy ? proxy->throttling_state()
diff --git a/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl_unittest.cc index 8fd2bb0..064b7adc 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/worker_scheduler_impl_unittest.cc
@@ -144,12 +144,13 @@ switch (task[0]) { case 'D': default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); + FROM_HERE, + base::BindOnce(&AppendToVectorTestTask, run_order, task)); break; case 'I': idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&AppendToVectorIdleTestTask, run_order, task)); + base::BindOnce(&AppendToVectorIdleTestTask, run_order, task)); break; default: NOTREACHED(); @@ -216,7 +217,7 @@ PostTestTasks(&run_order, "I1 D2 D3 D4"); default_task_runner_->PostDelayedTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, &run_order, "DELAYED"), + FROM_HERE, base::BindOnce(&AppendToVectorTestTask, &run_order, "DELAYED"), base::TimeDelta::FromMilliseconds(1000)); RunUntilIdle(); @@ -234,13 +235,14 @@ timeline.push_back("Post default task"); // Post a delayed task timed to occur mid way during the long idle period. default_task_runner_->PostTask( - FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline), - base::Unretained(&clock_))); + FROM_HERE, + base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline), + base::Unretained(&clock_))); RunUntilIdle(); timeline.push_back("Post idle task"); - idle_task_runner_->PostIdleTask(FROM_HERE, - base::Bind(&TimelineIdleTestTask, &timeline)); + idle_task_runner_->PostIdleTask( + FROM_HERE, base::BindOnce(&TimelineIdleTestTask, &timeline)); RunUntilIdle(); @@ -264,11 +266,11 @@ // Post a delayed task timed to occur mid way during the long idle period. default_task_runner_->PostDelayedTask( FROM_HERE, - base::Bind(&RecordTimelineTask, base::Unretained(&timeline), - base::Unretained(&clock_)), + base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline), + base::Unretained(&clock_)), base::TimeDelta::FromMilliseconds(20)); - idle_task_runner_->PostIdleTask(FROM_HERE, - base::Bind(&TimelineIdleTestTask, &timeline)); + idle_task_runner_->PostIdleTask( + FROM_HERE, base::BindOnce(&TimelineIdleTestTask, &timeline)); RunUntilIdle(); @@ -291,11 +293,11 @@ // Post a delayed task timed to occur well after the long idle period. default_task_runner_->PostDelayedTask( FROM_HERE, - base::Bind(&RecordTimelineTask, base::Unretained(&timeline), - base::Unretained(&clock_)), + base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline), + base::Unretained(&clock_)), base::TimeDelta::FromMilliseconds(500)); - idle_task_runner_->PostIdleTask(FROM_HERE, - base::Bind(&TimelineIdleTestTask, &timeline)); + idle_task_runner_->PostIdleTask( + FROM_HERE, base::BindOnce(&TimelineIdleTestTask, &timeline)); RunUntilIdle(); @@ -312,7 +314,8 @@ Init(); default_task_runner_->PostDelayedTask( - FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(1000)); + FROM_HERE, base::BindOnce(&NopTask), + base::TimeDelta::FromMilliseconds(1000)); RunUntilIdle(); std::vector<std::string> run_order; @@ -330,8 +333,8 @@ timeline->push_back(base::StringPrintf("run PostIdleTask @ %d", TimeTicksToIntMs(clock->NowTicks()))); - idle_task_runner->PostIdleTask(FROM_HERE, - base::Bind(&TimelineIdleTestTask, timeline)); + idle_task_runner->PostIdleTask( + FROM_HERE, base::BindOnce(&TimelineIdleTestTask, timeline)); } TEST_F(WorkerSchedulerImplTest, TestLongIdlePeriodTimeline) { @@ -358,22 +361,23 @@ // the idle task run. default_task_runner_->PostDelayedTask( FROM_HERE, - base::Bind(&PostIdleTask, base::Unretained(&timeline), - base::Unretained(&clock_), - base::Unretained(idle_task_runner_.get())), + base::BindOnce(&PostIdleTask, base::Unretained(&timeline), + base::Unretained(&clock_), + base::Unretained(idle_task_runner_.get())), base::TimeDelta::FromMilliseconds(30)); timeline.push_back("PostFirstIdleTask"); - idle_task_runner_->PostIdleTask(FROM_HERE, - base::Bind(&TimelineIdleTestTask, &timeline)); + idle_task_runner_->PostIdleTask( + FROM_HERE, base::BindOnce(&TimelineIdleTestTask, &timeline)); RunUntilIdle(); new_idle_period_deadline = scheduler_->CurrentIdleTaskDeadlineForTesting(); // Running a normal task will mark the system as non-quiescent. timeline.push_back("Post RecordTimelineTask"); default_task_runner_->PostTask( - FROM_HERE, base::Bind(&RecordTimelineTask, base::Unretained(&timeline), - base::Unretained(&clock_))); + FROM_HERE, + base::BindOnce(&RecordTimelineTask, base::Unretained(&timeline), + base::Unretained(&clock_))); RunUntilIdle(); std::string expected_timeline[] = {"RunUntilIdle begin @ 55",
diff --git a/third_party/WebKit/Source/platform/scheduler/child/worker_task_queue.cc b/third_party/WebKit/Source/platform/scheduler/child/worker_task_queue.cc index 2bed41e..020003dc 100644 --- a/third_party/WebKit/Source/platform/scheduler/child/worker_task_queue.cc +++ b/third_party/WebKit/Source/platform/scheduler/child/worker_task_queue.cc
@@ -16,8 +16,8 @@ : TaskQueue(std::move(impl), spec), worker_scheduler_(worker_scheduler) { if (GetTaskQueueImpl()) { // TaskQueueImpl may be null for tests. - GetTaskQueueImpl()->SetOnTaskCompletedHandler( - base::Bind(&WorkerTaskQueue::OnTaskCompleted, base::Unretained(this))); + GetTaskQueueImpl()->SetOnTaskCompletedHandler(base::BindRepeating( + &WorkerTaskQueue::OnTaskCompleted, base::Unretained(this))); } }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc index 38b5379..7f0f1f4d 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/auto_advancing_virtual_time_domain_unittest.cc
@@ -79,7 +79,7 @@ base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); bool task_run = false; - task_queue_->PostDelayedTask(FROM_HERE, base::Bind(NopTask, &task_run), + task_queue_->PostDelayedTask(FROM_HERE, base::BindOnce(NopTask, &task_run), delay); EXPECT_CALL(mock_observer, OnVirtualTimeAdvanced()); @@ -99,7 +99,7 @@ base::TimeDelta delay = base::TimeDelta::FromMilliseconds(10); bool task_run = false; - task_queue_->PostDelayedTask(FROM_HERE, base::Bind(NopTask, &task_run), + task_queue_->PostDelayedTask(FROM_HERE, base::BindOnce(NopTask, &task_run), delay); auto_advancing_time_domain_->SetCanAdvanceVirtualTime(false); @@ -123,7 +123,7 @@ return; task_queue->PostTask( - FROM_HERE, base::Bind(&RepostingTask, task_queue, max_count, count)); + FROM_HERE, base::BindOnce(&RepostingTask, task_queue, max_count, count)); } void DelayedTask(int* count_in, int* count_out) { @@ -141,7 +141,8 @@ int delayed_task_run_at_count = 0; RepostingTask(task_queue_, 1000, &count); task_queue_->PostDelayedTask( - FROM_HERE, base::Bind(DelayedTask, &count, &delayed_task_run_at_count), + FROM_HERE, + base::BindOnce(DelayedTask, &count, &delayed_task_run_at_count), base::TimeDelta::FromMilliseconds(10)); mock_task_runner_->RunUntilIdle(); @@ -159,7 +160,8 @@ int delayed_task_run_at_count = 0; RepostingTask(task_queue_, 1000, &count); task_queue_->PostDelayedTask( - FROM_HERE, base::Bind(DelayedTask, &count, &delayed_task_run_at_count), + FROM_HERE, + base::BindOnce(DelayedTask, &count, &delayed_task_run_at_count), base::TimeDelta::FromMilliseconds(10)); mock_task_runner_->RunUntilIdle();
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc index a6b9af1..b607860 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.cc
@@ -72,7 +72,7 @@ } void CPUTimeBudgetPool::SetReportingCallback( - base::Callback<void(base::TimeDelta)> reporting_callback) { + base::RepeatingCallback<void(base::TimeDelta)> reporting_callback) { reporting_callback_ = reporting_callback; }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.h b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.h index b5126c59..0b6c89e 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/cpu_time_budget_pool.h
@@ -69,7 +69,7 @@ // is throttled. Throttling duration (time until the queue is allowed // to run again) is passed as a parameter to callback. void SetReportingCallback( - base::Callback<void(base::TimeDelta)> reporting_callback); + base::RepeatingCallback<void(base::TimeDelta)> reporting_callback); // BudgetPool implementation: void RecordTaskRunTime(TaskQueue* queue, @@ -122,7 +122,7 @@ base::TimeTicks last_checkpoint_; double cpu_percentage_; - base::Callback<void(base::TimeDelta)> reporting_callback_; + base::RepeatingCallback<void(base::TimeDelta)> reporting_callback_; DISALLOW_COPY_AND_ASSIGN(CPUTimeBudgetPool); };
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner.cc b/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner.cc index c1f8443..610d083 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner.cc
@@ -10,11 +10,11 @@ namespace scheduler { DeadlineTaskRunner::DeadlineTaskRunner( - const base::Closure& callback, + const base::RepeatingClosure& callback, scoped_refptr<base::SingleThreadTaskRunner> task_runner) : callback_(callback), task_runner_(task_runner) { - cancelable_run_internal_.Reset( - base::Bind(&DeadlineTaskRunner::RunInternal, base::Unretained(this))); + cancelable_run_internal_.Reset(base::BindRepeating( + &DeadlineTaskRunner::RunInternal, base::Unretained(this))); } DeadlineTaskRunner::~DeadlineTaskRunner() = default;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner.h b/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner.h index 9041e00..1c74fa09 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner.h
@@ -18,7 +18,7 @@ // Runs a posted task at latest by a given deadline, but possibly sooner. class PLATFORM_EXPORT DeadlineTaskRunner { public: - DeadlineTaskRunner(const base::Closure& callback, + DeadlineTaskRunner(const base::RepeatingClosure& callback, scoped_refptr<base::SingleThreadTaskRunner> task_runner); ~DeadlineTaskRunner(); @@ -38,7 +38,7 @@ void RunInternal(); CancelableClosureHolder cancelable_run_internal_; - base::Closure callback_; + base::RepeatingClosure callback_; base::TimeTicks deadline_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner_unittest.cc index 1b9f6bd..0fcaa7a 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/deadline_task_runner_unittest.cc
@@ -24,7 +24,8 @@ clock_->Advance(base::TimeDelta::FromMicroseconds(5000)); mock_task_runner_ = new cc::OrderedSimpleTaskRunner(clock_.get(), true); deadline_task_runner_.reset(new DeadlineTaskRunner( - base::Bind(&DeadlineTaskRunnerTest::TestTask, base::Unretained(this)), + base::BindRepeating(&DeadlineTaskRunnerTest::TestTask, + base::Unretained(this)), mock_task_runner_)); run_times_.clear(); }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/main_thread_task_queue.cc b/third_party/WebKit/Source/platform/scheduler/renderer/main_thread_task_queue.cc index 40f2b57..5cd6ec7ce 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/main_thread_task_queue.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/main_thread_task_queue.cc
@@ -102,9 +102,9 @@ web_frame_scheduler_(nullptr) { if (GetTaskQueueImpl()) { // TaskQueueImpl may be null for tests. - GetTaskQueueImpl()->SetOnTaskStartedHandler(base::Bind( + GetTaskQueueImpl()->SetOnTaskStartedHandler(base::BindRepeating( &MainThreadTaskQueue::OnTaskStarted, base::Unretained(this))); - GetTaskQueueImpl()->SetOnTaskCompletedHandler(base::Bind( + GetTaskQueueImpl()->SetOnTaskCompletedHandler(base::BindRepeating( &MainThreadTaskQueue::OnTaskCompleted, base::Unretained(this))); } }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_metrics_helper.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_metrics_helper.cc index 31c03bc..d09df5d 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_metrics_helper.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_metrics_helper.cc
@@ -47,18 +47,20 @@ renderer_scheduler_(renderer_scheduler), main_thread_load_tracker( now, - base::Bind(&RendererMetricsHelper::RecordMainThreadTaskLoad, - base::Unretained(this)), + base::BindRepeating(&RendererMetricsHelper::RecordMainThreadTaskLoad, + base::Unretained(this)), kThreadLoadTrackerReportingInterval), background_main_thread_load_tracker( now, - base::Bind(&RendererMetricsHelper::RecordBackgroundMainThreadTaskLoad, - base::Unretained(this)), + base::BindRepeating( + &RendererMetricsHelper::RecordBackgroundMainThreadTaskLoad, + base::Unretained(this)), kThreadLoadTrackerReportingInterval), foreground_main_thread_load_tracker( now, - base::Bind(&RendererMetricsHelper::RecordForegroundMainThreadTaskLoad, - base::Unretained(this)), + base::BindRepeating( + &RendererMetricsHelper::RecordForegroundMainThreadTaskLoad, + base::Unretained(this)), kThreadLoadTrackerReportingInterval), per_queue_type_task_duration_reporter( DURATION_PER_QUEUE_TYPE_METRIC_NAME),
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc index 91e7efa..297b32a6 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl.cc
@@ -236,8 +236,8 @@ input_task_queue_enabled_voter_( input_task_queue_->CreateQueueEnabledVoter()), delayed_update_policy_runner_( - base::Bind(&RendererSchedulerImpl::UpdatePolicy, - base::Unretained(this)), + base::BindRepeating(&RendererSchedulerImpl::UpdatePolicy, + base::Unretained(this)), helper_.ControlMainThreadTaskQueue()), seqlock_queueing_time_estimator_( QueueingTimeEstimator(this, kQueueingTimeWindowDuration, 20)), @@ -250,9 +250,9 @@ weak_factory_(this) { task_queue_throttler_.reset( new TaskQueueThrottler(this, &tracing_controller_)); - update_policy_closure_ = base::Bind(&RendererSchedulerImpl::UpdatePolicy, - weak_factory_.GetWeakPtr()); - end_renderer_hidden_idle_period_closure_.Reset(base::Bind( + update_policy_closure_ = base::BindRepeating( + &RendererSchedulerImpl::UpdatePolicy, weak_factory_.GetWeakPtr()); + end_renderer_hidden_idle_period_closure_.Reset(base::BindRepeating( &RendererSchedulerImpl::EndIdlePeriod, weak_factory_.GetWeakPtr())); // Compositor task queue and default task queue should be managed by @@ -1267,8 +1267,8 @@ const base::Closure& callback) { main_thread_only().in_idle_period_for_testing = true; IdleTaskRunner()->PostIdleTask( - FROM_HERE, base::Bind(&RendererSchedulerImpl::EndIdlePeriodForTesting, - weak_factory_.GetWeakPtr(), callback)); + FROM_HERE, base::BindOnce(&RendererSchedulerImpl::EndIdlePeriodForTesting, + weak_factory_.GetWeakPtr(), callback)); idle_helper_.EnableLongIdlePeriod(); }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc index d666bde5..604f7dce 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/renderer_scheduler_impl_unittest.cc
@@ -63,10 +63,10 @@ int max_reentrant_count) { vector->push_back((*reentrant_count)++); if (*reentrant_count < max_reentrant_count) { - task_runner->PostTask( - FROM_HERE, - base::Bind(AppendToVectorReentrantTask, base::Unretained(task_runner), - vector, reentrant_count, max_reentrant_count)); + task_runner->PostTask(FROM_HERE, + base::BindOnce(AppendToVectorReentrantTask, + base::Unretained(task_runner), vector, + reentrant_count, max_reentrant_count)); } } @@ -84,8 +84,9 @@ base::TimeTicks deadline) { if ((*run_count + 1) < g_max_idle_task_reposts) { idle_task_runner->PostIdleTask( - FROM_HERE, base::Bind(&RepostingIdleTestTask, - base::Unretained(idle_task_runner), run_count)); + FROM_HERE, + base::BindOnce(&RepostingIdleTestTask, + base::Unretained(idle_task_runner), run_count)); } (*run_count)++; } @@ -99,9 +100,9 @@ base::TimeTicks deadline) { if ((*run_count + 1) < g_max_idle_task_reposts) { idle_task_runner->PostIdleTask( - FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask, - base::Unretained(idle_task_runner), run_count, - clock, advance_time, deadlines)); + FROM_HERE, base::BindOnce(&RepostingUpdateClockIdleTestTask, + base::Unretained(idle_task_runner), run_count, + clock, advance_time, deadlines)); } deadlines->push_back(deadline); (*run_count)++; @@ -131,7 +132,7 @@ bool* should_yield_before, bool* should_yield_after) { *should_yield_before = scheduler->ShouldYieldForHighPriorityWork(); - task_runner->PostTask(FROM_HERE, base::Bind(NullTask)); + task_runner->PostTask(FROM_HERE, base::BindOnce(NullTask)); if (simulate_input) { scheduler->DidHandleInputEventOnCompositorThread( FakeInputEvent(blink::WebInputEvent::kTouchMove), @@ -267,14 +268,14 @@ using UseCase = RendererSchedulerImpl::UseCase; RendererSchedulerImplTest() - : fake_task_(TaskQueue::PostedTask(base::Bind([] {}), FROM_HERE), + : fake_task_(TaskQueue::PostedTask(base::BindOnce([] {}), FROM_HERE), base::TimeTicks()) { feature_list_.InitAndEnableFeature(kHighPriorityInput); clock_.Advance(base::TimeDelta::FromMicroseconds(5000)); } RendererSchedulerImplTest(base::MessageLoop* message_loop) - : fake_task_(TaskQueue::PostedTask(base::Bind([] {}), FROM_HERE), + : fake_task_(TaskQueue::PostedTask(base::BindOnce([] {}), FROM_HERE), base::TimeTicks()), message_loop_(message_loop) { clock_.Advance(base::TimeDelta::FromMicroseconds(5000)); @@ -380,10 +381,10 @@ // Simulate a bunch of expensive tasks for (int i = 0; i < 10; i++) { - task_runner->PostTask(FROM_HERE, - base::Bind(&base::SimpleTestTickClock::Advance, - base::Unretained(&clock_), - base::TimeDelta::FromMilliseconds(500))); + task_runner->PostTask( + FROM_HERE, base::BindOnce(&base::SimpleTestTickClock::Advance, + base::Unretained(&clock_), + base::TimeDelta::FromMilliseconds(500))); } RunUntilIdle(); @@ -606,9 +607,9 @@ // slow and thus compositor tasks will not be prioritized. compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(1000))); + base::BindOnce( + &RendererSchedulerImplTest::SimulateMainThreadCompositorTask, + base::Unretained(this), base::TimeDelta::FromMilliseconds(1000))); RunUntilIdle(); } @@ -632,36 +633,43 @@ switch (task[0]) { case 'D': default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); + FROM_HERE, + base::BindOnce(&AppendToVectorTestTask, run_order, task)); break; case 'C': compositor_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); + FROM_HERE, + base::BindOnce(&AppendToVectorTestTask, run_order, task)); break; case 'P': input_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); + FROM_HERE, + base::BindOnce(&AppendToVectorTestTask, run_order, task)); break; case 'L': loading_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); + FROM_HERE, + base::BindOnce(&AppendToVectorTestTask, run_order, task)); break; case 'M': loading_control_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); + FROM_HERE, + base::BindOnce(&AppendToVectorTestTask, run_order, task)); break; case 'I': idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&AppendToVectorIdleTestTask, run_order, task)); + base::BindOnce(&AppendToVectorIdleTestTask, run_order, task)); break; case 'T': timer_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); + FROM_HERE, + base::BindOnce(&AppendToVectorTestTask, run_order, task)); break; case 'V': v8_task_runner_->PostTask( - FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); + FROM_HERE, + base::BindOnce(&AppendToVectorTestTask, run_order, task)); break; default: NOTREACHED(); @@ -773,9 +781,9 @@ int count = 0; std::vector<int> run_order; default_task_runner_->PostTask( - FROM_HERE, base::Bind(AppendToVectorReentrantTask, - base::RetainedRef(default_task_runner_), &run_order, - &count, 5)); + FROM_HERE, base::BindOnce(AppendToVectorReentrantTask, + base::RetainedRef(default_task_runner_), + &run_order, &count, 5)); RunUntilIdle(); EXPECT_THAT(run_order, ::testing::ElementsAre(0, 1, 2, 3, 4)); @@ -789,7 +797,7 @@ clock_.Advance(base::TimeDelta::FromMilliseconds(100)); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); RunUntilIdle(); EXPECT_EQ(0, run_count); // Shouldn't run yet as no WillBeginFrame. @@ -822,8 +830,9 @@ g_max_idle_task_reposts = 2; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&RepostingIdleTestTask, - base::RetainedRef(idle_task_runner_), &run_count)); + FROM_HERE, + base::BindOnce(&RepostingIdleTestTask, + base::RetainedRef(idle_task_runner_), &run_count)); EnableIdleTasks(); RunUntilIdle(); EXPECT_EQ(1, run_count); @@ -844,10 +853,10 @@ // Post two UpdateClockToDeadlineIdleTestTask tasks. idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count)); + base::BindOnce(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count)); idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count)); + base::BindOnce(&UpdateClockToDeadlineIdleTestTask, &clock_, &run_count)); EnableIdleTasks(); RunUntilIdle(); @@ -865,7 +874,7 @@ base::TimeTicks deadline_in_task; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); // Trigger the beginning of an idle period for 1000ms. scheduler_->WillBeginFrame(viz::BeginFrameArgs::Create( @@ -892,7 +901,7 @@ // Post a task which simulates running until after the previous end idle // period delayed task was scheduled for - scheduler_->DefaultTaskQueue()->PostTask(FROM_HERE, base::Bind(NullTask)); + scheduler_->DefaultTaskQueue()->PostTask(FROM_HERE, base::BindOnce(NullTask)); clock_.Advance(base::TimeDelta::FromMilliseconds(300)); RunUntilIdle(); @@ -1644,7 +1653,7 @@ PostTestTasks(&run_order, "D1 C1"); for (int i = 0; i < 20; i++) { - compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); + compositor_task_runner_->PostTask(FROM_HERE, base::BindOnce(&NullTask)); } PostTestTasks(&run_order, "C2"); @@ -1743,9 +1752,9 @@ scheduler_->SetHasVisibleRenderWidgetWithTouchHandler(true); default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(), - SimulateInputType::kNone, &is_anticipated_before, - &is_anticipated_after)); + FROM_HERE, base::BindOnce(&AnticipationTestTask, scheduler_.get(), + SimulateInputType::kNone, + &is_anticipated_before, &is_anticipated_after)); RunUntilIdle(); // In its default state, without input receipt, the scheduler should indicate // that no high-priority is anticipated. @@ -1753,21 +1762,21 @@ EXPECT_FALSE(is_anticipated_after); default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(), - SimulateInputType::kTouchStart, - &is_anticipated_before, &is_anticipated_after)); + FROM_HERE, base::BindOnce(&AnticipationTestTask, scheduler_.get(), + SimulateInputType::kTouchStart, + &is_anticipated_before, &is_anticipated_after)); bool dummy; default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(), - SimulateInputType::kTouchEnd, &dummy, &dummy)); + FROM_HERE, base::BindOnce(&AnticipationTestTask, scheduler_.get(), + SimulateInputType::kTouchEnd, &dummy, &dummy)); default_task_runner_->PostTask( FROM_HERE, - base::Bind(&AnticipationTestTask, scheduler_.get(), - SimulateInputType::kGestureScrollBegin, &dummy, &dummy)); + base::BindOnce(&AnticipationTestTask, scheduler_.get(), + SimulateInputType::kGestureScrollBegin, &dummy, &dummy)); default_task_runner_->PostTask( FROM_HERE, - base::Bind(&AnticipationTestTask, scheduler_.get(), - SimulateInputType::kGestureScrollEnd, &dummy, &dummy)); + base::BindOnce(&AnticipationTestTask, scheduler_.get(), + SimulateInputType::kGestureScrollEnd, &dummy, &dummy)); RunUntilIdle(); // When input is received, the scheduler should indicate that high-priority @@ -1777,9 +1786,9 @@ clock_.Advance(priority_escalation_after_input_duration() * 2); default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(), - SimulateInputType::kNone, &is_anticipated_before, - &is_anticipated_after)); + FROM_HERE, base::BindOnce(&AnticipationTestTask, scheduler_.get(), + SimulateInputType::kNone, + &is_anticipated_before, &is_anticipated_after)); RunUntilIdle(); // Without additional input, the scheduler should go into NONE // use case but with scrolling expected where high-priority work is still @@ -1791,9 +1800,9 @@ clock_.Advance(subsequent_input_expected_after_input_duration() * 2); default_task_runner_->PostTask( - FROM_HERE, base::Bind(&AnticipationTestTask, scheduler_.get(), - SimulateInputType::kNone, &is_anticipated_before, - &is_anticipated_after)); + FROM_HERE, base::BindOnce(&AnticipationTestTask, scheduler_.get(), + SimulateInputType::kNone, + &is_anticipated_before, &is_anticipated_after)); RunUntilIdle(); // Eventually the scheduler should go into the default use case where // high-priority work is no longer anticipated. @@ -1808,27 +1817,29 @@ bool should_yield_after = false; default_task_runner_->PostTask( - FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(), - base::RetainedRef(default_task_runner_), false, - &should_yield_before, &should_yield_after)); + FROM_HERE, base::BindOnce(&PostingYieldingTestTask, scheduler_.get(), + base::RetainedRef(default_task_runner_), false, + &should_yield_before, &should_yield_after)); RunUntilIdle(); // Posting to default runner shouldn't cause yielding. EXPECT_FALSE(should_yield_before); EXPECT_FALSE(should_yield_after); default_task_runner_->PostTask( - FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(), - base::RetainedRef(compositor_task_runner_), false, - &should_yield_before, &should_yield_after)); + FROM_HERE, + base::BindOnce(&PostingYieldingTestTask, scheduler_.get(), + base::RetainedRef(compositor_task_runner_), false, + &should_yield_before, &should_yield_after)); RunUntilIdle(); // Posting while not mainthread scrolling shouldn't cause yielding. EXPECT_FALSE(should_yield_before); EXPECT_FALSE(should_yield_after); default_task_runner_->PostTask( - FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(), - base::RetainedRef(compositor_task_runner_), true, - &should_yield_before, &should_yield_after)); + FROM_HERE, + base::BindOnce(&PostingYieldingTestTask, scheduler_.get(), + base::RetainedRef(compositor_task_runner_), true, + &should_yield_before, &should_yield_after)); RunUntilIdle(); // We should be able to switch to compositor priority mid-task. EXPECT_FALSE(should_yield_before); @@ -2138,24 +2149,26 @@ std::vector<std::string> order; idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("1"))); + base::BindOnce(&AppendToVectorIdleTestTask, &order, std::string("1"))); idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("2"))); + base::BindOnce(&AppendToVectorIdleTestTask, &order, std::string("2"))); std::vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>> tasks_to_post_from_nested_loop; tasks_to_post_from_nested_loop.push_back(std::make_pair( - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("3")), + base::BindOnce(&AppendToVectorIdleTestTask, &order, std::string("3")), false)); tasks_to_post_from_nested_loop.push_back(std::make_pair( - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("4")), true)); + base::BindOnce(&AppendToVectorIdleTestTask, &order, std::string("4")), + true)); tasks_to_post_from_nested_loop.push_back(std::make_pair( - base::Bind(&AppendToVectorIdleTestTask, &order, std::string("5")), true)); + base::BindOnce(&AppendToVectorIdleTestTask, &order, std::string("5")), + true)); default_task_runner_->PostTask( FROM_HERE, - base::Bind( + base::BindOnce( &RendererSchedulerImplWithMessageLoopTest::PostFromNestedRunloop, base::Unretained(this), base::Unretained(&tasks_to_post_from_nested_loop))); @@ -2175,7 +2188,7 @@ int run_count = 0; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); RunUntilIdle(); EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period. @@ -2197,7 +2210,7 @@ int run_count = 0; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); RunUntilIdle(); EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period. @@ -2215,8 +2228,8 @@ int run_count = 0; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); + default_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NullTask), pending_task_delay); scheduler_->BeginFrameNotExpectedSoon(); @@ -2231,7 +2244,7 @@ base::TimeTicks deadline_in_task; int run_count = 0; - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), + default_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NullTask), pending_task_delay); // Advance clock until after delayed task was meant to be run. @@ -2241,7 +2254,7 @@ // period. Since there is a late pending delayed task this shouldn't actually // start an idle period. idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); scheduler_->BeginFrameNotExpectedSoon(); RunUntilIdle(); EXPECT_EQ(0, run_count); @@ -2261,9 +2274,10 @@ base::TimeTicks clock_before(clock_.NowTicks()); base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10)); idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask, - base::RetainedRef(idle_task_runner_), &run_count, - &clock_, idle_task_runtime, &actual_deadlines)); + FROM_HERE, + base::BindOnce(&RepostingUpdateClockIdleTestTask, + base::RetainedRef(idle_task_runner_), &run_count, &clock_, + idle_task_runtime, &actual_deadlines)); scheduler_->BeginFrameNotExpectedSoon(); RunUntilIdle(); EXPECT_EQ(3, run_count); @@ -2277,13 +2291,14 @@ // new BeginMainFrame. g_max_idle_task_reposts = 5; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask, - base::RetainedRef(idle_task_runner_), &run_count, - &clock_, idle_task_runtime, &actual_deadlines)); - idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&WillBeginFrameIdleTask, base::Unretained(scheduler_.get()), - next_begin_frame_number_++, &clock_)); + base::BindOnce(&RepostingUpdateClockIdleTestTask, + base::RetainedRef(idle_task_runner_), &run_count, &clock_, + idle_task_runtime, &actual_deadlines)); + idle_task_runner_->PostIdleTask( + FROM_HERE, base::BindOnce(&WillBeginFrameIdleTask, + base::Unretained(scheduler_.get()), + next_begin_frame_number_++, &clock_)); RunUntilIdle(); EXPECT_EQ(4, run_count); } @@ -2294,7 +2309,7 @@ int run_count = 0; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); + FROM_HERE, base::BindOnce(&IdleTestTask, &run_count, &deadline_in_task)); // Observation of touchstart should defer the start of the long idle period. scheduler_->DidHandleInputEventOnCompositorThread( @@ -2328,8 +2343,8 @@ // Should return false for short idle periods. idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(), - &can_exceed_idle_deadline, &run_count)); + base::BindOnce(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(), + &can_exceed_idle_deadline, &run_count)); EnableIdleTasks(); RunUntilIdle(); EXPECT_EQ(1, run_count); @@ -2337,12 +2352,12 @@ // Should return false for a long idle period which is shortened due to a // pending delayed task. - default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), + default_task_runner_->PostDelayedTask(FROM_HERE, base::BindOnce(&NullTask), base::TimeDelta::FromMilliseconds(10)); idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(), - &can_exceed_idle_deadline, &run_count)); + base::BindOnce(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(), + &can_exceed_idle_deadline, &run_count)); scheduler_->BeginFrameNotExpectedSoon(); RunUntilIdle(); EXPECT_EQ(2, run_count); @@ -2353,8 +2368,8 @@ clock_.Advance(maximum_idle_period_duration()); idle_task_runner_->PostIdleTask( FROM_HERE, - base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(), - &can_exceed_idle_deadline, &run_count)); + base::BindOnce(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(), + &can_exceed_idle_deadline, &run_count)); RunUntilIdle(); EXPECT_EQ(3, run_count); EXPECT_TRUE(can_exceed_idle_deadline); @@ -2375,8 +2390,9 @@ g_max_idle_task_reposts = 2; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&RepostingIdleTestTask, - base::RetainedRef(idle_task_runner_), &run_count)); + FROM_HERE, + base::BindOnce(&RepostingIdleTestTask, + base::RetainedRef(idle_task_runner_), &run_count)); // Renderer should start in visible state. RunUntilIdle(); @@ -2393,8 +2409,9 @@ // idle tasks when hidden (plus some slack) - idle period should have ended. g_max_idle_task_reposts = 3; idle_task_runner_->PostIdleTask( - FROM_HERE, base::Bind(&RepostingIdleTestTask, - base::RetainedRef(idle_task_runner_), &run_count)); + FROM_HERE, + base::BindOnce(&RepostingIdleTestTask, + base::RetainedRef(idle_task_runner_), &run_count)); clock_.Advance(end_idle_when_hidden_delay() + base::TimeDelta::FromMilliseconds(10)); RunUntilIdle(); @@ -3015,14 +3032,15 @@ scheduler_->WillBeginFrame(begin_frame_args); compositor_task_runner_->PostTask( - FROM_HERE, base::Bind(&RendererSchedulerImplTest:: - SimulateMainThreadInputHandlingCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(8))); + FROM_HERE, + base::BindOnce(&RendererSchedulerImplTest:: + SimulateMainThreadInputHandlingCompositorTask, + base::Unretained(this), + base::TimeDelta::FromMilliseconds(8))); timer_task_runner_->PostTask( - FROM_HERE, base::Bind(&RendererSchedulerImplTest::SimulateTimerTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(4))); + FROM_HERE, base::BindOnce(&RendererSchedulerImplTest::SimulateTimerTask, + base::Unretained(this), + base::TimeDelta::FromMilliseconds(4))); RunUntilIdle(); EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i; @@ -3056,13 +3074,13 @@ compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(8))); + base::BindOnce( + &RendererSchedulerImplTest::SimulateMainThreadCompositorTask, + base::Unretained(this), base::TimeDelta::FromMilliseconds(8))); timer_task_runner_->PostTask( - FROM_HERE, base::Bind(&RendererSchedulerImplTest::SimulateTimerTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(40))); + FROM_HERE, base::BindOnce(&RendererSchedulerImplTest::SimulateTimerTask, + base::Unretained(this), + base::TimeDelta::FromMilliseconds(40))); RunUntilIdle(); EXPECT_TRUE(simulate_timer_task_ran_) << " i = " << i; @@ -3096,14 +3114,15 @@ scheduler_->WillBeginFrame(begin_frame_args); compositor_task_runner_->PostTask( - FROM_HERE, base::Bind(&RendererSchedulerImplTest:: - SimulateMainThreadInputHandlingCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(8))); + FROM_HERE, + base::BindOnce(&RendererSchedulerImplTest:: + SimulateMainThreadInputHandlingCompositorTask, + base::Unretained(this), + base::TimeDelta::FromMilliseconds(8))); timer_task_runner_->PostTask( - FROM_HERE, base::Bind(&RendererSchedulerImplTest::SimulateTimerTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(10))); + FROM_HERE, base::BindOnce(&RendererSchedulerImplTest::SimulateTimerTask, + base::Unretained(this), + base::TimeDelta::FromMilliseconds(10))); RunUntilIdle(); EXPECT_EQ(RendererSchedulerImpl::UseCase::kMainThreadCustomInputHandling, @@ -3162,9 +3181,10 @@ compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest:: - SimulateMainThreadInputHandlingCompositorTask, - base::Unretained(this), base::TimeDelta::FromMilliseconds(5))); + base::BindOnce(&RendererSchedulerImplTest:: + SimulateMainThreadInputHandlingCompositorTask, + base::Unretained(this), + base::TimeDelta::FromMilliseconds(5))); RunUntilIdle(); EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase()); @@ -3186,9 +3206,10 @@ compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest:: - SimulateMainThreadInputHandlingCompositorTask, - base::Unretained(this), base::TimeDelta::FromMilliseconds(5))); + base::BindOnce(&RendererSchedulerImplTest:: + SimulateMainThreadInputHandlingCompositorTask, + base::Unretained(this), + base::TimeDelta::FromMilliseconds(5))); RunUntilIdle(); EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase()); @@ -3211,8 +3232,9 @@ compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask, - base::Unretained(this), base::TimeDelta::FromMilliseconds(5))); + base::BindOnce( + &RendererSchedulerImplTest::SimulateMainThreadCompositorTask, + base::Unretained(this), base::TimeDelta::FromMilliseconds(5))); RunUntilIdle(); EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()); @@ -3249,8 +3271,9 @@ scoped_refptr<base::SingleThreadTaskRunner> timer_queue) { clock->Advance(base::TimeDelta::FromMilliseconds(task_duration)); if (++(*count) < 500) { - timer_queue->PostTask(FROM_HERE, base::Bind(SlowCountingTask, count, clock, - task_duration, timer_queue)); + timer_queue->PostTask( + FROM_HERE, base::BindOnce(SlowCountingTask, count, clock, task_duration, + timer_queue)); } } } @@ -3283,13 +3306,13 @@ simulate_compositor_task_ran_ = false; compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(10))); + base::BindOnce( + &RendererSchedulerImplTest::SimulateMainThreadCompositorTask, + base::Unretained(this), base::TimeDelta::FromMilliseconds(10))); - mock_task_runner_->RunTasksWhile( - base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending, - base::Unretained(this))); + mock_task_runner_->RunTasksWhile(base::BindRepeating( + &RendererSchedulerImplTest::SimulatedCompositorTaskPending, + base::Unretained(this))); EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i; // We expect the queue to get throttled on the second iteration which is @@ -3347,13 +3370,13 @@ simulate_compositor_task_ran_ = false; compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(10))); + base::BindOnce( + &RendererSchedulerImplTest::SimulateMainThreadCompositorTask, + base::Unretained(this), base::TimeDelta::FromMilliseconds(10))); - mock_task_runner_->RunTasksWhile( - base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending, - base::Unretained(this))); + mock_task_runner_->RunTasksWhile(base::BindRepeating( + &RendererSchedulerImplTest::SimulatedCompositorTaskPending, + base::Unretained(this))); EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i; // Before the policy is updated the queue will be enabled. Subsequently it @@ -3403,13 +3426,13 @@ simulate_compositor_task_ran_ = false; compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(10))); + base::BindOnce( + &RendererSchedulerImplTest::SimulateMainThreadCompositorTask, + base::Unretained(this), base::TimeDelta::FromMilliseconds(10))); - mock_task_runner_->RunTasksWhile( - base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending, - base::Unretained(this))); + mock_task_runner_->RunTasksWhile(base::BindRepeating( + &RendererSchedulerImplTest::SimulatedCompositorTaskPending, + base::Unretained(this))); EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i; EXPECT_TRUE(timer_task_runner_->IsQueueEnabled()) << "i = " << i; } @@ -3505,13 +3528,13 @@ simulate_compositor_task_ran_ = false; compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(20))); + base::BindOnce( + &RendererSchedulerImplTest::SimulateMainThreadCompositorTask, + base::Unretained(this), base::TimeDelta::FromMilliseconds(20))); - mock_task_runner_->RunTasksWhile( - base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending, - base::Unretained(this))); + mock_task_runner_->RunTasksWhile(base::BindRepeating( + &RendererSchedulerImplTest::SimulatedCompositorTaskPending, + base::Unretained(this))); EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i; } @@ -3547,13 +3570,13 @@ simulate_compositor_task_ran_ = false; compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(20))); + base::BindOnce( + &RendererSchedulerImplTest::SimulateMainThreadCompositorTask, + base::Unretained(this), base::TimeDelta::FromMilliseconds(20))); - mock_task_runner_->RunTasksWhile( - base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending, - base::Unretained(this))); + mock_task_runner_->RunTasksWhile(base::BindRepeating( + &RendererSchedulerImplTest::SimulatedCompositorTaskPending, + base::Unretained(this))); EXPECT_EQ(UseCase::kMainThreadCustomInputHandling, CurrentUseCase()) << "i = " << i; } @@ -3591,13 +3614,13 @@ simulate_compositor_task_ran_ = false; compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(20))); + base::BindOnce( + &RendererSchedulerImplTest::SimulateMainThreadCompositorTask, + base::Unretained(this), base::TimeDelta::FromMilliseconds(20))); - mock_task_runner_->RunTasksWhile( - base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending, - base::Unretained(this))); + mock_task_runner_->RunTasksWhile(base::BindRepeating( + &RendererSchedulerImplTest::SimulatedCompositorTaskPending, + base::Unretained(this))); EXPECT_EQ(UseCase::kMainThreadGesture, CurrentUseCase()) << "i = " << i; } @@ -3696,11 +3719,11 @@ size_t timer_count = 0; size_t unthrottled_count = 0; timer_task_runner_->PostTask( - FROM_HERE, base::Bind(SlowCountingTask, &timer_count, &clock_, 7, - timer_task_runner_)); + FROM_HERE, base::BindOnce(SlowCountingTask, &timer_count, &clock_, 7, + timer_task_runner_)); unthrottled_task_runner->PostTask( - FROM_HERE, base::Bind(SlowCountingTask, &unthrottled_count, &clock_, 7, - unthrottled_task_runner)); + FROM_HERE, base::BindOnce(SlowCountingTask, &unthrottled_count, &clock_, + 7, unthrottled_task_runner)); auto handle = scheduler_->PauseRenderer(); for (int i = 0; i < 1000; i++) { @@ -3717,13 +3740,13 @@ simulate_compositor_task_ran_ = false; compositor_task_runner_->PostTask( FROM_HERE, - base::Bind(&RendererSchedulerImplTest::SimulateMainThreadCompositorTask, - base::Unretained(this), - base::TimeDelta::FromMilliseconds(10))); + base::BindOnce( + &RendererSchedulerImplTest::SimulateMainThreadCompositorTask, + base::Unretained(this), base::TimeDelta::FromMilliseconds(10))); - mock_task_runner_->RunTasksWhile( - base::Bind(&RendererSchedulerImplTest::SimulatedCompositorTaskPending, - base::Unretained(this))); + mock_task_runner_->RunTasksWhile(base::BindRepeating( + &RendererSchedulerImplTest::SimulatedCompositorTaskPending, + base::Unretained(this))); EXPECT_EQ(UseCase::kSynchronizedGesture, CurrentUseCase()) << "i = " << i; } @@ -3928,7 +3951,7 @@ std::vector<base::TimeTicks> run_times; timer_task_runner_->PostTask( - FROM_HERE, base::Bind(&RecordingTimeTestTask, &run_times, &clock_)); + FROM_HERE, base::BindOnce(&RecordingTimeTestTask, &run_times, &clock_)); mock_task_runner_->RunUntilTime(base::TimeTicks() + base::TimeDelta::FromMilliseconds(1100)); @@ -3939,7 +3962,7 @@ run_times.clear(); timer_task_runner_->PostDelayedTask( - FROM_HERE, base::Bind(&RecordingTimeTestTask, &run_times, &clock_), + FROM_HERE, base::BindOnce(&RecordingTimeTestTask, &run_times, &clock_), base::TimeDelta::FromMilliseconds(200)); scheduler_->SetRendererBackgrounded(false);
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc index cc562ee9..362b8ca2 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.cc
@@ -73,11 +73,11 @@ time_domain_(new ThrottledTimeDomain()), allow_throttling_(true), weak_factory_(this) { - pump_throttled_tasks_closure_.Reset(base::Bind( + pump_throttled_tasks_closure_.Reset(base::BindRepeating( &TaskQueueThrottler::PumpThrottledTasks, weak_factory_.GetWeakPtr())); forward_immediate_work_callback_ = - base::Bind(&TaskQueueThrottler::OnQueueNextWakeUpChanged, - weak_factory_.GetWeakPtr()); + base::BindRepeating(&TaskQueueThrottler::OnQueueNextWakeUpChanged, + weak_factory_.GetWeakPtr()); renderer_scheduler_->RegisterTimeDomain(time_domain_.get()); } @@ -193,8 +193,8 @@ base::TimeTicks next_wake_up) { if (!control_task_queue_->RunsTasksInCurrentSequence()) { control_task_queue_->PostTask( - FROM_HERE, base::Bind(forward_immediate_work_callback_, - base::RetainedRef(queue), next_wake_up)); + FROM_HERE, base::BindOnce(forward_immediate_work_callback_, + base::RetainedRef(queue), next_wake_up)); return; }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h index ed152ba..9fc34d5 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/task_queue_throttler.h
@@ -198,7 +198,7 @@ TaskQueue* queue); TaskQueueMap queue_details_; - base::Callback<void(TaskQueue*, base::TimeTicks)> + base::RepeatingCallback<void(TaskQueue*, base::TimeTicks)> forward_immediate_work_callback_; scoped_refptr<TaskQueue> control_task_queue_; RendererSchedulerImpl* renderer_scheduler_; // NOT OWNED
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc index d36288b..e22e088 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.cc
@@ -122,6 +122,7 @@ this, &tracing_controller_, CrossOriginStateToString), + url_tracer_("WebFrameScheduler.URL", this), frame_type_(frame_type), active_connection_count_(0), weak_factory_(this) { @@ -228,6 +229,10 @@ return cross_origin_; } +void WebFrameSchedulerImpl::TraceUrlChange(const String& url) { + url_tracer_.TraceString(url); +} + WebFrameScheduler::FrameType WebFrameSchedulerImpl::GetFrameType() const { return frame_type_; }
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h index 742a584..5b29344 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl.h
@@ -17,7 +17,6 @@ #include "platform/scheduler/child/page_visibility_state.h" #include "platform/scheduler/child/worker_scheduler_proxy.h" #include "platform/scheduler/util/tracing_helper.h" -#include "platform/wtf/HashSet.h" namespace base { namespace trace_event { @@ -67,6 +66,7 @@ void SetCrossOrigin(bool cross_origin) override; bool IsCrossOrigin() const override; + void TraceUrlChange(const String& url) override; WebFrameScheduler::FrameType GetFrameType() const override; scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner(TaskType) override; WebViewScheduler* GetWebViewScheduler() const override; @@ -166,6 +166,7 @@ TraceableState<bool, kTracingCategoryNameInfo> page_frozen_; TraceableState<bool, kTracingCategoryNameInfo> frame_paused_; TraceableState<bool, kTracingCategoryNameInfo> cross_origin_; + StateTracer<kTracingCategoryNameInfo> url_tracer_; WebFrameScheduler::FrameType frame_type_; int active_connection_count_;
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc index cd5252e..cd8018e01 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_frame_scheduler_impl_unittest.cc
@@ -115,10 +115,10 @@ void RunRepeatingTask(scoped_refptr<TaskQueue> task_queue, int* run_count); -base::Closure MakeRepeatingTask(scoped_refptr<TaskQueue> task_queue, - int* run_count) { - return base::Bind(&RunRepeatingTask, base::Passed(std::move(task_queue)), - base::Unretained(run_count)); +base::OnceClosure MakeRepeatingTask(scoped_refptr<TaskQueue> task_queue, + int* run_count) { + return base::BindOnce(&RunRepeatingTask, std::move(task_queue), + base::Unretained(run_count)); } void RunRepeatingTask(scoped_refptr<TaskQueue> task_queue, int* run_count) { @@ -240,15 +240,15 @@ TEST_F(WebFrameSchedulerImplTest, PauseAndResume) { int counter = 0; LoadingTaskQueue()->PostTask( - FROM_HERE, base::Bind(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); ThrottleableTaskQueue()->PostTask( - FROM_HERE, base::Bind(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); DeferrableTaskQueue()->PostTask( - FROM_HERE, base::Bind(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); PausableTaskQueue()->PostTask( - FROM_HERE, base::Bind(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); UnpausableTaskQueue()->PostTask( - FROM_HERE, base::Bind(&IncrementCounter, base::Unretained(&counter))); + FROM_HERE, base::BindOnce(&IncrementCounter, base::Unretained(&counter))); web_frame_scheduler_->SetPaused(true);
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc index bfac5416..326ae82 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/web_view_scheduler_impl_unittest.cc
@@ -111,10 +111,10 @@ void RunRepeatingTask(scoped_refptr<TaskQueue> task_queue, int* run_count); -base::Closure MakeRepeatingTask(scoped_refptr<TaskQueue> task_queue, - int* run_count) { - return base::Bind(&RunRepeatingTask, base::Passed(std::move(task_queue)), - base::Unretained(run_count)); +base::OnceClosure MakeRepeatingTask(scoped_refptr<TaskQueue> task_queue, + int* run_count) { + return base::BindOnce(&RunRepeatingTask, std::move(task_queue), + base::Unretained(run_count)); } void RunRepeatingTask(scoped_refptr<TaskQueue> task_queue, int* run_count) { @@ -334,8 +334,9 @@ scoped_refptr<TaskQueue> task_queue, std::vector<int>* out_run_order) { out_run_order->push_back(index); - task_queue->PostTask(FROM_HERE, base::Bind(&RunOrderTask, index + 1, - base::Unretained(out_run_order))); + task_queue->PostTask(FROM_HERE, + base::BindOnce(&RunOrderTask, index + 1, + base::Unretained(out_run_order))); } } @@ -346,18 +347,19 @@ web_view_scheduler_->EnableVirtualTime(); ThrottleableTaskQueue()->PostTask( - FROM_HERE, base::Bind(&RunOrderTask, 0, base::Unretained(&run_order))); + FROM_HERE, + base::BindOnce(&RunOrderTask, 0, base::Unretained(&run_order))); ThrottleableTaskQueue()->PostDelayedTask( FROM_HERE, - base::Bind(&DelayedRunOrderTask, 1, base::Passed(ThrottleableTaskQueue()), - base::Unretained(&run_order)), + base::BindOnce(&DelayedRunOrderTask, 1, ThrottleableTaskQueue(), + base::Unretained(&run_order)), base::TimeDelta::FromMilliseconds(2)); ThrottleableTaskQueue()->PostDelayedTask( FROM_HERE, - base::Bind(&DelayedRunOrderTask, 3, base::Passed(ThrottleableTaskQueue()), - base::Unretained(&run_order)), + base::BindOnce(&DelayedRunOrderTask, 3, ThrottleableTaskQueue(), + base::Unretained(&run_order)), base::TimeDelta::FromMilliseconds(4)); mock_task_runner_->RunUntilIdle(); @@ -373,18 +375,19 @@ web_view_scheduler_->EnableVirtualTime(); ThrottleableTaskQueue()->PostTask( - FROM_HERE, base::Bind(&RunOrderTask, 0, base::Unretained(&run_order))); + FROM_HERE, + base::BindOnce(&RunOrderTask, 0, base::Unretained(&run_order))); ThrottleableTaskQueue()->PostDelayedTask( FROM_HERE, - base::Bind(&DelayedRunOrderTask, 1, base::Passed(ThrottleableTaskQueue()), - base::Unretained(&run_order)), + base::BindOnce(&DelayedRunOrderTask, 1, ThrottleableTaskQueue(), + base::Unretained(&run_order)), base::TimeDelta::FromMilliseconds(2)); ThrottleableTaskQueue()->PostDelayedTask( FROM_HERE, - base::Bind(&DelayedRunOrderTask, 3, base::Passed(ThrottleableTaskQueue()), - base::Unretained(&run_order)), + base::BindOnce(&DelayedRunOrderTask, 3, ThrottleableTaskQueue(), + base::Unretained(&run_order)), base::TimeDelta::FromMilliseconds(4)); mock_task_runner_->RunUntilIdle(); @@ -427,7 +430,8 @@ ThrottleableTaskQueueForScheduler(web_frame_scheduler.get()) ->PostDelayedTask( - FROM_HERE, base::Bind(&RunOrderTask, 1, base::Unretained(&run_order)), + FROM_HERE, + base::BindOnce(&RunOrderTask, 1, base::Unretained(&run_order)), base::TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunUntilIdle(); @@ -442,8 +446,8 @@ namespace { template <typename T> -base::Closure MakeDeletionTask(T* obj) { - return base::Bind([](T* obj) { delete obj; }, base::Unretained(obj)); +base::OnceClosure MakeDeletionTask(T* obj) { + return base::BindOnce([](T* obj) { delete obj; }, base::Unretained(obj)); } } // namespace @@ -597,8 +601,8 @@ web_view_scheduler_->EnableVirtualTime(); ThrottleableTaskQueueForScheduler(web_frame_scheduler.get()) - ->PostTask(FROM_HERE, - base::Bind(&RunOrderTask, 1, base::Unretained(&run_order))); + ->PostTask(FROM_HERE, base::BindOnce(&RunOrderTask, 1, + base::Unretained(&run_order))); mock_task_runner_->RunUntilIdle(); EXPECT_TRUE(run_order.empty()); @@ -698,13 +702,16 @@ web_view_scheduler_->EnableVirtualTime(); ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(200)); + FROM_HERE, base::BindOnce(&NopTask), + base::TimeDelta::FromMilliseconds(200)); ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(20)); + FROM_HERE, base::BindOnce(&NopTask), + base::TimeDelta::FromMilliseconds(20)); ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, base::Bind(&NopTask), base::TimeDelta::FromMilliseconds(2)); + FROM_HERE, base::BindOnce(&NopTask), + base::TimeDelta::FromMilliseconds(2)); web_view_scheduler_->GrantVirtualTimeBudget( base::TimeDelta::FromMilliseconds(1000), @@ -731,8 +738,8 @@ return; task_queue->PostTask(FROM_HERE, - base::Bind(&RepostingTask, task_queue, max_count, - base::Unretained(count))); + base::BindOnce(&RepostingTask, task_queue, max_count, + base::Unretained(count))); } void DelayedTask(int* count_in, int* count_out) { @@ -751,8 +758,8 @@ RepostingTask(ThrottleableTaskQueue(), 1000, &count); ThrottleableTaskQueue()->PostDelayedTask( FROM_HERE, - base::Bind(DelayedTask, base::Unretained(&count), - base::Unretained(&delayed_task_run_at_count)), + base::BindOnce(DelayedTask, base::Unretained(&count), + base::Unretained(&delayed_task_run_at_count)), base::TimeDelta::FromMilliseconds(10)); web_view_scheduler_->GrantVirtualTimeBudget( @@ -782,8 +789,8 @@ RepostingTask(ThrottleableTaskQueue(), 1000, &count); ThrottleableTaskQueue()->PostDelayedTask( FROM_HERE, - base::Bind(DelayedTask, WTF::Unretained(&count), - WTF::Unretained(&delayed_task_run_at_count)), + base::BindOnce(DelayedTask, WTF::Unretained(&count), + WTF::Unretained(&delayed_task_run_at_count)), base::TimeDelta::FromMilliseconds(10)); web_view_scheduler_->GrantVirtualTimeBudget( @@ -810,8 +817,8 @@ RepostingTask(ThrottleableTaskQueue(), 1000, &count); ThrottleableTaskQueue()->PostDelayedTask( FROM_HERE, - base::Bind(DelayedTask, WTF::Unretained(&count), - WTF::Unretained(&delayed_task_run_at_count)), + base::BindOnce(DelayedTask, WTF::Unretained(&count), + WTF::Unretained(&delayed_task_run_at_count)), base::TimeDelta::FromMilliseconds(10)); web_view_scheduler_->GrantVirtualTimeBudget( @@ -874,10 +881,10 @@ base::TimeDelta::FromMilliseconds(2500)); ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, base::Bind(&ExpensiveTestTask, &clock_, &run_times), + FROM_HERE, base::BindOnce(&ExpensiveTestTask, &clock_, &run_times), base::TimeDelta::FromMilliseconds(1)); ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, base::Bind(&ExpensiveTestTask, &clock_, &run_times), + FROM_HERE, base::BindOnce(&ExpensiveTestTask, &clock_, &run_times), base::TimeDelta::FromMilliseconds(1)); mock_task_runner_->RunUntilTime(base::TimeTicks() + @@ -894,10 +901,10 @@ web_view_scheduler_->SetPageVisible(false); ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, base::Bind(&ExpensiveTestTask, &clock_, &run_times), + FROM_HERE, base::BindOnce(&ExpensiveTestTask, &clock_, &run_times), base::TimeDelta::FromMicroseconds(1)); ThrottleableTaskQueue()->PostDelayedTask( - FROM_HERE, base::Bind(&ExpensiveTestTask, &clock_, &run_times), + FROM_HERE, base::BindOnce(&ExpensiveTestTask, &clock_, &run_times), base::TimeDelta::FromMicroseconds(1)); mock_task_runner_->RunUntilIdle(); @@ -938,9 +945,9 @@ for (size_t i = 0; i < 3; ++i) { ThrottleableTaskQueueForScheduler(web_frame_scheduler1.get()) - ->PostDelayedTask(FROM_HERE, - base::Bind(&ExpensiveTestTask, &clock_, &run_times), - base::TimeDelta::FromMilliseconds(1)); + ->PostDelayedTask( + FROM_HERE, base::BindOnce(&ExpensiveTestTask, &clock_, &run_times), + base::TimeDelta::FromMilliseconds(1)); } mock_task_runner_->RunUntilTime(base::TimeTicks() + @@ -959,9 +966,9 @@ for (size_t i = 0; i < 3; ++i) { ThrottleableTaskQueueForScheduler(web_frame_scheduler1.get()) - ->PostDelayedTask(FROM_HERE, - base::Bind(&ExpensiveTestTask, &clock_, &run_times), - base::TimeDelta::FromMilliseconds(1)); + ->PostDelayedTask( + FROM_HERE, base::BindOnce(&ExpensiveTestTask, &clock_, &run_times), + base::TimeDelta::FromMilliseconds(1)); } mock_task_runner_->RunUntilTime(base::TimeTicks() + @@ -979,9 +986,9 @@ for (size_t i = 0; i < 3; ++i) { ThrottleableTaskQueueForScheduler(web_frame_scheduler2.get()) - ->PostDelayedTask(FROM_HERE, - base::Bind(&ExpensiveTestTask, &clock_, &run_times), - base::TimeDelta::FromMilliseconds(1)); + ->PostDelayedTask( + FROM_HERE, base::BindOnce(&ExpensiveTestTask, &clock_, &run_times), + base::TimeDelta::FromMilliseconds(1)); } mock_task_runner_->RunUntilTime(base::TimeTicks() + @@ -1004,9 +1011,9 @@ for (size_t i = 0; i < 3; ++i) { ThrottleableTaskQueueForScheduler(web_frame_scheduler1.get()) - ->PostDelayedTask(FROM_HERE, - base::Bind(&ExpensiveTestTask, &clock_, &run_times), - base::TimeDelta::FromMilliseconds(1)); + ->PostDelayedTask( + FROM_HERE, base::BindOnce(&ExpensiveTestTask, &clock_, &run_times), + base::TimeDelta::FromMilliseconds(1)); } mock_task_runner_->RunUntilIdle();
diff --git a/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc b/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc index 6e04533..a5f80a61 100644 --- a/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/renderer/webthread_impl_for_renderer_scheduler_unittest.cc
@@ -194,8 +194,8 @@ } message_loop_.task_runner()->PostTask( - FROM_HERE, base::Bind(&EnterRunLoop, base::Unretained(&message_loop_), - base::Unretained(thread_.get()))); + FROM_HERE, base::BindOnce(&EnterRunLoop, base::Unretained(&message_loop_), + base::Unretained(thread_.get()))); base::RunLoop().RunUntilIdle(); thread_->RemoveTaskObserver(&observer); }
diff --git a/third_party/WebKit/Source/platform/scheduler/test/fake_web_frame_scheduler.h b/third_party/WebKit/Source/platform/scheduler/test/fake_web_frame_scheduler.h index fb35c7de..ef77709 100644 --- a/third_party/WebKit/Source/platform/scheduler/test/fake_web_frame_scheduler.h +++ b/third_party/WebKit/Source/platform/scheduler/test/fake_web_frame_scheduler.h
@@ -113,6 +113,7 @@ void SetPaused(bool) override {} void SetCrossOrigin(bool) override {} bool IsCrossOrigin() const override { return is_cross_origin_; } + void TraceUrlChange(const String&) override {} WebFrameScheduler::FrameType GetFrameType() const override { return frame_type_; }
diff --git a/third_party/WebKit/Source/platform/scheduler/util/thread_load_tracker.h b/third_party/WebKit/Source/platform/scheduler/util/thread_load_tracker.h index 6a9b31d..23f0d76 100644 --- a/third_party/WebKit/Source/platform/scheduler/util/thread_load_tracker.h +++ b/third_party/WebKit/Source/platform/scheduler/util/thread_load_tracker.h
@@ -21,7 +21,7 @@ class PLATFORM_EXPORT ThreadLoadTracker { public: // Callback is called with (current_time, load_level) parameters. - using Callback = base::Callback<void(base::TimeTicks, double)>; + using Callback = base::RepeatingCallback<void(base::TimeTicks, double)>; ThreadLoadTracker(base::TimeTicks now, const Callback& callback,
diff --git a/third_party/WebKit/Source/platform/scheduler/util/thread_load_tracker_unittest.cc b/third_party/WebKit/Source/platform/scheduler/util/thread_load_tracker_unittest.cc index 83e925cb..5e8a259 100644 --- a/third_party/WebKit/Source/platform/scheduler/util/thread_load_tracker_unittest.cc +++ b/third_party/WebKit/Source/platform/scheduler/util/thread_load_tracker_unittest.cc
@@ -31,7 +31,8 @@ std::vector<std::pair<base::TimeTicks, double>> result; ThreadLoadTracker thread_load_tracker( - SecondsToTime(1), base::Bind(&AddToVector, base::Unretained(&result)), + SecondsToTime(1), + base::BindRepeating(&AddToVector, base::Unretained(&result)), base::TimeDelta::FromSeconds(1)); thread_load_tracker.Resume(SecondsToTime(1)); @@ -66,7 +67,8 @@ std::vector<std::pair<base::TimeTicks, double>> result; ThreadLoadTracker thread_load_tracker( - SecondsToTime(1), base::Bind(&AddToVector, base::Unretained(&result)), + SecondsToTime(1), + base::BindRepeating(&AddToVector, base::Unretained(&result)), base::TimeDelta::FromSeconds(1)); thread_load_tracker.Resume(SecondsToTime(1)); @@ -102,7 +104,8 @@ TEST(ThreadLoadTrackerTest, DisabledByDefault) { std::vector<std::pair<base::TimeTicks, double>> result; ThreadLoadTracker thread_load_tracker( - SecondsToTime(1), base::Bind(&AddToVector, base::Unretained(&result)), + SecondsToTime(1), + base::BindRepeating(&AddToVector, base::Unretained(&result)), base::TimeDelta::FromSeconds(1)); // ThreadLoadTracker should be disabled and these tasks should be @@ -121,7 +124,8 @@ TEST(ThreadLoadTrackerTest, Reset) { std::vector<std::pair<base::TimeTicks, double>> result; ThreadLoadTracker thread_load_tracker( - SecondsToTime(1), base::Bind(&AddToVector, base::Unretained(&result)), + SecondsToTime(1), + base::BindRepeating(&AddToVector, base::Unretained(&result)), base::TimeDelta::FromSeconds(1)); thread_load_tracker.Resume(SecondsToTime(1));
diff --git a/third_party/WebKit/Source/platform/scheduler/util/tracing_helper.h b/third_party/WebKit/Source/platform/scheduler/util/tracing_helper.h index 743a037..728f7d1 100644 --- a/third_party/WebKit/Source/platform/scheduler/util/tracing_helper.h +++ b/third_party/WebKit/Source/platform/scheduler/util/tracing_helper.h
@@ -13,6 +13,7 @@ #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "platform/PlatformExport.h" +#include "platform/wtf/text/WTFString.h" namespace blink { namespace scheduler { @@ -80,9 +81,77 @@ // of category. Hence, we need distinct version for each category in order to // prevent unintended leak of state. -template <typename T, const char* category> -class TraceableState : public TraceableVariable { +template <const char* category> +class StateTracer { public: + StateTracer(const char* name, const void* object) + : name_(name), object_(object), slice_is_open_(false) { + internal::ValidateTracingCategory(category); + } + + ~StateTracer() { + if (slice_is_open_) + TRACE_EVENT_ASYNC_END0(category, name_, object_); + } + + // String will be copied before leaving this function. + void TraceString(const String& state) { + TraceImpl(state.Utf8().data(), true); + } + + // Trace compile-time defined const string, so no copy needed. + // Null may be passed to indicate the absence of state. + void TraceCompileTimeString(const char* state) { + TraceImpl(state, false); + } + + protected: + bool is_enabled() const { + bool result = false; + TRACE_EVENT_CATEGORY_GROUP_ENABLED(category, &result); // Cached. + return result; + } + + private: + void TraceImpl(const char* state, bool need_copy) { + if (slice_is_open_) { + TRACE_EVENT_ASYNC_END0(category, name_, object_); + slice_is_open_ = false; + } + if (!state || !is_enabled()) + return; + + // Trace viewer logic relies on subslice starting at the exact same time + // as the async event. + base::TimeTicks now = TRACE_TIME_TICKS_NOW(); + TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(category, name_, object_, now); + if (need_copy) { + TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category, name_, object_, + TRACE_STR_COPY(state), now); + } else { + TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category, name_, object_, + state, now); + } + slice_is_open_ = true; + } + + const char* const name_; // Not owned. + const void* const object_; // Not owned. + + // We have to track whether slice is open to avoid confusion since assignment, + // "absent" state and OnTraceLogEnabled can happen anytime. + bool slice_is_open_; + + DISALLOW_COPY_AND_ASSIGN(StateTracer); +}; + +// TODO(kraynov): Rename to something less generic and reflecting +// the enum nature of such variables. +template <typename T, const char* category> +class TraceableState : public TraceableVariable, private StateTracer<category> { + public: + // Converter must return compile-time defined const strings because tracing + // will not make a copy of them. using ConverterFuncPtr = const char* (*)(T); TraceableState(T initial_state, @@ -91,19 +160,13 @@ TraceableVariableController* controller, ConverterFuncPtr converter) : TraceableVariable(controller), - name_(name), - object_(object), + StateTracer<category>(name, object), converter_(converter), - state_(initial_state), - slice_is_open_(false) { - internal::ValidateTracingCategory(category); + state_(initial_state) { Trace(); } - ~TraceableState() override { - if (slice_is_open_) - TRACE_EVENT_ASYNC_END0(category, name_, object_); - } + ~TraceableState() override = default; TraceableState& operator =(const T& value) { Assign(value); @@ -142,40 +205,19 @@ return; } - if (slice_is_open_) { - TRACE_EVENT_ASYNC_END0(category, name_, object_); - slice_is_open_ = false; + // Null state string means the absence of state. + const char* state_str = nullptr; + if (StateTracer<category>::is_enabled()) { + state_str = converter_(state_); } - if (!is_enabled()) - return; - // Converter returns nullptr to indicate the absence of state. - const char* state_str = converter_(state_); - if (!state_str) - return; - // Trace viewer logic relies on subslice starting at the exact same time - // as the async event. - base::TimeTicks now = base::TimeTicks::Now(); - TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP0(category, name_, object_, now); - TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(category, name_, object_, - state_str, now); - slice_is_open_ = true; + // We have to be explicit to deal with two-phase name lookup in templates: + // http://blog.llvm.org/2009/12/dreaded-two-phase-name-lookup.html + StateTracer<category>::TraceCompileTimeString(state_str); } - bool is_enabled() const { - bool result = false; - TRACE_EVENT_CATEGORY_GROUP_ENABLED(category, &result); // Cached. - return result; - } - - const char* const name_; // Not owned. - const void* const object_; // Not owned. const ConverterFuncPtr converter_; - T state_; - // We have to track whether slice is open to avoid confusion since assignment, - // "absent" state and OnTraceLogEnabled can happen anytime. - bool slice_is_open_; DISALLOW_COPY(TraceableState); };
diff --git a/third_party/WebKit/Source/platform/wtf/HashTable.h b/third_party/WebKit/Source/platform/wtf/HashTable.h index 6fb75807..9dde70b 100644 --- a/third_party/WebKit/Source/platform/wtf/HashTable.h +++ b/third_party/WebKit/Source/platform/wtf/HashTable.h
@@ -2102,14 +2102,11 @@ if (!table_) return; - // Backing store can be moved during compaction. - Allocator::RegisterBackingStoreReference(visitor, &table_); - if (Traits::kWeakHandlingFlag == kNoWeakHandling) { // Strong HashTable. DCHECK(IsTraceableInCollectionTrait<Traits>::value); - Allocator::template TraceHashTableBacking<ValueType, HashTable>(visitor, - table_); + Allocator::template TraceHashTableBackingStrongly<ValueType, HashTable>( + visitor, table_, &table_); } else { // Weak HashTable. The HashTable may be held alive strongly from somewhere // else, e.g., an iterator. @@ -2117,7 +2114,9 @@ // Marking of the table is delayed because the backing store is potentially // held alive strongly by other objects. Delayed marking happens after // regular marking. - Allocator::RegisterDelayedMarkNoTracing(visitor, table_); + Allocator::template TraceHashTableBackingWeakly<ValueType, HashTable>( + visitor, table_, &table_); + // It is safe to register the table multiple times. Allocator::RegisterWeakMembers( visitor, this,
diff --git a/third_party/WebKit/public/platform/InterfaceRegistry.h b/third_party/WebKit/public/platform/InterfaceRegistry.h index bbed26f3..0cc0770 100644 --- a/third_party/WebKit/public/platform/InterfaceRegistry.h +++ b/third_party/WebKit/public/platform/InterfaceRegistry.h
@@ -24,9 +24,10 @@ namespace blink { -using InterfaceFactory = base::Callback<void(mojo::ScopedMessagePipeHandle)>; +using InterfaceFactory = + base::RepeatingCallback<void(mojo::ScopedMessagePipeHandle)>; using AssociatedInterfaceFactory = - base::Callback<void(mojo::ScopedInterfaceEndpointHandle)>; + base::RepeatingCallback<void(mojo::ScopedInterfaceEndpointHandle)>; class BLINK_PLATFORM_EXPORT InterfaceRegistry { public:
diff --git a/third_party/gvr-android-sdk/display_synchronizer_jni.h b/third_party/gvr-android-sdk/display_synchronizer_jni.h index 4e677cd2..98bfee9 100644 --- a/third_party/gvr-android-sdk/display_synchronizer_jni.h +++ b/third_party/gvr-android-sdk/display_synchronizer_jni.h
@@ -72,6 +72,12 @@ jlong syncTime, jint currentRotation); +extern "C" __attribute__((visibility("default"))) void +Java_com_google_vr_cardboard_DisplaySynchronizer_nativeOnMetricsChanged( + JNIEnv* env, + jobject obj, + jlong native_object); + // Step 3: RegisterNatives. static const JNINativeMethod kMethodsDisplaySynchronizer[] = { @@ -108,6 +114,13 @@ "V", reinterpret_cast<void*>( Java_com_google_vr_cardboard_DisplaySynchronizer_nativeUpdate)}, + {"nativeOnMetricsChanged", + "(" + "J" + ")" + "V", + reinterpret_cast<void*>( + Java_com_google_vr_cardboard_DisplaySynchronizer_nativeOnMetricsChanged)}, }; static bool RegisterNativesImpl(JNIEnv* env) {
diff --git a/third_party/libprotobuf-mutator/BUILD.gn b/third_party/libprotobuf-mutator/BUILD.gn index 3ee754e..cea5363 100644 --- a/third_party/libprotobuf-mutator/BUILD.gn +++ b/third_party/libprotobuf-mutator/BUILD.gn
@@ -73,7 +73,7 @@ # generator_plugin_suffix = ".pb" # # The plugin will generate cc, so don't ask for it to be done by protoc. # generate_cc = false - # deps = ["//third_party/libprotobuf-mutator:protoc_plugin"] + # deps = ["//third_party/libprotobuf-mutator:override_lite_runtime_plugin"] # } }
diff --git a/tools/android/native_lib_memory/extract_symbols.py b/tools/android/native_lib_memory/extract_symbols.py index fa992719..da1b383f 100755 --- a/tools/android/native_lib_memory/extract_symbols.py +++ b/tools/android/native_lib_memory/extract_symbols.py
@@ -44,7 +44,7 @@ of the output_directory part. """ path = os.path.join(build_directory, 'obj') - object_filenames = cyglog_to_orderfile.GetObjectFileNames(path) + object_filenames = cyglog_to_orderfile.GetObjectFilenames(path) pool = multiprocessing.Pool() symbol_infos_filename = zip( pool.map(symbol_extractor.SymbolInfosFromBinary, object_filenames),
diff --git a/tools/battor_agent/battor_agent.cc b/tools/battor_agent/battor_agent.cc index 7c260dc..cce7dae 100644 --- a/tools/battor_agent/battor_agent.cc +++ b/tools/battor_agent/battor_agent.cc
@@ -93,7 +93,7 @@ Listener* listener, scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) : connection_(new BattOrConnectionImpl(path, this, ui_thread_task_runner)), - tick_clock_(std::make_unique<base::DefaultTickClock>()), + tick_clock_(base::DefaultTickClock::GetInstance()), listener_(listener), last_action_(Action::INVALID), command_(Command::INVALID),
diff --git a/tools/battor_agent/battor_agent.h b/tools/battor_agent/battor_agent.h index 1dc34c86..eb3e2ca 100644 --- a/tools/battor_agent/battor_agent.h +++ b/tools/battor_agent/battor_agent.h
@@ -103,7 +103,7 @@ std::unique_ptr<BattOrConnection> connection_; // A source of TimeTicks. Protected so that it can be faked in testing. - std::unique_ptr<base::TickClock> tick_clock_; + base::TickClock* tick_clock_; // Timeout for when an action isn't completed within the allotted time. This // is virtual and protected so that timeouts can be disabled in testing. The
diff --git a/tools/battor_agent/battor_agent_unittest.cc b/tools/battor_agent/battor_agent_unittest.cc index 23e1d1b5..a1f48cb 100644 --- a/tools/battor_agent/battor_agent_unittest.cc +++ b/tools/battor_agent/battor_agent_unittest.cc
@@ -84,11 +84,11 @@ class TestableBattOrAgent : public BattOrAgent { public: TestableBattOrAgent(BattOrAgent::Listener* listener, - std::unique_ptr<base::TickClock> tick_clock) + base::TickClock* tick_clock) : BattOrAgent("/dev/test", listener, nullptr) { connection_ = std::unique_ptr<BattOrConnection>(new MockBattOrConnection(this)); - tick_clock_ = std::move(tick_clock); + tick_clock_ = tick_clock; } MockBattOrConnection* GetConnection() { @@ -149,8 +149,8 @@ protected: void SetUp() override { - agent_.reset( - new TestableBattOrAgent(this, task_runner_->GetMockTickClock())); + tick_clock_ = task_runner_->GetMockTickClock(); + agent_.reset(new TestableBattOrAgent(this, tick_clock_.get())); task_runner_->ClearPendingTasks(); is_command_complete_ = false; command_error_ = BATTOR_ERROR_NONE; @@ -346,6 +346,11 @@ private: scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; + + // TODO(tzik): Remove |tick_clock_| after updating GetMockTickClock to own the + // instance. + std::unique_ptr<base::TickClock> tick_clock_; + // Needed to support ThreadTaskRunnerHandle::Get() in code under test. base::ThreadTaskRunnerHandle thread_task_runner_handle_;
diff --git a/tools/battor_agent/battor_connection_impl.cc b/tools/battor_agent/battor_connection_impl.cc index c7d9898..91b9fb8 100644 --- a/tools/battor_agent/battor_connection_impl.cc +++ b/tools/battor_agent/battor_connection_impl.cc
@@ -83,7 +83,7 @@ serial_log_.open(serial_log_path.c_str(), std::fstream::out | std::fstream::trunc); } - tick_clock_ = std::make_unique<base::DefaultTickClock>(); + tick_clock_ = base::DefaultTickClock::GetInstance(); } BattOrConnectionImpl::~BattOrConnectionImpl() = default;
diff --git a/tools/battor_agent/battor_connection_impl.h b/tools/battor_agent/battor_connection_impl.h index 8cb142b..a2db3b0 100644 --- a/tools/battor_agent/battor_connection_impl.h +++ b/tools/battor_agent/battor_connection_impl.h
@@ -64,7 +64,7 @@ // IO handler capable of reading and writing from the serial connection. scoped_refptr<device::SerialIoHandler> io_handler_; - std::unique_ptr<base::TickClock> tick_clock_; + base::TickClock* tick_clock_; private: void OnOpened(bool success);
diff --git a/tools/battor_agent/battor_connection_impl_unittest.cc b/tools/battor_agent/battor_connection_impl_unittest.cc index 34a87f0a..15268c4 100644 --- a/tools/battor_agent/battor_connection_impl_unittest.cc +++ b/tools/battor_agent/battor_connection_impl_unittest.cc
@@ -31,9 +31,9 @@ class TestableBattOrConnection : public BattOrConnectionImpl { public: TestableBattOrConnection(BattOrConnection::Listener* listener, - std::unique_ptr<base::TickClock> tick_clock) + base::TickClock* tick_clock) : BattOrConnectionImpl("/dev/test", listener, nullptr) { - tick_clock_ = std::move(tick_clock); + tick_clock_ = tick_clock; } scoped_refptr<device::SerialIoHandler> CreateIoHandler() override { return device::TestSerialIoHandler::Create(); @@ -73,8 +73,8 @@ protected: void SetUp() override { - connection_.reset( - new TestableBattOrConnection(this, task_runner_->GetMockTickClock())); + tick_clock_ = task_runner_->GetMockTickClock(); + connection_.reset(new TestableBattOrConnection(this, tick_clock_.get())); task_runner_->ClearPendingTasks(); } @@ -149,11 +149,15 @@ std::vector<char>* GetReadMessage() { return read_bytes_.get(); } private: - std::unique_ptr<TestableBattOrConnection> connection_; + // TODO(tzik): Remove |tick_clock_| after updating GetMockTickClock to own the + // instance. + std::unique_ptr<base::TickClock> tick_clock_; scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; base::ThreadTaskRunnerHandle thread_task_runner_handle_; + std::unique_ptr<TestableBattOrConnection> connection_; + // Result from the last connect command. bool open_success_; // Results from the last flush command.
diff --git a/tools/binary_size/libsupersize/archive.py b/tools/binary_size/libsupersize/archive.py index f3aa2df..45fba505 100644 --- a/tools/binary_size/libsupersize/archive.py +++ b/tools/binary_size/libsupersize/archive.py
@@ -34,20 +34,27 @@ from grit.format import data_pack -# Effect of _MAX_SAME_NAME_ALIAS_COUNT (as of Oct 2017, with min_pss = max): -# 1: shared .text symbols = 1772874 bytes, file size = 9.43MiB (645476 symbols). -# 2: shared .text symbols = 1065654 bytes, file size = 9.58MiB (669952 symbols). -# 6: shared .text symbols = 464058 bytes, file size = 10.11MiB (782693 symbols). -# 10: shared .text symbols = 365648 bytes, file size =10.24MiB (813758 symbols). -# 20: shared .text symbols = 86202 bytes, file size = 10.38MiB (854548 symbols). -# 40: shared .text symbols = 48424 bytes, file size = 10.50MiB (890396 symbols). -# 50: shared .text symbols = 41860 bytes, file size = 10.54MiB (902304 symbols). -# max: shared .text symbols = 0 bytes, file size = 11.10MiB (1235449 symbols). -_MAX_SAME_NAME_ALIAS_COUNT = 40 # 50kb is basically negligable. +# Tunable "knobs" for CreateSectionSizesAndSymbols(). +class SectionSizeKnobs(object): + def __init__(self): + # A limit on the number of symbols an address can have, before these symbols + # are compacted into shared symbols. Increasing this value causes more data + # to be stored .size files, but is also more expensive. + # Effect of max_same_name_alias_count (as of Oct 2017, with min_pss = max): + # 1: shared .text syms = 1772874 bytes, file size = 9.43MiB (645476 syms). + # 2: shared .text syms = 1065654 bytes, file size = 9.58MiB (669952 syms). + # 6: shared .text syms = 464058 bytes, file size = 10.11MiB (782693 syms). + # 10: shared .text syms = 365648 bytes, file size = 10.24MiB (813758 syms). + # 20: shared .text syms = 86202 bytes, file size = 10.38MiB (854548 syms). + # 40: shared .text syms = 48424 bytes, file size = 10.50MiB (890396 syms). + # 50: shared .text syms = 41860 bytes, file size = 10.54MiB (902304 syms). + # max: shared .text syms = 0 bytes, file size = 11.10MiB (1235449 syms). + self.max_same_name_alias_count = 40 # 50kb is basically negligable. -# This is an estimate of pak translation compression ratio to make comparisons -# between .size files reasonable. Otherwise this can differ every pak change. -_PAK_COMPRESSION_RATIO = 0.33 + # An estimate of pak translation compression ratio to make comparisons + # between .size files reasonable. Otherwise this can differ every pak + # change. + self.pak_compression_ratio = 0.33 def _OpenMaybeGz(path): @@ -239,7 +246,7 @@ return os.path.join(os.path.dirname(prefix), '{shared}', symbol_count_str) -def _CompactLargeAliasesIntoSharedSymbols(raw_symbols): +def _CompactLargeAliasesIntoSharedSymbols(raw_symbols, knobs): """Converts symbols with large number of aliases into single symbols. The merged symbol's path fields are changed to common-ancestor paths in @@ -256,7 +263,7 @@ raw_symbols[dst_cursor] = symbol dst_cursor += 1 aliases = symbol.aliases - if aliases and len(aliases) > _MAX_SAME_NAME_ALIAS_COUNT: + if aliases and len(aliases) > knobs.max_same_name_alias_count: symbol.source_path = _ComputeAncestorPath( [s.source_path for s in aliases if s.source_path], len(aliases)) symbol.object_path = _ComputeAncestorPath( @@ -678,8 +685,6 @@ # is fast enough since len(merge_string_syms) < 10. raw_symbols[idx:idx + 1] = literal_syms - logging.debug('Connecting nm aliases') - _ConnectNmAliases(raw_symbols) return section_sizes, raw_symbols @@ -810,7 +815,7 @@ return apk_symbols -def _FindPakSymbolsFromApk(apk_path, output_directory): +def _FindPakSymbolsFromApk(apk_path, output_directory, knobs): with zipfile.ZipFile(apk_path) as z: pak_zip_infos = (f for f in z.infolist() if f.filename.endswith('.pak')) apk_info_name = os.path.basename(apk_path) + '.pak.info' @@ -825,7 +830,7 @@ if zip_info.compress_size < zip_info.file_size: total_compressed_size += zip_info.compress_size total_uncompressed_size += zip_info.file_size - compression_ratio = _PAK_COMPRESSION_RATIO + compression_ratio = knobs.pak_compression_ratio _ComputePakFileSymbols( os.path.relpath(zip_info.filename, output_directory), contents, res_info, symbols_by_id, compression_ratio=compression_ratio) @@ -833,8 +838,9 @@ actual_ratio = ( float(total_compressed_size) / total_uncompressed_size) logging.info('Pak Compression Ratio: %f Actual: %f Diff: %.0f', - _PAK_COMPRESSION_RATIO, actual_ratio, - (_PAK_COMPRESSION_RATIO - actual_ratio) * total_uncompressed_size) + knobs.pak_compression_ratio, actual_ratio, + (knobs.pak_compression_ratio - actual_ratio) * + total_uncompressed_size) return symbols_by_id @@ -866,7 +872,8 @@ def CreateSectionSizesAndSymbols( map_path=None, tool_prefix=None, output_directory=None, elf_path=None, apk_path=None, track_string_literals=True, metadata=None, - apk_elf_result=None, pak_files=None, pak_info_file=None): + apk_elf_result=None, pak_files=None, pak_info_file=None, + knobs=SectionSizeKnobs()): """Creates sections sizes and symbols for a SizeInfo. Args: @@ -899,7 +906,8 @@ pak_symbols_by_id = None if apk_path: - pak_symbols_by_id = _FindPakSymbolsFromApk(apk_path, output_directory) + pak_symbols_by_id = _FindPakSymbolsFromApk(apk_path, output_directory, + knobs) section_sizes, elf_overhead_size = _ParseApkElfSectionSize( section_sizes, metadata, apk_elf_result) raw_symbols.extend(_ParseApkOtherSymbols(section_sizes, apk_path)) @@ -922,7 +930,9 @@ _ExtractSourcePathsAndNormalizeObjectPaths(raw_symbols, source_mapper) logging.info('Converting excessive aliases into shared-path symbols') - _CompactLargeAliasesIntoSharedSymbols(raw_symbols) + _CompactLargeAliasesIntoSharedSymbols(raw_symbols, knobs) + logging.debug('Connecting nm aliases') + _ConnectNmAliases(raw_symbols) return section_sizes, raw_symbols
diff --git a/tools/binary_size/libsupersize/integration_test.py b/tools/binary_size/libsupersize/integration_test.py index 1737e851..e1b9294 100755 --- a/tools/binary_size/libsupersize/integration_test.py +++ b/tools/binary_size/libsupersize/integration_test.py
@@ -123,15 +123,20 @@ if cache_key not in IntegrationTest.cached_size_info: elf_path = _TEST_ELF_PATH if use_elf else None output_directory = _TEST_OUTPUT_DIR if use_output_directory else None + knobs = archive.SectionSizeKnobs() + # Override for testing. Lower the bar for compacting symbols, to allow + # smaller test cases to be created. + knobs.max_same_name_alias_count = 3 if use_pak: section_sizes, raw_symbols = archive.CreateSectionSizesAndSymbols( map_path=_TEST_MAP_PATH, tool_prefix=_TEST_TOOL_PREFIX, elf_path=elf_path, output_directory=output_directory, - pak_files=[_TEST_PAK_PATH], pak_info_file=_TEST_PAK_INFO_PATH) + pak_files=[_TEST_PAK_PATH], pak_info_file=_TEST_PAK_INFO_PATH, + knobs=knobs) else: section_sizes, raw_symbols = archive.CreateSectionSizesAndSymbols( map_path=_TEST_MAP_PATH, tool_prefix=_TEST_TOOL_PREFIX, - elf_path=elf_path, output_directory=output_directory) + elf_path=elf_path, output_directory=output_directory, knobs=knobs) metadata = None if use_elf: with _AddMocksToPath():
diff --git a/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp b/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp index a588740..0c89dbf 100644 --- a/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp +++ b/tools/clang/base_bind_rewriters/BaseBindRewriters.cpp
@@ -197,7 +197,7 @@ llvm::make_unique<PassedToMoveRewriter>(&replacements); match_finder.addMatcher(passed_to_move->GetMatcher(), passed_to_move.get()); rewriter = std::move(passed_to_move); - } else if (rewriter_option == "bind_toBind_once") { + } else if (rewriter_option == "bind_to_bind_once") { auto bind_once = llvm::make_unique<BindOnceRewriter>(&replacements); match_finder.addMatcher(bind_once->GetMatcher(), bind_once.get()); rewriter = std::move(bind_once);
diff --git a/tools/cygprofile/BUILD.gn b/tools/cygprofile/BUILD.gn index f5f9016..0ba8b6a 100644 --- a/tools/cygprofile/BUILD.gn +++ b/tools/cygprofile/BUILD.gn
@@ -5,8 +5,9 @@ import("//build/config/android/config.gni") if (target_cpu == "arm") { - static_library("lightweight_cygprofile") { + static_library("cygprofile") { sources = [ + "delayed_dumper.cc", "lightweight_cygprofile.cc", "lightweight_cygprofile.h", ] @@ -17,71 +18,8 @@ configs -= [ "//build/config/android:default_cygprofile_instrumentation" ] configs += [ "//build/config/android:no_cygprofile_instrumentation" ] } -} -static_library("cygprofile") { - deps = [ - # This adds uninstrumented symbols to the static library from base. - # These symbols are likely *not* to be used because there are many other - # duplicates in other objects/libraries. - "//base", - ] - - if (use_lightweight_order_profiling) { - assert(use_order_profiling) - assert(target_cpu == "arm") - sources = [ - "delayed_dumper.cc", - ] - deps += [ ":lightweight_cygprofile" ] - } else { - sources = [ - "cygprofile.cc", - "cygprofile.h", - ] - } - - configs -= [ "//build/config/android:default_cygprofile_instrumentation" ] - configs += [ "//build/config/android:no_cygprofile_instrumentation" ] -} - -executable("cygprofile_unittests") { - testonly = true - - sources = [ - "cygprofile_unittest.cc", - ] - - configs -= [ "//build/config/android:default_cygprofile_instrumentation" ] - configs += [ "//build/config/android:no_cygprofile_instrumentation" ] - - deps = [ - ":cygprofile", - "//base", - "//testing/gtest", - ] -} - -executable("cygprofile_perftests") { - testonly = true - - sources = [ - "cygprofile_perftest.cc", - ] - - configs -= [ "//build/config/android:default_cygprofile_instrumentation" ] - configs += [ "//build/config/android:no_cygprofile_instrumentation" ] - - deps = [ - ":cygprofile", - "//base", - "//testing/gtest", - "//testing/perf", - ] -} - -if (target_cpu == "arm") { - executable("lightweight_cygprofile_perftests") { + executable("cygprofile_perftests") { testonly = true sources = [ @@ -92,7 +30,7 @@ configs += [ "//build/config/android:no_cygprofile_instrumentation" ] deps = [ - ":lightweight_cygprofile", + ":cygprofile", "//base", "//testing/gtest", "//testing/perf",
diff --git a/tools/cygprofile/cyglog_to_orderfile.py b/tools/cygprofile/cyglog_to_orderfile.py index 0fb2e90..cf9afbb 100755 --- a/tools/cygprofile/cyglog_to_orderfile.py +++ b/tools/cygprofile/cyglog_to_orderfile.py
@@ -13,7 +13,6 @@ import multiprocessing import os import re -import string import sys import tempfile @@ -32,6 +31,17 @@ return repr(self.value) +def GetObjectFilenames(obj_dir): + """Returns all a list of .o files in a given directory tree.""" + obj_files = [] + # Scan _obj_dir recursively for .o files. + for (dirpath, _, filenames) in os.walk(obj_dir): + for file_name in filenames: + if file_name.endswith('.o'): + obj_files.append(os.path.join(dirpath, file_name)) + return obj_files + + class ObjectFileProcessor(object): """Processes symbols found in the object file tree. @@ -108,13 +118,7 @@ symbol_extractor.DemangleSymbol(symbol2)) def _GetAllSymbolInfos(self): - obj_files = [] - # Scan _obj_dir recursively for .o files. - for (dirpath, _, filenames) in os.walk(self._obj_dir): - for file_name in filenames: - if file_name.endswith('.o'): - obj_files.append(os.path.join(dirpath, file_name)) - + obj_files = GetObjectFilenames(self._obj_dir) pool = multiprocessing.Pool() # Hopefully the object files are in the page cache at this point as # typically the library has just been built before the object files are @@ -123,6 +127,7 @@ symbol_infos_nested = pool.map( symbol_extractor.SymbolInfosFromBinary, obj_files) pool.close() + pool.join() result = [] for symbol_infos in symbol_infos_nested: result += symbol_infos @@ -201,47 +206,6 @@ raise _SymbolNotFoundException(offset) -def _ParseLogLines(log_file_lines): - """Parses a merged cyglog produced by mergetraces.py. - - Args: - log_file_lines: array of lines in log file produced by profiled run - - Below is an example of a small log file: - 5086e000-52e92000 r-xp 00000000 b3:02 51276 libchromeview.so - secs usecs pid:threadid func - START - 1314897086 795828 3587:1074648168 0x509e105c - 1314897086 795874 3587:1074648168 0x509e0eb4 - 1314897086 796326 3587:1074648168 0x509e0e3c - 1314897086 796552 3587:1074648168 0x509e07bc - END - - Returns: - An ordered list of callee offsets. - """ - call_lines = [] - vm_start = 0 - line = log_file_lines[0] - assert 'r-xp' in line - end_index = line.find('-') - vm_start = int(line[:end_index], 16) - for line in log_file_lines[3:]: - fields = line.split() - if len(fields) == 4: - call_lines.append(fields) - else: - assert fields[0] == 'END' - # Convert strings to int in fields. - call_info = [] - for call_line in call_lines: - addr = int(call_line[3], 16) - if vm_start < addr: - addr -= vm_start - call_info.append(addr) - return call_info - - def _WarnAboutDuplicates(offsets): """Warns about duplicate offsets. @@ -275,9 +239,7 @@ parser.add_argument('--target-arch', required=False, choices=['arm', 'arm64', 'x86', 'x86_64', 'x64', 'mips'], help='The target architecture for libchrome.so') - parser.add_argument('--merged-cyglog', type=str, required=False, - help='Path to the merged cyglog') - parser.add_argument('--reached-offsets', type=str, required=False, + parser.add_argument('--reached-offsets', type=str, required=True, help='Path to the reached offsets') parser.add_argument('--native-library', type=str, required=True, help='Path to the unstripped instrumented library') @@ -290,20 +252,13 @@ parser = _CreateArgumentParser() args = parser.parse_args() - assert bool(args.merged_cyglog) ^ bool(args.reached_offsets) - if not args.target_arch: args.arch = cygprofile_utils.DetectArchitecture() symbol_extractor.SetArchitecture(args.target_arch) obj_dir = cygprofile_utils.GetObjDir(args.native_library) - offsets = [] - if args.merged_cyglog: - log_file_lines = map(string.rstrip, open(args.merged_cyglog).readlines()) - offsets = _ParseLogLines(log_file_lines) - else: - offsets = _ReadReachedOffsets(args.reached_offsets) + offsets = _ReadReachedOffsets(args.reached_offsets) assert offsets _WarnAboutDuplicates(offsets)
diff --git a/tools/cygprofile/cyglog_to_orderfile_unittest.py b/tools/cygprofile/cyglog_to_orderfile_unittest.py index 37722570..2aae4d4 100755 --- a/tools/cygprofile/cyglog_to_orderfile_unittest.py +++ b/tools/cygprofile/cyglog_to_orderfile_unittest.py
@@ -76,17 +76,6 @@ if failure_items: raise self.failureException('\n'.join(failure_items)) - def testParseLogLines(self): - lines = """5086e000-52e92000 r-xp 00000000 b3:02 51276 libchromeview.so -secs usecs pid:threadid func -START -1314897086 795828 3587:1074648168 0x509e105c -1314897086 795874 3587:1074648168 0x509e0eb4 -END""".split('\n') - offsets = cyglog_to_orderfile._ParseLogLines(lines) - self.assertListEqual( - offsets, [0x509e105c - 0x5086e000, 0x509e0eb4 - 0x5086e000]) - def testWarnAboutDuplicates(self): offsets = [0x1, 0x2, 0x3] self.assertTrue(cyglog_to_orderfile._WarnAboutDuplicates(offsets))
diff --git a/tools/cygprofile/cygprofile.cc b/tools/cygprofile/cygprofile.cc deleted file mode 100644 index 7c04fed..0000000 --- a/tools/cygprofile/cygprofile.cc +++ /dev/null
@@ -1,400 +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 "tools/cygprofile/cygprofile.h" - -#include <fcntl.h> -#include <pthread.h> -#include <stddef.h> -#include <stdint.h> -#include <sys/stat.h> -#include <sys/syscall.h> -#include <sys/time.h> -#include <sys/types.h> - -#include <cstdio> -#include <fstream> -#include <string> -#include <vector> - -#include "base/bind.h" -#include "base/containers/hash_tables.h" -#include "base/files/scoped_file.h" -#include "base/lazy_instance.h" -#include "base/logging.h" -#include "base/macros.h" -#include "base/memory/ptr_util.h" -#include "base/stl_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/string_piece.h" -#include "base/strings/stringprintf.h" -#include "base/synchronization/lock.h" - -namespace cygprofile { -namespace { - -// Allow 8 MBytes of data for each thread log. -const size_t kMaxBufferSize = 8 * 1024 * 1024 / sizeof(LogEntry); - -// Have the background internal thread do its flush every 15 sec. -const int kFlushThreadIdleTimeSec = 15; - -const char kLogFileNamePrefix[] = "/data/local/tmp/chrome/cyglog/"; - -// "cyglog.PID.LWP.PPID" -const char kLogFilenameFormat[] = "%scyglog.%d.%d-%d"; - -// Magic value of above to prevent instrumentation. Used when ThreadLog is being -// constructed (to prevent reentering by malloc, for example) and by the flush -// log thread (to prevent it from being logged0. -ThreadLog* const kMagicBeingConstructed = reinterpret_cast<ThreadLog*>(1); - -// Per-thread pointer to the current log object. -pthread_key_t g_tls_slot; - -// Used to initialize the tls slot, once per the entire process. -pthread_once_t g_tls_slot_initializer_once = PTHREAD_ONCE_INIT; - -// This variable is to prevent re-entrancy in the __cyg_profile_func_enter() -// while the TLS slot itself is being initialized. Volatile here is required -// to avoid compiler optimizations as this need to be read in a re-entrant way. -// This variable is written by one thread only, which is the first thread that -// happens to run the TLSSlotInitializer(). In practice this will happen very -// early in the startup process, as soon as the first instrumented function is -// called. -volatile bool g_tls_slot_being_initialized = false; - -// Initializes the global TLS slot. This is invoked only once per process. -static void TLSSlotInitializer() -{ - g_tls_slot_being_initialized = true; - PCHECK(0 == pthread_key_create(&g_tls_slot, NULL)); - g_tls_slot_being_initialized = false; -} - -// Returns light-weight process ID. On Linux, this is a system-wide unique -// thread id. -pid_t GetTID() { - return syscall(__NR_gettid); -} - -timespec GetCurrentTime() { - timespec timestamp; - clock_gettime(CLOCK_MONOTONIC, ×tamp); - return timestamp; -} - -// Sleeps for |sec| seconds. -void SleepSec(int sec) { - for (int secs_to_sleep = sec; secs_to_sleep != 0;) - secs_to_sleep = sleep(secs_to_sleep); -} - -// Exposes the string header that will appear at the top of every trace file. -// This string contains memory mapping information for the mapped -// library/executable which is used offline during symbolization. Note that -// this class is meant to be instantiated once per process and lazily (during -// the first flush). -struct ImmutableFileHeaderLine { - ImmutableFileHeaderLine() : value(MakeFileHeaderLine()) {} - - const std::string value; - - private: - // Returns whether the integer representation of the hexadecimal address - // stored in |line| at position |start_offset| was successfully stored in - // |result|. - static bool ParseAddress(const std::string& line, - size_t start_offset, - size_t length, - uint64_t* result) { - if (start_offset >= line.length()) - return false; - - uint64_t address; - const bool ret = HexStringToUInt64( - base::StringPiece(line.c_str() + start_offset, length), &address); - if (!ret) - return false; - - *result = address; - return true; - } - - // Parses /proc/self/maps and returns a two line string such as: - // 758c6000-79f4b000 r-xp 00000000 b3:17 309475 libchrome.2009.0.so - // secs usecs pid:threadid func - static std::string MakeFileHeaderLine() { - std::ifstream mapsfile("/proc/self/maps"); - CHECK(mapsfile.good()); - std::string result; - - for (std::string line; std::getline(mapsfile, line); ) { - if (line.find("r-xp") == std::string::npos) - continue; - - const size_t address_length = line.find('-'); - uint64_t start_address = 0; - CHECK(ParseAddress(line, 0, address_length, &start_address)); - - uint64_t end_address = 0; - CHECK(ParseAddress(line, address_length + 1, address_length, - &end_address)); - - const uintptr_t current_func_addr = reinterpret_cast<uintptr_t>( - &MakeFileHeaderLine); - if (current_func_addr >= start_address && - current_func_addr < end_address) { - result.swap(line); - break; - } - } - CHECK(!result.empty()); - result.append("\nsecs\tusecs\tpid:threadid\tfunc\n"); - return result; - } -}; - -base::LazyInstance<ThreadLogsManager>::Leaky g_logs_manager = - LAZY_INSTANCE_INITIALIZER; - -base::LazyInstance<ImmutableFileHeaderLine>::Leaky g_file_header_line = - LAZY_INSTANCE_INITIALIZER; - -} // namespace - -// Custom thread implementation that joins on destruction. Note that -// base::Thread has non-trivial dependencies on e.g. AtExitManager which makes -// it hard to use it early. -class Thread { - public: - Thread(const base::Closure& thread_callback) - : thread_callback_(thread_callback) { - PCHECK(0 == pthread_create(&handle_, NULL, &Thread::EntryPoint, this)); - } - - ~Thread() { - PCHECK(0 == pthread_join(handle_, NULL)); - } - - private: - static void* EntryPoint(void* data) { - // Disable logging on this thread. Although this routine is not instrumented - // (cygprofile.gyp provides that), the called routines are and thus will - // call instrumentation. - pthread_once(&g_tls_slot_initializer_once, TLSSlotInitializer); - ThreadLog* thread_log = reinterpret_cast<ThreadLog*>( - pthread_getspecific(g_tls_slot)); - CHECK(thread_log == NULL); // Must be 0 as this is a new thread. - PCHECK(0 == pthread_setspecific(g_tls_slot, kMagicBeingConstructed)); - - Thread* const instance = reinterpret_cast<Thread*>(data); - instance->thread_callback_.Run(); - return NULL; - } - - const base::Closure thread_callback_; - pthread_t handle_; - - DISALLOW_COPY_AND_ASSIGN(Thread); -}; - -// Single log entry recorded for each function call. -LogEntry::LogEntry(const void* address, pid_t pid, pid_t tid) - : time(GetCurrentTime()), pid(pid), tid(tid), address(address) {} - -ThreadLog::ThreadLog() - : pid_(getpid()), - tid_(GetTID()), - in_use_(false), - flush_callback_( - base::Bind(&ThreadLog::FlushInternal, base::Unretained(this))) {} - -ThreadLog::ThreadLog(const FlushCallback& flush_callback) - : pid_(getpid()), - tid_(GetTID()), - in_use_(false), - flush_callback_(flush_callback) {} - -ThreadLog::~ThreadLog() { - PCHECK(0 == pthread_setspecific(g_tls_slot, NULL)); -} - -void ThreadLog::AddEntry(void* address) { - if (in_use_) - return; - in_use_ = true; - - DCHECK_EQ(tid_, GetTID()); - bool did_insert = called_functions_.insert(address).second; - - if (did_insert) { - base::AutoLock auto_lock(lock_); - entries_.emplace_back(address, pid_, tid_); - // Crash in a quickly understandable way instead of crashing (or maybe not - // though) due to OOM. - CHECK_LE(entries_.size(), kMaxBufferSize); - } - - in_use_ = false; -} - -void ThreadLog::TakeEntries(std::vector<LogEntry>* destination) { - base::AutoLock auto_lock(lock_); - destination->swap(entries_); - base::STLClearObject(&entries_); -} - -void ThreadLog::Flush(std::vector<LogEntry>* entries) const { - flush_callback_.Run(entries); -} - -void ThreadLog::FlushInternal(std::vector<LogEntry>* entries) const { - const std::string log_filename( - base::StringPrintf( - kLogFilenameFormat, kLogFileNamePrefix, getpid(), tid_, getppid())); - const base::ScopedFILE file(fopen(log_filename.c_str(), "a")); - CHECK(file.get()); - - const long offset = ftell(file.get()); - if (offset == 0) - fprintf(file.get(), "%s", g_file_header_line.Get().value.c_str()); - - for (std::vector<LogEntry>::const_iterator it = entries->begin(); - it != entries->end(); ++it) { - fprintf(file.get(), "%ld %ld\t%d:%d\t%p\n", it->time.tv_sec, - it->time.tv_nsec / 1000, it->pid, it->tid, it->address); - } - - base::STLClearObject(entries); -} - -ThreadLogsManager::ThreadLogsManager() - : wait_callback_(base::Bind(&SleepSec, kFlushThreadIdleTimeSec)) { -} - -ThreadLogsManager::ThreadLogsManager(const base::Closure& wait_callback, - const base::Closure& notify_callback) - - : wait_callback_(wait_callback), - notify_callback_(notify_callback) { -} - -ThreadLogsManager::~ThreadLogsManager() { - // Note that the internal thread does some work until it sees |flush_thread_| - // = NULL. - std::unique_ptr<Thread> flush_thread; - { - base::AutoLock auto_lock(lock_); - flush_thread_.swap(flush_thread); - } - flush_thread.reset(); // Joins the flush thread. -} - -void ThreadLogsManager::AddLog(std::unique_ptr<ThreadLog> new_log) { - base::AutoLock auto_lock(lock_); - - if (logs_.empty()) - StartInternalFlushThread_Locked(); - - logs_.push_back(std::move(new_log)); -} - -void ThreadLogsManager::StartInternalFlushThread_Locked() { - lock_.AssertAcquired(); - CHECK(!flush_thread_); - // Note that the |flush_thread_| joins at destruction which guarantees that it - // will never outlive |this|, i.e. it's safe not to use ref-counting. - flush_thread_.reset( - new Thread(base::Bind(&ThreadLogsManager::FlushAllLogsOnFlushThread, - base::Unretained(this)))); -} - -// Type used below for flushing. -struct LogData { - LogData(ThreadLog* thread_log) : thread_log(thread_log) {} - - ThreadLog* const thread_log; - std::vector<LogEntry> entries; -}; - -void ThreadLogsManager::FlushAllLogsOnFlushThread() { - while (true) { - { - base::AutoLock auto_lock(lock_); - // The |flush_thread_| field is reset during destruction. - if (!flush_thread_) - return; - } - // Sleep for a few secs and then flush all thread's buffers. There is a - // danger that, when quitting Chrome, this thread may see unallocated data - // and segfault. We do not care because we need logs when Chrome is working. - wait_callback_.Run(); - - // Copy the ThreadLog pointers to avoid acquiring both the logs manager's - // lock and the one for individual thread logs. - std::vector<ThreadLog*> thread_logs_copy; - { - base::AutoLock auto_lock(lock_); - for (const auto& log : logs_) - thread_logs_copy.push_back(log.get()); - } - - // Move the logs' data before flushing them so that the mutexes are not - // acquired for too long. - std::vector<LogData> logs; - for (std::vector<ThreadLog*>::const_iterator it = - thread_logs_copy.begin(); - it != thread_logs_copy.end(); ++it) { - ThreadLog* const thread_log = *it; - LogData log_data(thread_log); - logs.push_back(log_data); - thread_log->TakeEntries(&logs.back().entries); - } - - for (std::vector<LogData>::iterator it = logs.begin(); - it != logs.end(); ++it) { - if (!it->entries.empty()) - it->thread_log->Flush(&it->entries); - } - - if (!notify_callback_.is_null()) - notify_callback_.Run(); - } -} - -extern "C" { - -// The GCC compiler callbacks, called on every function invocation providing -// addresses of caller and callee codes. -void __cyg_profile_func_enter(void* this_fn, void* call_site) - __attribute__((no_instrument_function)); -void __cyg_profile_func_exit(void* this_fn, void* call_site) - __attribute__((no_instrument_function)); - -void __cyg_profile_func_enter(void* this_fn, void* callee_unused) { - // Avoid re-entrancy while initializing the TLS slot (once per process). - if (g_tls_slot_being_initialized) - return; - - pthread_once(&g_tls_slot_initializer_once, TLSSlotInitializer); - ThreadLog* thread_log = reinterpret_cast<ThreadLog*>( - pthread_getspecific(g_tls_slot)); - - if (thread_log == NULL) { - PCHECK(0 == pthread_setspecific(g_tls_slot, kMagicBeingConstructed)); - thread_log = new ThreadLog(); - CHECK(thread_log); - g_logs_manager.Pointer()->AddLog(base::WrapUnique(thread_log)); - PCHECK(0 == pthread_setspecific(g_tls_slot, thread_log)); - } - - if (thread_log != kMagicBeingConstructed) - thread_log->AddEntry(this_fn); -} - -void __cyg_profile_func_exit(void* this_fn, void* call_site) {} - -} // extern "C" -} // namespace cygprofile
diff --git a/tools/cygprofile/cygprofile.h b/tools/cygprofile/cygprofile.h deleted file mode 100644 index 97684e78..0000000 --- a/tools/cygprofile/cygprofile.h +++ /dev/null
@@ -1,169 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// Tool to log the execution of the process (Chrome). Writes logs containing -// time and address of the callback being called for the first time. -// -// For performance reasons logs are buffered. Every thread has its own buffer -// and log file so the contention between threads is minimal. As a side-effect, -// functions called might be mentioned in many thread logs. -// -// A special thread is created in the process to periodically flush logs for all -// threads in case the thread had stopped before flushing its logs. -// -// Also note that the instrumentation code is self-activated. It begins to -// record the log data when it is called first, including the run-time startup. -// Have it in mind when modifying it, in particular do not use global objects -// with constructors as they are called during startup (too late for us). - -#ifndef TOOLS_CYGPROFILE_CYGPROFILE_H_ -#define TOOLS_CYGPROFILE_CYGPROFILE_H_ - -#include <sys/time.h> -#include <sys/types.h> - -#include <memory> -#include <vector> - -#include "base/callback.h" -#include "base/containers/hash_tables.h" -#include "base/macros.h" -#include "base/synchronization/lock.h" -#include "build/build_config.h" - -#if !defined(OS_ANDROID) -// This is only supported on Android thanks to the fact that on Android -// processes (other than the system's zygote) don't fork. -// -// To make cygprofile truly work (i.e. without any deadlock) on Chrome -// platforms that use fork(), cygprofile.cc should be written in a way that -// guarantees that: -// - No lock is acquired by a foreign thread during fork(). In particular this -// means that cygprofile.cc should not perform any heap allocation (since heap -// allocators, including TCMalloc generally use locks). -// - Only cygprofile.cc uses pthread_atfork() in the whole process. Unlike POSIX -// signals, pthread_atfork() doesn't provide a way to install multiple handlers. -// Calling pthread_atfork() in cygprofile.cc would override any handler that -// could have been installed previously. -// -// Chrome happens to violate the first requirement at least once by having its -// process launcher thread fork. However the child process in that case, when -// it's not instrumented with cygprofile, directly calls exec(). This is safe -// since the child process doesn't try to release a lock acquired by another -// thread in the parent process which would lead to a deadlock. This problem was -// actually observed by trying to port the current version of cygprofile.cc to -// Linux. -#error This is only supported on Android. -#endif - -// The following is only exposed for testing. -namespace cygprofile { - -class Thread; - -// Single log entry recorded for each function call. -struct LogEntry { - LogEntry(const void* address, pid_t pid, pid_t tid); - - const timespec time; - const pid_t pid; - const pid_t tid; - const void* const address; -}; - -// Per-thread function calls log. -class ThreadLog { - public: - // Callback invoked for flushing that can be provided for testing. - typedef base::Callback<void (std::vector<LogEntry>*)> FlushCallback; - - ThreadLog(); - - // Used for testing. - ThreadLog(const FlushCallback& flush_callback); - - ~ThreadLog(); - - // Must only be called from the thread this ThreadLog instance is watching. - void AddEntry(void* address); - - // Can be called from any thread. - void TakeEntries(std::vector<LogEntry>* output); - - // Flushes the provided vector of entries to a file and clears it. Note that - // this can be called from any thread. - void Flush(std::vector<LogEntry>* entries) const; - - private: - // Default implementation (that can be overridden for testing) of the method - // above. - void FlushInternal(std::vector<LogEntry>* entries) const; - - // Process ID, as returned by getpid(). - const pid_t pid_; - - // Thread identifier as Linux kernel shows it. LWP (light-weight process) is - // a unique ID of the thread in the system, unlike pthread_self() which is the - // same for fork()-ed threads. - const pid_t tid_; - - // Current thread is inside the instrumentation routine. - bool in_use_; - - // Callback used to flush entries. - const FlushCallback flush_callback_; - - // Keeps track of all functions that have been logged on this thread so we do - // not record duplicates. - base::hash_set<void*> called_functions_; - - // A lock that guards |entries_| usage between per-thread instrumentation - // routine and timer flush callback. So the contention could happen only - // during the flush, every 15 secs. - base::Lock lock_; - - std::vector<LogEntry> entries_; - - DISALLOW_COPY_AND_ASSIGN(ThreadLog); -}; - -// Manages a list of per-thread logs. -class ThreadLogsManager { - public: - ThreadLogsManager(); - - // Used for testing. The provided callbacks are used for testing to - // synchronize the internal thread with the unit test running on the main - // thread. - ThreadLogsManager(const base::Closure& wait_callback, - const base::Closure& notify_callback); - - ~ThreadLogsManager(); - - // Can be called from any thread. - void AddLog(std::unique_ptr<ThreadLog> new_log); - - private: - void StartInternalFlushThread_Locked(); - - // Flush thread's entry point. - void FlushAllLogsOnFlushThread(); - - // Used to make the internal thread sleep before each flush iteration. - const base::Closure wait_callback_; - // Used to trigger a notification when a flush happened on the internal - // thread. - const base::Closure notify_callback_; - - // Protects the state below. - base::Lock lock_; - std::unique_ptr<Thread> flush_thread_; - std::vector<std::unique_ptr<ThreadLog>> logs_; - - DISALLOW_COPY_AND_ASSIGN(ThreadLogsManager); -}; - -} // namespace cygprofile - -#endif // TOOLS_CYGPROFILE_CYGPROFILE_H_
diff --git a/tools/cygprofile/cygprofile_perftest.cc b/tools/cygprofile/cygprofile_perftest.cc deleted file mode 100644 index ae8fe3e7..0000000 --- a/tools/cygprofile/cygprofile_perftest.cc +++ /dev/null
@@ -1,67 +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 "tools/cygprofile/cygprofile.h" - -#include <cstdint> -#include <vector> - -#include "base/strings/stringprintf.h" -#include "base/time/time.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" - -namespace cygprofile { - -namespace { - -void AddEntryCost(int iterations, int addresses_count) { - // This is intentionally leaky. ThreadLog() destructor would call abort(), - // limiting us to a single test. Leaking ThreadLog is fine as long as we clean - // up the entries. - auto* thread_log = new ThreadLog(); - - auto tick = base::TimeTicks::Now(); - for (int i = 0; i < iterations; i++) { - for (int address = 0; address < addresses_count; address++) { - thread_log->AddEntry(reinterpret_cast<void*>(address)); - } - } - auto tock = base::TimeTicks::Now(); - double nanos = static_cast<double>((tock - tick).InNanoseconds()); - auto ns_per_call = - nanos / (iterations * static_cast<double>(addresses_count)); - auto modifier = base::StringPrintf("_%d_%d", iterations, addresses_count); - perf_test::PrintResult("AddEntryCostPerCall", modifier, "", ns_per_call, "ns", - true); - - // Entries cleanup, see comment at the beginning of the function. - std::vector<LogEntry> entries; - thread_log->TakeEntries(&entries); -} -} // namespace - -TEST(CygprofilePerfTest, CreateEntries_10_10000) { - AddEntryCost(10, 10000); -} - -TEST(CygprofilePerfTest, CreateEntries_100_10000) { - AddEntryCost(100, 10000); -} - -TEST(CygprofilePerfTest, CreateEntries_10_100000) { - AddEntryCost(10, 100000); -} - -TEST(CygprofilePerfTest, CreateEntries_100_1000000) { - AddEntryCost(100, 100000); -} - -} // namespace cygprofile - -// Custom runner implementation since base's one requires JNI on Android. -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -}
diff --git a/tools/cygprofile/cygprofile_unittest.cc b/tools/cygprofile/cygprofile_unittest.cc deleted file mode 100644 index 5be4804..0000000 --- a/tools/cygprofile/cygprofile_unittest.cc +++ /dev/null
@@ -1,106 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "tools/cygprofile/cygprofile.h" - -#include <stdint.h> -#include <sys/time.h> -#include <utility> -#include <vector> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "base/synchronization/waitable_event.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cygprofile { -namespace { - -void FlushEntries(std::vector<LogEntry>* destination, - std::vector<LogEntry>* entries) { - CHECK_EQ(0U, destination->size()); - // Move the provided |entries| vector to the provided |destination| so that - // the unit test that triggered the flush can check it. - destination->swap(*entries); -} - -// Flush callback that should not be invoked. -void CheckFlushDoesNotHappen(std::vector<LogEntry>* entries) { - NOTREACHED(); -} - -uint64_t GetUsecSecTimeFromTimeSpec(struct timespec timespec) { - return timespec.tv_sec * 1000 * 1000 + timespec.tv_nsec / 1000; -} - -TEST(CygprofileTest, ThreadLogBasic) { - ThreadLog thread_log(base::Bind(&CheckFlushDoesNotHappen)); - - thread_log.AddEntry(reinterpret_cast<void*>(0x2)); - thread_log.AddEntry(reinterpret_cast<void*>(0x1)); - - std::vector<LogEntry> entries; - thread_log.TakeEntries(&entries); - - ASSERT_EQ(2U, entries.size()); - // The entries should appear in their insertion order. - const LogEntry& first_entry = entries[0]; - ASSERT_EQ(reinterpret_cast<uintptr_t>(first_entry.address), 2U); - ASSERT_EQ(getpid(), first_entry.pid); - ASSERT_LT(0, first_entry.tid); - - const LogEntry& second_entry = entries[1]; - ASSERT_EQ(1U, reinterpret_cast<uintptr_t>(second_entry.address)); - ASSERT_EQ(first_entry.pid, second_entry.pid); - ASSERT_EQ(first_entry.tid, second_entry.tid); - - ASSERT_GE(GetUsecSecTimeFromTimeSpec(second_entry.time), - GetUsecSecTimeFromTimeSpec(first_entry.time)); -} - -TEST(CygprofileTest, ManagerBasic) { - base::WaitableEvent wait_event( - base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - base::WaitableEvent notify_event( - base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - - ThreadLogsManager manager( - base::Bind(&base::WaitableEvent::Wait, base::Unretained(&wait_event)), - base::Bind(&base::WaitableEvent::Signal, - base::Unretained(¬ify_event))); - - std::vector<LogEntry> entries; - std::unique_ptr<ThreadLog> thread_log( - new ThreadLog(base::Bind(&FlushEntries, base::Unretained(&entries)))); - - thread_log->AddEntry(reinterpret_cast<void*>(0x2)); - thread_log->AddEntry(reinterpret_cast<void*>(0x3)); - - // This should make the manager spawn its internal flush thread which will - // wait for a notification before it starts doing some work. - manager.AddLog(std::move(thread_log)); - - EXPECT_EQ(0U, entries.size()); - // This will wake up the internal thread. - wait_event.Signal(); - // Now it's our turn to wait until it performed the flush. - notify_event.Wait(); - - // The flush should have moved the data to the local vector of entries. - EXPECT_EQ(2U, entries.size()); - ASSERT_EQ(2U, reinterpret_cast<uintptr_t>(entries[0].address)); - ASSERT_EQ(3U, reinterpret_cast<uintptr_t>(entries[1].address)); -} - -} // namespace -} // namespace cygprofile - -// Custom runner implementation since base's one requires JNI on Android. -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -}
diff --git a/tools/cygprofile/mergetraces.py b/tools/cygprofile/mergetraces.py deleted file mode 100755 index 2ac8393..0000000 --- a/tools/cygprofile/mergetraces.py +++ /dev/null
@@ -1,254 +0,0 @@ -#!/usr/bin/python -# Copyright 2013 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Use: ../mergetraces.py `ls cyglog.* -Sr` > merged_cyglog - -""""Merge multiple logs files from different processes into a single log. - -Given two log files of execution traces, merge the traces into a single trace. -Merging will use timestamps (i.e. the first two columns of logged calls) to -create a single log that is an ordered trace of calls by both processes. -""" - -import optparse -import string -import sys - - -def ParseLogLines(lines): - """Parse log file lines. - - Args: - lines: lines from log file produced by profiled run - - Below is an example of a small log file: - 5086e000-52e92000 r-xp 00000000 b3:02 51276 libchromeview.so - secs usecs pid:threadid func - START - 1314897086 795828 3587:1074648168 0x509e105c - 1314897086 795874 3587:1074648168 0x509e0eb4 - 1314897086 796326 3587:1074648168 0x509e0e3c - 1314897086 796552 3587:1074648168 0x509e07bc - END - - Returns: - tuple conisiting of 1) an ordered list of the logged calls, as an array of - fields, 2) the virtual start address of the library, used to compute the - offset of the symbol in the library and 3) the virtual end address - """ - call_lines = [] - vm_start = 0 - vm_end = 0 - dash_index = lines[0].find ('-') - space_index = lines[0].find (' ') - vm_start = int (lines[0][:dash_index], 16) - vm_end = int (lines[0][dash_index+1:space_index], 16) - for line in lines[2:]: - line = line.strip() - fields = line.split() - call_lines.append (fields) - - return (call_lines, vm_start, vm_end) - - -def HasDuplicates(calls): - """Makes sure that calls are only logged once. - - Args: - calls: list of calls logged - - Returns: - boolean indicating if calls has duplicate calls - """ - seen = set([]) - for call in calls: - if call[3] in seen: - return True - seen.add(call[3]) - return False - -def CheckTimestamps(calls): - """Prints warning to stderr if the call timestamps are not in order. - - Args: - calls: list of calls logged - """ - index = 0 - last_timestamp_secs = -1 - last_timestamp_us = -1 - while (index < len (calls)): - timestamp_secs = int (calls[index][0]) - timestamp_us = int (calls[index][1]) - timestamp = (timestamp_secs * 1000000) + timestamp_us - last_timestamp = (last_timestamp_secs * 1000000) + last_timestamp_us - if (timestamp < last_timestamp): - raise Exception("last_timestamp: " + str(last_timestamp_secs) - + " " + str(last_timestamp_us) + " timestamp: " - + str(timestamp_secs) + " " + str(timestamp_us) + "\n") - last_timestamp_secs = timestamp_secs - last_timestamp_us = timestamp_us - index = index + 1 - - -def Convert(call_lines, start_address, end_address): - """Converts the call addresses to static offsets and removes invalid calls. - - Removes profiled calls not in shared library using start and end virtual - addresses, converts strings to integer values, coverts virtual addresses to - address in shared library. - - Returns: - list of calls as tuples (sec, usec, pid:tid, callee) - """ - converted_calls = [] - call_addresses = set() - for fields in call_lines: - secs = int (fields[0]) - usecs = int (fields[1]) - callee = int (fields[3], 16) - # Eliminate repetitions of the same function. - if callee in call_addresses: - continue - # Eliminate small addresses. It should be safe to do so because these point - # before the .text section (it is in .plt or earlier). - # TODO(pasko): understand why __cyg_profile_func_enter may output a small - # offset sometimes. - if callee < start_address + 4096: - sys.stderr.write('WARNING: ignoring small address: %s' % - hex(callee - start_address)) - call_addresses.add(callee) - continue - if start_address <= callee < end_address: - converted_calls.append((secs, usecs, fields[2], (callee - start_address))) - call_addresses.add(callee) - return converted_calls - - -def Timestamp(trace_entry): - return int (trace_entry[0]) * 1000000 + int(trace_entry[1]) - - -def AddTrace (tracemap, trace): - """Adds a trace to the tracemap. - - Adds entries in the trace to the tracemap. All new calls will be added to - the tracemap. If the calls already exist in the tracemap then they will be - replaced if they happened sooner in the new trace. - - Args: - tracemap: the tracemap - trace: the trace - - """ - for trace_entry in trace: - call = trace_entry[3] - if (not call in tracemap) or ( - Timestamp(tracemap[call]) > Timestamp(trace_entry)): - tracemap[call] = trace_entry - - -def GroupByProcessAndThreadId(input_trace): - """Returns an array of traces grouped by pid and tid. - - This is used to make the order of functions not depend on thread scheduling - which can be greatly impacted when profiling is done with cygprofile. As a - result each thread has its own contiguous segment of code (ordered by - timestamp) and processes also have their code isolated (i.e. not interleaved). - """ - def MakeTimestamp(sec, usec): - return sec * 1000000 + usec - - def PidAndTidFromString(pid_and_tid): - strings = pid_and_tid.split(':') - return (int(strings[0]), int(strings[1])) - - tid_to_pid_map = {} - pid_first_seen = {} - tid_first_seen = {} - - for (sec, usec, pid_and_tid, _) in input_trace: - (pid, tid) = PidAndTidFromString(pid_and_tid) - - # Make sure that thread IDs are unique since this is a property we rely on. - if tid_to_pid_map.setdefault(tid, pid) != pid: - raise Exception( - 'Seen PIDs %d and %d for TID=%d. Thread-IDs must be unique' % ( - tid_to_pid_map[tid], pid, tid)) - - if not pid in pid_first_seen: - pid_first_seen[pid] = MakeTimestamp(sec, usec) - if not tid in tid_first_seen: - tid_first_seen[tid] = MakeTimestamp(sec, usec) - - def CompareEvents(event1, event2): - (sec1, usec1, pid_and_tid, _) = event1 - (pid1, tid1) = PidAndTidFromString(pid_and_tid) - (sec2, usec2, pid_and_tid, _) = event2 - (pid2, tid2) = PidAndTidFromString(pid_and_tid) - - pid_cmp = cmp(pid_first_seen[pid1], pid_first_seen[pid2]) - if pid_cmp != 0: - return pid_cmp - tid_cmp = cmp(tid_first_seen[tid1], tid_first_seen[tid2]) - if tid_cmp != 0: - return tid_cmp - return cmp(MakeTimestamp(sec1, usec1), MakeTimestamp(sec2, usec2)) - - return sorted(input_trace, cmp=CompareEvents) - - -def Main(): - """Merge two traces for code in specified library and write to stdout. - - Merges the two traces and coverts the virtual addresses to the offsets in the - library. First line of merged trace has dummy virtual address of 0-ffffffff - so that symbolizing the addresses uses the addresses in the log, since the - addresses have already been converted to static offsets. - """ - parser = optparse.OptionParser('usage: %prog trace1 ... traceN') - (_, args) = parser.parse_args() - if len(args) <= 1: - parser.error('expected at least the following args: trace1 trace2') - - step = 0 - - # Maps function addresses to their corresponding trace entry. - tracemap = dict() - - for trace_file in args: - step += 1 - sys.stderr.write(" " + str(step) + "/" + str(len(args)) + - ": " + trace_file + ":\n") - - trace_lines = map(string.rstrip, open(trace_file).readlines()) - (trace_calls, trace_start, trace_end) = ParseLogLines(trace_lines) - CheckTimestamps(trace_calls) - sys.stderr.write("Len: " + str(len(trace_calls)) + - ". Start: " + hex(trace_start) + - ", end: " + hex(trace_end) + '\n') - - trace_calls = Convert(trace_calls, trace_start, trace_end) - sys.stderr.write("Converted len: " + str(len(trace_calls)) + "\n") - - AddTrace(tracemap, trace_calls) - sys.stderr.write("Merged len: " + str(len(tracemap)) + "\n") - - # Extract the resulting trace from the tracemap - merged_trace = [] - for call in tracemap: - merged_trace.append(tracemap[call]) - merged_trace.sort(key=Timestamp) - - grouped_trace = GroupByProcessAndThreadId(merged_trace) - - print "0-ffffffff r-xp 00000000 xx:00 00000 ./" - print "secs\tusecs\tpid:threadid\tfunc" - for call in grouped_trace: - print (str(call[0]) + "\t" + str(call[1]) + "\t" + call[2] + "\t" + - hex(call[3])) - - -if __name__ == '__main__': - Main()
diff --git a/tools/cygprofile/mergetraces_unittest.py b/tools/cygprofile/mergetraces_unittest.py deleted file mode 100644 index de88137..0000000 --- a/tools/cygprofile/mergetraces_unittest.py +++ /dev/null
@@ -1,51 +0,0 @@ -# Copyright 2014 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import unittest - -import mergetraces - -class GroupByProcessAndThreadIdTestBasic(unittest.TestCase): - def runTest(self): - # (sec, usec, 'pid:tid', function address). - input_trace = [ - (100, 10, '2000:2001', 0x5), - (100, 11, '2000:2001', 0x3), - (100, 13, '2000:1999', 0x8), - (100, 14, '2000:2000', 0x7), - (120, 13, '2001:2003', 0x9), - (150, 12, '2001:2004', 0x6), - (180, 11, '2000:2000', 0x1), - ] - - # Functions should be grouped by thread-id and PIDs should not be - # interleaved. - expected_trace = [ - (100, 10, '2000:2001', 0x5), - (100, 11, '2000:2001', 0x3), - (100, 13, '2000:1999', 0x8), - (100, 14, '2000:2000', 0x7), - (180, 11, '2000:2000', 0x1), - (120, 13, '2001:2003', 0x9), - (150, 12, '2001:2004', 0x6), - ] - - grouped_trace = mergetraces.GroupByProcessAndThreadId(input_trace) - - self.assertEqual(grouped_trace, expected_trace) - -class GroupByProcessAndThreadIdFailsWithNonUniqueTIDs(unittest.TestCase): - def runTest(self): - # (sec, usec, 'pid:tid', function address). - input_trace = [ - (100, 10, '1999:2001', 0x5), - (100, 10, '1988:2001', 0x5), - ] - - try: - mergetraces.GroupByProcessAndThreadId(input_trace) - except Exception: - return - - self.fail('Multiple processes should not have a same thread-ID.')
diff --git a/tools/cygprofile/orderfile_generator_backend.py b/tools/cygprofile/orderfile_generator_backend.py index 147a067..96348a5 100755 --- a/tools/cygprofile/orderfile_generator_backend.py +++ b/tools/cygprofile/orderfile_generator_backend.py
@@ -250,7 +250,7 @@ """Handles compilation of clank.""" def __init__(self, out_dir, step_recorder, arch, jobs, max_load, use_goma, - goma_dir, lightweight_instrumentation): + goma_dir): self._out_dir = out_dir self._step_recorder = step_recorder self._arch = arch @@ -258,7 +258,6 @@ self._max_load = max_load self._use_goma = use_goma self._goma_dir = goma_dir - self._lightweight_instrumentation = lightweight_instrumentation lib_chrome_so_dir = 'lib.unstripped' self.lib_chrome_so = os.path.join( self._out_dir, 'Release', lib_chrome_so_dir, 'libchrome.so') @@ -288,8 +287,6 @@ 'use_goma=' + str(self._use_goma).lower(), 'use_order_profiling=' + str(instrumented).lower(), ] - if instrumented and self._lightweight_instrumentation: - args.append('use_lightweight_order_profiling=true') if self._goma_dir: args += ['goma_dir="%s"' % self._goma_dir] @@ -420,8 +417,6 @@ generates an updated orderfile. """ _CLANK_REPO = os.path.join(constants.DIR_SOURCE_ROOT, 'clank') - _MERGE_TRACES_SCRIPT = os.path.join( - constants.DIR_SOURCE_ROOT, 'tools', 'cygprofile', 'mergetraces.py') _CYGLOG_TO_ORDERFILE_SCRIPT = os.path.join( constants.DIR_SOURCE_ROOT, 'tools', 'cygprofile', 'cyglog_to_orderfile.py') @@ -460,18 +455,12 @@ if options.profile: output_directory = os.path.join(self._instrumented_out_dir, 'Release') host_cyglog_dir = os.path.join(output_directory, 'cyglog_data') - # Only override the defaults when using lightweight instrumentation, - # as the regular profiling code is likely too slow for these. urls = [profile_android_startup.AndroidProfileTool.TEST_URL] use_wpr = True simulate_user = False - if options.simulate_user and not options.lightweight_instrumentation: - logging.error( - '--simulate-user required --lightweight-instrumentation, ignoring.') - if options.lightweight_instrumentation: - urls = options.urls - use_wpr = not options.no_wpr - simulate_user = options.simulate_user + urls = options.urls + use_wpr = not options.no_wpr + simulate_user = options.simulate_user self._profiler = profile_android_startup.AndroidProfileTool( output_directory, host_cyglog_dir, use_wpr, urls, simulate_user) @@ -486,27 +475,6 @@ assert os.path.isdir(constants.DIR_SOURCE_ROOT), 'No src directory found' symbol_extractor.SetArchitecture(options.arch) - def _RunCygprofileUnitTests(self): - """Builds, deploys and runs cygprofile_unittests.""" - # There an no unittests (yet) for the lightweight instrumentation. - # TODO(lizeb): Fix this. - if self._options.lightweight_instrumentation: - return - tools_compiler = ClankCompiler( - os.path.dirname(constants.GetOutDirectory()), - self._step_recorder, self._options.arch, self._options.jobs, - self._options.max_load, self._options.use_goma, self._options.goma_dir, - self._options.lightweight_instrumentation) - tools_compiler.Build(instrumented=False, target='android_tools') - self._compiler.Build(instrumented=True, target='cygprofile_unittests') - - self._step_recorder.BeginStep('Deploy and run cygprofile_unittests') - exit_code = self._profiler.RunCygprofileTests() - - if exit_code != 0: - self._step_recorder.FailStep( - 'cygprofile_unittests exited with non-0 status: %d' % exit_code) - @staticmethod def _RemoveBlanks(src_file, dest_file): """A utility to remove blank lines from a file. @@ -537,20 +505,14 @@ self._compiler.chrome_apk, constants.PACKAGE_INFO['chrome']) self._step_recorder.BeginStep('Process cyglog') - if self._options.lightweight_instrumentation: - assert os.path.exists(self._compiler.lib_chrome_so) - offsets = process_profiles.GetReachedOffsetsFromDumpFiles( - files, self._compiler.lib_chrome_so) - if not offsets: - raise Exception('No profiler offsets found in {}'.format( - '\n'.join(files))) - with open(self._MERGED_CYGLOG_FILENAME, 'w') as f: - f.write('\n'.join(map(str, offsets))) - else: - with open(self._MERGED_CYGLOG_FILENAME, 'w') as merged_cyglog: - self._step_recorder.RunCommand([self._MERGE_TRACES_SCRIPT] + files, - constants.DIR_SOURCE_ROOT, - stdout=merged_cyglog) + assert os.path.exists(self._compiler.lib_chrome_so) + offsets = process_profiles.GetReachedOffsetsFromDumpFiles( + files, self._compiler.lib_chrome_so) + if not offsets: + raise Exception('No profiler offsets found in {}'.format( + '\n'.join(files))) + with open(self._MERGED_CYGLOG_FILENAME, 'w') as f: + f.write('\n'.join(map(str, offsets))) except Exception: for f in files: self._SaveForDebugging(f) @@ -564,10 +526,7 @@ '--target-arch=' + self._options.arch, '--native-library=' + self._compiler.lib_chrome_so, '--output=' + self._GetUnpatchedOrderfileFilename()] - if self._options.lightweight_instrumentation: - command_args.append('--reached-offsets=' + self._MERGED_CYGLOG_FILENAME) - else: - command_args.append('--merged-cyglog=' + self._MERGED_CYGLOG_FILENAME) + command_args.append('--reached-offsets=' + self._MERGED_CYGLOG_FILENAME) self._step_recorder.RunCommand( [self._CYGLOG_TO_ORDERFILE_SCRIPT] + command_args) except CommandError: @@ -688,13 +647,9 @@ self._instrumented_out_dir, self._step_recorder, self._options.arch, self._options.jobs, self._options.max_load, self._options.use_goma, - self._options.goma_dir, - self._options.lightweight_instrumentation) - self._RunCygprofileUnitTests() - if self._options.lightweight_instrumentation: - _EnsureOrderfileStartsWithAnchorSection(self._GetPathToOrderfile()) - self._compiler.CompileChromeApk( - True, self._options.lightweight_instrumentation) + self._options.goma_dir) + _EnsureOrderfileStartsWithAnchorSection(self._GetPathToOrderfile()) + self._compiler.CompileChromeApk(True) self._GenerateAndProcessProfile() self._MaybeArchiveOrderfile(self._GetUnpatchedOrderfileFilename()) profile_uploaded = True @@ -710,8 +665,7 @@ self._compiler = ClankCompiler( self._uninstrumented_out_dir, self._step_recorder, self._options.arch, self._options.jobs, self._options.max_load, - self._options.use_goma, self._options.goma_dir, - self._options.lightweight_instrumentation) + self._options.use_goma, self._options.goma_dir) self._compiler.CompileLibchrome(False) self._PatchOrderfile() # Because identical code folding is a bit different with and without @@ -748,10 +702,6 @@ """Creates and returns the argument parser.""" parser = argparse.ArgumentParser() parser.add_argument( - '--regular-instrumentation', action='store_false', - dest='lightweight_instrumentation', - help='Use the regular instrumentation path') - parser.add_argument( '--buildbot', action='store_true', help='If true, the script expects to be run on a buildbot') parser.add_argument(
diff --git a/tools/cygprofile/profile_android_startup.py b/tools/cygprofile/profile_android_startup.py index ba96bce8..c71fb53 100755 --- a/tools/cygprofile/profile_android_startup.py +++ b/tools/cygprofile/profile_android_startup.py
@@ -393,6 +393,9 @@ cyglog_dir = os.path.join(self._host_cyglog_dir, 'cyglog') files = os.listdir(cyglog_dir) + if len(files) == 0: + raise NoCyglogDataError('No cyglog data was collected') + return [os.path.join(cyglog_dir, x) for x in files]
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index bb90bf4..e5105caef 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -25712,6 +25712,7 @@ <int value="-1868284723" label="DirectManipulationStylus:disabled"/> <int value="-1867382602" label="WebRTC-H264WithOpenH264FFmpeg:enabled"/> <int value="-1867342522" label="MaterialDesignHistory:enabled"/> + <int value="-1863962664" label="LockScreenNotifications:enabled"/> <int value="-1861814223" label="MidiManagerDynamicInstantiation:enabled"/> <int value="-1860481724" label="ChromeHomeExpandButton:enabled"/> <int value="-1859095876" label="Previews:disabled"/> @@ -26059,6 +26060,7 @@ <int value="-1033738911" label="enable-mac-views-dialogs"/> <int value="-1029920490" label="IdleTimeSpellChecking:enabled"/> <int value="-1028733699" label="MacViewsWebUIDialogs:disabled"/> + <int value="-1027254093" label="LockScreenNotifications:disabled"/> <int value="-1027124889" label="NtlmV2Enabled:enabled"/> <int value="-1022971520" label="enable-search-button-in-omnibox-for-str"/> <int value="-1022165708" label="BreakingNewsPush:disabled"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 91c3e01..b7db1f6 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml
@@ -80416,6 +80416,18 @@ </summary> </histogram> +<histogram name="Security.SecurityLevel.DownloadStarted" enum="SecurityLevel"> + <owner>cthomp@chromium.org</owner> + <summary> + Records the security level of the page that initiated a download (rather + than the security state of the connection to the download URL itself). The + recorded security level is the level of the page the download was initiated + from, not that of the download URL. This histogram is not recorded for + downloads that are initiated in a new tab or window, as the security level + of the initiating page cannot be tracked. + </summary> +</histogram> + <histogram name="Security.SecurityLevel.FormSubmission" enum="SecurityLevel"> <owner>carlosil@chromium.org</owner> <owner>cthomp@chromium.org</owner>
diff --git a/tools/perf/process_perf_results.py b/tools/perf/process_perf_results.py index 1bd7bbd6..5184774 100755 --- a/tools/perf/process_perf_results.py +++ b/tools/perf/process_perf_results.py
@@ -90,21 +90,35 @@ for f in listdir(join(task_output_dir, directory)) ] + # We need to keep track of disabled benchmarks so we don't try to + # upload the results. + disabled_benchmarks = [] test_results_list = [] tmpfile_dir = tempfile.mkdtemp('resultscache') try: for directory in benchmark_directory_list: - if '.reference' in directory: - # We don't need to upload reference build data to the - # flakiness dashboard since we don't monitor the ref build - continue with open(join(directory, 'test_results.json')) as json_data: - test_results_list.append(json.load(json_data)) + json_results = json.load(json_data) + if json_results.get('version') == 3: + # Non-telemetry tests don't have written json results but + # if they are executing then they are enabled and will generate + # chartjson results. + if not bool(json_results.get('tests')): + disabled_benchmarks.append(directory) + if '.reference' in directory: + # We don't need to upload reference build data to the + # flakiness dashboard since we don't monitor the ref build + continue + test_results_list.append(json_results) _merge_json_output(output_json, test_results_list) with oauth_api.with_access_token(service_account_file) as oauth_file: for directory in benchmark_directory_list: print 'Uploading perf results from %s benchmark' % directory + if directory in disabled_benchmarks: + # We don't upload disabled benchmarks + print 'Benchmark %s disabled' % directory + continue _upload_perf_results(join(directory, 'perf_results.json'), directory, configuration_name, build_properties, oauth_file, tmpfile_dir)
diff --git a/ui/base/ui_base_features.cc b/ui/base/ui_base_features.cc index c227b35..2ff84fc 100644 --- a/ui/base/ui_base_features.cc +++ b/ui/base/ui_base_features.cc
@@ -73,4 +73,17 @@ #endif } +#if defined(OS_MACOSX) && BUILDFLAG(MAC_VIEWS_BROWSER) +// Causes Views browser builds to use Views browser windows by default rather +// than Cocoa browser windows. +const base::Feature kViewsBrowserWindows{"ViewsBrowserWindows", + base::FEATURE_DISABLED_BY_DEFAULT}; + +// Returns whether a Views-capable browser build should use the Cocoa browser +// UI. +bool IsViewsBrowserCocoa() { + return !base::FeatureList::IsEnabled(kViewsBrowserWindows); +} +#endif // defined(OS_MACOSX) && BUILDFLAG(MAC_VIEWS_BROWSER) + } // namespace features
diff --git a/ui/base/ui_base_features.h b/ui/base/ui_base_features.h index f21fb22..c7d20168e 100644 --- a/ui/base/ui_base_features.h +++ b/ui/base/ui_base_features.h
@@ -8,6 +8,7 @@ #include "base/feature_list.h" #include "build/build_config.h" #include "ui/base/ui_base_export.h" +#include "ui/base/ui_features.h" namespace features { @@ -39,6 +40,14 @@ // TODO(sky): rename this to IsWindowServiceEnabled(). UI_BASE_EXPORT bool IsMusEnabled(); +#if defined(OS_MACOSX) && BUILDFLAG(MAC_VIEWS_BROWSER) +UI_BASE_EXPORT extern const base::Feature kViewsBrowserWindows; + +// Returns whether a Views-capable browser build should use the Cocoa browser +// UI. +UI_BASE_EXPORT bool IsViewsBrowserCocoa(); +#endif // defined(OS_MACOSX) && BUILDFLAG(MAC_VIEWS_BROWSER) + } // namespace features #endif // UI_BASE_UI_BASE_FEATURES_H_
diff --git a/ui/base/win/on_screen_keyboard_display_manager_tab_tip.cc b/ui/base/win/on_screen_keyboard_display_manager_tab_tip.cc index 23b0379..e4c4a6d0 100644 --- a/ui/base/win/on_screen_keyboard_display_manager_tab_tip.cc +++ b/ui/base/win/on_screen_keyboard_display_manager_tab_tip.cc
@@ -22,7 +22,7 @@ #include "base/win/windows_version.h" #include "ui/base/win/hidden_window.h" #include "ui/base/win/osk_display_observer.h" -#include "ui/display/win/dpi.h" +#include "ui/display/win/screen_win.h" #include "ui/gfx/geometry/dip_util.h" namespace { @@ -66,10 +66,13 @@ void AddObserver(OnScreenKeyboardObserver* observer); void RemoveObserver(OnScreenKeyboardObserver* observer); - // Returns true if the osk is visible. Sets osk bounding rect if non-null - static bool IsKeyboardVisible(gfx::Rect* osk_bounding_rect); + // Returns true if the osk is visible. + static bool IsKeyboardVisible(); private: + // Returns the occluded rect in dips. + gfx::Rect GetOccludedRect(); + // Executes as a task and detects if the on screen keyboard is displayed. // Once the keyboard is displayed it schedules the HideIfNecessary() task to // detect when the keyboard is or should be hidden. @@ -82,7 +85,7 @@ // Notifies observers that the keyboard was displayed. // A recurring task HideIfNecessary() is started to detect when the OSK // disappears. - void HandleKeyboardVisible(); + void HandleKeyboardVisible(const gfx::Rect& occluded_rect); // Notifies observers that the keyboard was hidden. // The observer list is cleared out after this notification. @@ -97,9 +100,6 @@ // Tracks if the keyboard was displayed. bool osk_visible_notification_received_ = false; - // The keyboard dimensions in pixels. - gfx::Rect osk_rect_pixels_; - // Set to true if a call to DetectKeyboard() was made. bool keyboard_detect_requested_ = false; @@ -178,22 +178,39 @@ } // static -bool OnScreenKeyboardDetector::IsKeyboardVisible(gfx::Rect* osk_bounding_rect) { +bool OnScreenKeyboardDetector::IsKeyboardVisible() { HWND osk = ::FindWindow(kOSKClassName, nullptr); if (!::IsWindow(osk)) return false; - if (osk_bounding_rect) { - RECT osk_rect = {}; - ::GetWindowRect(osk, &osk_rect); - *osk_bounding_rect = gfx::Rect(osk_rect); - } return ::IsWindowVisible(osk) && ::IsWindowEnabled(osk); } +gfx::Rect OnScreenKeyboardDetector::GetOccludedRect() { + gfx::Rect occluded_rect; + HWND osk = ::FindWindow(kOSKClassName, nullptr); + if (!::IsWindow(osk) || !::IsWindowVisible(osk) || !::IsWindowEnabled(osk)) + return occluded_rect; + + RECT osk_rect = {}; + RECT main_window_rect = {}; + if (!::GetWindowRect(osk, &osk_rect) || + !::GetWindowRect(main_window_, &main_window_rect)) { + return occluded_rect; + } + + gfx::Rect gfx_osk_rect(osk_rect); + gfx::Rect gfx_main_window_rect(main_window_rect); + + gfx_osk_rect.Intersect(gfx_main_window_rect); + + return display::win::ScreenWin::ScreenToDIPRect(main_window_, gfx_osk_rect); +} + void OnScreenKeyboardDetector::CheckIfKeyboardVisible() { - if (IsKeyboardVisible(&osk_rect_pixels_)) { + gfx::Rect occluded_rect = GetOccludedRect(); + if (!occluded_rect.IsEmpty()) { if (!osk_visible_notification_received_) - HandleKeyboardVisible(); + HandleKeyboardVisible(occluded_rect); } else { DVLOG(1) << "OSK did not come up. Something wrong."; } @@ -233,12 +250,13 @@ } } -void OnScreenKeyboardDetector::HandleKeyboardVisible() { +void OnScreenKeyboardDetector::HandleKeyboardVisible( + const gfx::Rect& occluded_rect) { DCHECK(!osk_visible_notification_received_); osk_visible_notification_received_ = true; for (OnScreenKeyboardObserver& observer : observers_) - observer.OnKeyboardVisible(osk_rect_pixels_); + observer.OnKeyboardVisible(occluded_rect); // Now that the keyboard is visible, run the task to detect if it was hidden. base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( @@ -251,7 +269,7 @@ void OnScreenKeyboardDetector::HandleKeyboardHidden() { osk_visible_notification_received_ = false; for (OnScreenKeyboardObserver& observer : observers_) - observer.OnKeyboardHidden(osk_rect_pixels_); + observer.OnKeyboardHidden(); ClearObservers(); } @@ -368,7 +386,7 @@ } bool OnScreenKeyboardDisplayManagerTabTip::IsKeyboardVisible() const { - return OnScreenKeyboardDetector::IsKeyboardVisible(nullptr); + return OnScreenKeyboardDetector::IsKeyboardVisible(); } } // namespace ui
diff --git a/ui/base/win/osk_display_observer.h b/ui/base/win/osk_display_observer.h index 8c5d092..16d341a 100644 --- a/ui/base/win/osk_display_observer.h +++ b/ui/base/win/osk_display_observer.h
@@ -17,10 +17,9 @@ public: virtual ~OnScreenKeyboardObserver() {} - // The |keyboard_rect| parameter contains the bounds of the keyboard in - // pixels. - virtual void OnKeyboardVisible(const gfx::Rect& keyboard_rect_in_pixels) {} - virtual void OnKeyboardHidden(const gfx::Rect& keyboard_rect_in_pixels) {} + // The |keyboard_rect| parameter contains the bounds of the keyboard in dips. + virtual void OnKeyboardVisible(const gfx::Rect& keyboard_rect) {} + virtual void OnKeyboardHidden() {} }; } // namespace ui
diff --git a/ui/gfx/x/x11.h b/ui/gfx/x/x11.h index eb53d6d..4bce2bc 100644 --- a/ui/gfx/x/x11.h +++ b/ui/gfx/x/x11.h
@@ -89,6 +89,7 @@ #undef Bool // Defined by X11/Xlib.h to int #undef RootWindow // Defined by X11/Xlib.h #undef DestroyAll // Defined by X11/X.h to 0 +#undef AddToList // Defined by X11/extensions/XI.h to 0 #undef COUNT // Defined by X11/extensions/XI.h to 0 #undef CREATE // Defined by X11/extensions/XI.h to 1 #undef DeviceAdded // Defined by X11/extensions/XI.h to 0
diff --git a/ui/views/controls/button/checkbox.cc b/ui/views/controls/button/checkbox.cc index 84684604..ecdcda3d 100644 --- a/ui/views/controls/button/checkbox.cc +++ b/ui/views/controls/button/checkbox.cc
@@ -16,6 +16,7 @@ #include "ui/gfx/color_utils.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/native_theme/native_theme.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/animation/ink_drop_impl.h" #include "ui/views/animation/ink_drop_ripple.h" #include "ui/views/controls/button/label_button_border.h" @@ -76,6 +77,7 @@ Checkbox::Checkbox(const base::string16& label, bool force_md) : LabelButton(NULL, label), checked_(false), + label_ax_id_(0), use_md_(force_md || ui::MaterialDesignController::IsSecondaryUiMaterial()) { SetHorizontalAlignment(gfx::ALIGN_LEFT); @@ -152,6 +154,18 @@ label()->SetMultiLine(multi_line); } +void Checkbox::SetAssociatedLabel(View* labelling_view) { + DCHECK(labelling_view); + label_ax_id_ = labelling_view->GetViewAccessibility().GetUniqueId().Get(); + ui::AXNodeData node_data; + labelling_view->GetAccessibleNodeData(&node_data); + // TODO(aleventhal) automatically handle setting the name from the related + // label in view_accessibility and have it update the name if the text of the + // associated label changes. + SetAccessibleName( + node_data.GetString16Attribute(ax::mojom::StringAttribute::kName)); +} + // TODO(tetsui): Remove this method and |use_md_| when MD for secondary UI // becomes default and IsSecondaryUiMaterial() is tautology. bool Checkbox::UseMd() const { @@ -176,6 +190,10 @@ node_data->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kCheck); } } + if (label_ax_id_) { + node_data->AddIntListAttribute(ax::mojom::IntListAttribute::kLabelledbyIds, + {label_ax_id_}); + } } void Checkbox::OnFocus() {
diff --git a/ui/views/controls/button/checkbox.h b/ui/views/controls/button/checkbox.h index f6605e8d..cec15a8 100644 --- a/ui/views/controls/button/checkbox.h +++ b/ui/views/controls/button/checkbox.h
@@ -39,6 +39,12 @@ void SetMultiLine(bool multi_line); + // If the accessible name should be the same as the labelling view's text, + // use this. It will set the accessible label relationship and copy the + // accessible name from the labelling views's accessible name. Any view with + // an accessible name can be used, e.g. a Label, StyledLabel or Link. + void SetAssociatedLabel(View* labelling_view); + protected: // Returns whether MD is enabled. Returns true if |force_md| in the // constructor or --secondary-ui-md flag is set. @@ -95,6 +101,9 @@ // The images for each button node_data. gfx::ImageSkia images_[2][2][STATE_COUNT]; + // The unique id for the associated label's accessible object. + int32_t label_ax_id_; + bool use_md_; DISALLOW_COPY_AND_ASSIGN(Checkbox);
diff --git a/ui/views/controls/styled_label.cc b/ui/views/controls/styled_label.cc index e99c027..51ae7229 100644 --- a/ui/views/controls/styled_label.cc +++ b/ui/views/controls/styled_label.cc
@@ -13,6 +13,7 @@ #include "base/i18n/rtl.h" #include "base/strings/string_util.h" +#include "ui/accessibility/ax_node_data.h" #include "ui/gfx/font_list.h" #include "ui/gfx/text_elider.h" #include "ui/gfx/text_utils.h" @@ -225,6 +226,15 @@ return insets; } +void StyledLabel::GetAccessibleNodeData(ui::AXNodeData* node_data) { + if (text_context_ == style::CONTEXT_DIALOG_TITLE) + node_data->role = ax::mojom::Role::kTitleBar; + else + node_data->role = ax::mojom::Role::kStaticText; + + node_data->SetName(text()); +} + gfx::Size StyledLabel::CalculatePreferredSize() const { return calculated_size_; }
diff --git a/ui/views/controls/styled_label.h b/ui/views/controls/styled_label.h index e32c6f6..14a76375 100644 --- a/ui/views/controls/styled_label.h +++ b/ui/views/controls/styled_label.h
@@ -127,6 +127,7 @@ // View: const char* GetClassName() const override; gfx::Insets GetInsets() const override; + void GetAccessibleNodeData(ui::AXNodeData* node_data) override; gfx::Size CalculatePreferredSize() const override; int GetHeightForWidth(int w) const override; void Layout() override;
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index be15588..51c15f6 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -319,9 +319,16 @@ } } -void Textfield::SetAssociatedLabel(Label* label) { - label_ax_id_ = label->GetViewAccessibility().GetUniqueId().Get(); - accessible_name_ = label->text(); +void Textfield::SetAssociatedLabel(View* labelling_view) { + DCHECK(labelling_view); + label_ax_id_ = labelling_view->GetViewAccessibility().GetUniqueId().Get(); + ui::AXNodeData node_data; + labelling_view->GetAccessibleNodeData(&node_data); + // TODO(aleventhal) automatically handle setting the name from the related + // label in view_accessibility and have it update the name if the text of the + // associated label changes. + SetAccessibleName( + node_data.GetString16Attribute(ax::mojom::StringAttribute::kName)); } void Textfield::SetReadOnly(bool read_only) {
diff --git a/ui/views/controls/textfield/textfield.h b/ui/views/controls/textfield/textfield.h index db30abd..5ab239d 100644 --- a/ui/views/controls/textfield/textfield.h +++ b/ui/views/controls/textfield/textfield.h
@@ -224,10 +224,11 @@ // label, use SetAssociatedLabel() instead. void SetAccessibleName(const base::string16& name); - // If the accessible name should be the same as the label text, use this. It - // will set both the accessible label relationship and the accessible name - // from the contents of the label. - void SetAssociatedLabel(Label* label); + // If the accessible name should be the same as the labelling view's text, + // use this. It will set the accessible label relationship and copy the + // accessible name from the labelling views's accessible name. Any view with + // an accessible name can be used, typically a Label, StyledLabel or Link. + void SetAssociatedLabel(View* labelling_view); // Set extra spacing placed between glyphs; used for obscured text styling. void SetGlyphSpacing(int spacing);