diff --git a/.gitignore b/.gitignore index c01e2ae9..98d23f96 100644 --- a/.gitignore +++ b/.gitignore
@@ -186,6 +186,7 @@ /ios/third_party/material_roboto_font_loader_ios/src /ios/third_party/material_sprited_animation_view_ios/src /ios/third_party/material_text_accessibility_ios/src +/ios/third_party/motion_animator_objc/src /ios/third_party/motion_interchange_objc/src /ios/third_party/ochamcrest/src /ios_internal
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 791d86e..213a2c76 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md
@@ -5,7 +5,8 @@ applies to our repos and organizations, issue trackers, mailing lists, blog content, and any other Chromium-supported communication group, as well as any private communication initiated in the context of these -spaces. +spaces. This code of conduct must be followed by everyone contributing to +the Chromium project, regardless of affiliation or position. Simply put, community discussions should be
diff --git a/DEPS b/DEPS index 02f64fd..46be599 100644 --- a/DEPS +++ b/DEPS
@@ -227,6 +227,11 @@ 'condition': 'checkout_ios', }, + 'src/ios/third_party/motion_animator_objc/src': { + 'url': Var('chromium_git') + '/external/github.com/material-motion/motion-animator-objc.git' + '@' + '60cf5680f1df8b181299c04ba22c32e388a7f0ba', + 'condition': 'checkout_ios', + }, + 'src/ios/third_party/ochamcrest/src': { 'url': Var('chromium_git') + '/external/github.com/hamcrest/OCHamcrest.git' + '@' + '92d9c14d13bb864255e65c09383564653896916b', 'condition': 'checkout_ios', @@ -313,7 +318,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'f6b946d71d43483dc701837aae4871927d0115bd', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6c5a1c4c3c97b568c79ee44a7b1d7ffac17e30d3', # DevTools node modules. Used on Linux buildbots only. 'src/third_party/devtools-node-modules': {
diff --git a/ash/display/display_move_window_util.cc b/ash/display/display_move_window_util.cc index 4a2cd6f..98fc0f57 100644 --- a/ash/display/display_move_window_util.cc +++ b/ash/display/display_move_window_util.cc
@@ -9,6 +9,7 @@ #include "ash/accessibility/accessibility_controller.h" #include "ash/shell.h" +#include "ash/wm/mru_window_tracker.h" #include "ash/wm/window_util.h" #include "ui/aura/window.h" #include "ui/display/display.h" @@ -141,6 +142,13 @@ if (!window) return; + // When |window_list| is not empty, |window| can only be the first one of the + // fresh built list if it is in the list. + MruWindowTracker::WindowList window_list = + Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(); + if (window_list.empty() || window_list.front() != window) + return; + display::Display origin_display = display::Screen::GetScreen()->GetDisplayNearestWindow(window); int64_t dest_display_id = GetNextDisplay(origin_display, direction);
diff --git a/ash/display/display_move_window_util_unittest.cc b/ash/display/display_move_window_util_unittest.cc index 0ce5e24..2807be5 100644 --- a/ash/display/display_move_window_util_unittest.cc +++ b/ash/display/display_move_window_util_unittest.cc
@@ -8,6 +8,7 @@ #include "ash/accessibility/test_accessibility_controller_client.h" #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/wm/mru_window_tracker.h" #include "ash/wm/window_util.h" #include "base/macros.h" #include "ui/aura/test/test_windows.h" @@ -248,4 +249,39 @@ client.last_a11y_alert()); } +// Tests that moving window between displays is no-op if active window is not in +// cycle window list. +TEST_F(DisplayMoveWindowUtilTest, NoMovementIfNotInCycleWindowList) { + display::Screen* screen = display::Screen::GetScreen(); + int64_t primary_id = screen->GetPrimaryDisplay().id(); + display::DisplayIdList list = + display::test::CreateDisplayIdList2(primary_id, primary_id + 1); + // Layout: [p][1] + display::DisplayLayoutBuilder builder(primary_id); + builder.AddDisplayPlacement(list[1], primary_id, + display::DisplayPlacement::RIGHT, 0); + display_manager()->layout_store()->RegisterLayoutForDisplayIdList( + list, builder.Build()); + UpdateDisplay("400x300,400x300"); + EXPECT_EQ(2U, display_manager()->GetNumDisplays()); + EXPECT_EQ(gfx::Rect(0, 0, 400, 300), + display_manager()->GetDisplayAt(0).bounds()); + EXPECT_EQ(gfx::Rect(400, 0, 400, 300), + display_manager()->GetDisplayAt(1).bounds()); + + // Create a window in app list container, which would be excluded in cycle + // window list. + std::unique_ptr<aura::Window> window = CreateChildWindow( + Shell::GetPrimaryRootWindow(), gfx::Rect(10, 20, 200, 100), + kShellWindowId_AppListContainer); + wm::ActivateWindow(window.get()); + EXPECT_EQ(list[0], screen->GetDisplayNearestWindow(window.get()).id()); + + MruWindowTracker::WindowList cycle_window_list = + Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(); + EXPECT_TRUE(cycle_window_list.empty()); + HandleMoveWindowToDisplay(DisplayMoveWindowDirection::kRight); + EXPECT_EQ(list[0], screen->GetDisplayNearestWindow(window.get()).id()); +} + } // namespace ash
diff --git a/ash/wm/OWNERS b/ash/wm/OWNERS index c1e24dc9f..26780820 100644 --- a/ash/wm/OWNERS +++ b/ash/wm/OWNERS
@@ -1,5 +1,3 @@ -pkotwicz@chromium.org -varkha@chromium.org flackr@chromium.org # COMPONENT: UI>Shell>WindowManager
diff --git a/ash/wm/mru_window_tracker.cc b/ash/wm/mru_window_tracker.cc index 5ee031d2..0a21166e 100644 --- a/ash/wm/mru_window_tracker.cc +++ b/ash/wm/mru_window_tracker.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include "ash/public/cpp/shell_window_ids.h" +#include "ash/public/cpp/window_properties.h" #include "ash/shell.h" #include "ash/wm/focus_rules.h" #include "ash/wm/switchable_windows.h" @@ -121,6 +122,31 @@ base::Bind(&IsWindowConsideredActivatable)); } +MruWindowTracker::WindowList MruWindowTracker::BuildWindowForCycleList() const { + MruWindowTracker::WindowList window_list = BuildMruWindowList(); + // Exclude windows: + // - non user positionable windows, such as extension popups. + // - windows being dragged + // - the AppList window, which will hide as soon as cycling starts + // anyway. It doesn't make sense to count it as a "switchable" window, yet + // a lot of code relies on the MRU list returning the app window. If we + // don't manually remove it, the window cycling UI won't crash or misbehave, + // but there will be a flicker as the target window changes. Also exclude + // unselectable windows such as extension popups. + auto window_is_ineligible = [](aura::Window* window) { + wm::WindowState* state = wm::GetWindowState(window); + return !state->IsUserPositionable() || state->is_dragged() || + window->GetRootWindow() + ->GetChildById(kShellWindowId_AppListContainer) + ->Contains(window) || + !window->GetProperty(kShowInOverviewKey); + }; + window_list.erase(std::remove_if(window_list.begin(), window_list.end(), + window_is_ineligible), + window_list.end()); + return window_list; +} + void MruWindowTracker::SetIgnoreActivations(bool ignore) { ignore_window_activations_ = ignore;
diff --git a/ash/wm/mru_window_tracker.h b/ash/wm/mru_window_tracker.h index c90da432..7af4150 100644 --- a/ash/wm/mru_window_tracker.h +++ b/ash/wm/mru_window_tracker.h
@@ -34,6 +34,11 @@ // modal dialog window is present. WindowList BuildWindowListIgnoreModal() const; + // This does the same thing as |BuildMruWindowList()| but with some + // exclusions. This list is used for cycling through by the keyboard via + // alt-tab. + WindowList BuildWindowForCycleList() const; + // Starts or stops ignoring window activations. If no longer ignoring // activations the currently active window is moved to the front of the // MRU window list. Used by WindowCycleList to avoid adding all cycled
diff --git a/ash/wm/window_cycle_controller.cc b/ash/wm/window_cycle_controller.cc index 687fbe26..0803bb1 100644 --- a/ash/wm/window_cycle_controller.cc +++ b/ash/wm/window_cycle_controller.cc
@@ -8,7 +8,6 @@ #include "ash/metrics/task_switch_source.h" #include "ash/metrics/user_metrics_recorder.h" #include "ash/public/cpp/shell_window_ids.h" -#include "ash/public/cpp/window_properties.h" #include "ash/session/session_controller.h" #include "ash/shell.h" #include "ash/shell_port.h" @@ -16,7 +15,6 @@ #include "ash/wm/screen_pinning_controller.h" #include "ash/wm/window_cycle_event_filter.h" #include "ash/wm/window_cycle_list.h" -#include "ash/wm/window_state.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/user_metrics.h" @@ -59,27 +57,7 @@ void WindowCycleController::StartCycling() { WindowCycleList::WindowList window_list = - Shell::Get()->mru_window_tracker()->BuildMruWindowList(); - // Exclude windows: - // - non user positionable windows, such as extension popups. - // - windows being dragged - // - the AppList window, which will hide as soon as cycling starts - // anyway. It doesn't make sense to count it as a "switchable" window, yet - // a lot of code relies on the MRU list returning the app window. If we - // don't manually remove it, the window cycling UI won't crash or misbehave, - // but there will be a flicker as the target window changes. Also exclude - // unselectable windows such as extension popups. - auto window_is_ineligible = [](aura::Window* window) { - wm::WindowState* state = wm::GetWindowState(window); - return !state->IsUserPositionable() || state->is_dragged() || - window->GetRootWindow() - ->GetChildById(kShellWindowId_AppListContainer) - ->Contains(window) || - !window->GetProperty(kShowInOverviewKey); - }; - window_list.erase(std::remove_if(window_list.begin(), window_list.end(), - window_is_ineligible), - window_list.end()); + Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(); active_window_before_window_cycle_ = GetActiveWindow(window_list);
diff --git a/base/process/process_win.cc b/base/process/process_win.cc index 005a68e..c3b59924 100644 --- a/base/process/process_win.cc +++ b/base/process/process_win.cc
@@ -132,19 +132,22 @@ } bool Process::Terminate(int exit_code, bool wait) const { + constexpr DWORD kWaitMs = 60 * 1000; + // exit_code cannot be implemented. DCHECK(IsValid()); bool result = (::TerminateProcess(Handle(), exit_code) != FALSE); if (result) { // The process may not end immediately due to pending I/O - if (wait && ::WaitForSingleObject(Handle(), 60 * 1000) != WAIT_OBJECT_0) + if (wait && ::WaitForSingleObject(Handle(), kWaitMs) != WAIT_OBJECT_0) DPLOG(ERROR) << "Error waiting for process exit"; Exited(exit_code); } else { // The process can't be terminated, perhaps because it has already - // exited. + // exited or is in the process of exiting. A non-zero timeout is necessary + // here for the same reasons as above. DPLOG(ERROR) << "Unable to terminate process"; - if (::WaitForSingleObject(Handle(), 0) == WAIT_OBJECT_0) { + if (::WaitForSingleObject(Handle(), kWaitMs) == WAIT_OBJECT_0) { DWORD actual_exit; Exited(::GetExitCodeProcess(Handle(), &actual_exit) ? actual_exit : exit_code);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java index 4d5e30e..8562af0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
@@ -19,7 +19,11 @@ import org.chromium.chrome.browser.customtabs.CustomTabsConnection; import org.chromium.chrome.browser.datausage.ExternalDataUseObserver; import org.chromium.chrome.browser.externalauth.ExternalAuthUtils; +import org.chromium.chrome.browser.feedback.AsyncFeedbackSource; +import org.chromium.chrome.browser.feedback.FeedbackCollector; import org.chromium.chrome.browser.feedback.FeedbackReporter; +import org.chromium.chrome.browser.feedback.FeedbackSource; +import org.chromium.chrome.browser.feedback.FeedbackSourceProvider; import org.chromium.chrome.browser.gsa.GSAHelper; import org.chromium.chrome.browser.help.HelpAndFeedback; import org.chromium.chrome.browser.historyreport.AppIndexingReporter; @@ -331,4 +335,12 @@ public PartnerBrowserCustomizations.Provider getCustomizationProvider() { return new PartnerBrowserCustomizations.ProviderPackage(); } + + /** + * @return A {@link FeedbackSourceProvider} that can provide additional {@link FeedbackSource}s + * and {@link AsyncFeedbackSource}s to be used by a {@link FeedbackCollector}. + */ + public FeedbackSourceProvider getAdditionalFeedbackSources() { + return new FeedbackSourceProvider() {}; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java index 1eadfce..722ca8b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundService.java
@@ -80,14 +80,14 @@ DownloadNotificationUmaHelper.recordServiceStoppedHistogram( DownloadNotificationUmaHelper.ServiceStopped.STOPPED, true /* withForeground */); - boolean notificationDetachedOrKilled = - (detachNotification && isSdkAtLeast24()) || killNotification; + boolean notificationDetached = detachNotification && isSdkAtLeast24(); + boolean notificationDetachedOrKilled = notificationDetached || killNotification; // Reset pinned notification if notification is properly detached or killed. if (notificationDetachedOrKilled) clearPinnedNotificationId(); // Detach notification from foreground if possible. - if (detachNotification && isSdkAtLeast24()) { + if (notificationDetached) { stopForegroundInternal(ServiceCompat.STOP_FOREGROUND_DETACH); return true; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java index b70ce44..ba6b5fb 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManager.java
@@ -244,24 +244,31 @@ Preconditions.checkNotNull(mBoundService); mIsServiceBound = false; + // For pre-Lollipop phones (API < 21), we need to kill the notification in the pause case + // because otherwise the notification gets stuck in the ongoing state. + boolean needAdjustNotificationPreLollipop = + isPreLollipop() && downloadStatus == DownloadStatus.PAUSE; + // Pause: only try to detach, do not kill notification. // Complete/failed: try to detach, if that doesn't work, kill. // Cancel: don't even try to detach, just kill. + boolean detachNotification = downloadStatus == DownloadStatus.PAUSE || downloadStatus == DownloadStatus.COMPLETE || downloadStatus == DownloadStatus.FAIL; boolean killNotification = downloadStatus == DownloadStatus.CANCEL || downloadStatus == DownloadStatus.COMPLETE - || downloadStatus == DownloadStatus.FAIL; + || downloadStatus == DownloadStatus.FAIL || needAdjustNotificationPreLollipop; boolean notificationHandledProperly = stopAndUnbindServiceInternal(detachNotification, killNotification); mBoundService = null; - // If the download is completed, need to relaunch the notification so it is no longer - // pinned to the foreground service. - if ((downloadStatus == DownloadStatus.COMPLETE || downloadStatus == DownloadStatus.FAIL) - && Build.VERSION.SDK_INT < 24) { + // Relaunch notification so it is no longer pinned to the foreground service when the + // download is completed/failed or if a pre-Lollipop adjustment is needed. + if (((downloadStatus == DownloadStatus.COMPLETE || downloadStatus == DownloadStatus.FAIL) + && Build.VERSION.SDK_INT < 24) + || needAdjustNotificationPreLollipop) { relaunchPinnedNotification(); } @@ -290,4 +297,9 @@ void setBoundService(DownloadForegroundService service) { mBoundService = service; } + + @VisibleForTesting + boolean isPreLollipop() { + return Build.VERSION.SDK_INT < 21; + } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java index 1d469ec..33d8899 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java
@@ -15,6 +15,7 @@ import org.chromium.base.CollectionUtil; import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; +import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.profiles.Profile; import java.util.ArrayList; @@ -74,6 +75,7 @@ // This is the list of all synchronous sources of feedback. Please add new synchronous // entries here. + sources.addAll(AppHooks.get().getAdditionalFeedbackSources().getSynchronousSources()); sources.add(new UrlFeedbackSource(url)); sources.add(new VariationsFeedbackSource(profile)); sources.add(new DataReductionProxyFeedbackSource(profile)); @@ -91,6 +93,7 @@ // This is the list of all asynchronous sources of feedback. Please add new asynchronous // entries here. + sources.addAll(AppHooks.get().getAdditionalFeedbackSources().getAsynchronousSources()); sources.add(new ConnectivityFeedbackSource(profile)); sources.add(new SystemInfoFeedbackSource());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackSourceProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackSourceProvider.java new file mode 100644 index 0000000..b485d9ed --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/feedback/FeedbackSourceProvider.java
@@ -0,0 +1,24 @@ +// 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. + +package org.chromium.chrome.browser.feedback; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * Used for an external component to be able to provide extra feedback sources to the + * FeedbackCollector. In general it is best to add the sources directly to FeedbackCollector, but + * if there are DEPS or repository reasons for not doing that, they can be provided through here. + */ +public interface FeedbackSourceProvider { + // clang-format off + // TODO(crbug.com/781015): Clang isn't formatting this correctly. + /** @return A list of {@link FeedbackSource}s to add to a {@link FeedbackCollector}. */ + default Collection<FeedbackSource> getSynchronousSources() { return new ArrayList<>(); } + + /** @return A list of {@link AsyncFeedbackSource}s to add to a {@link FeedbackCollector}. */ + default Collection<AsyncFeedbackSource> getAsynchronousSources() { return new ArrayList<>(); } + // clang-format on +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteController.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteController.java index dcaacd5..0ea8cec 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteController.java
@@ -147,10 +147,11 @@ * @param profile The profile to use for starting the AutocompleteController. * @param omniboxText The text displayed in the omnibox. * @param url The url of the currently loaded web page. + * @param url The title of the currently loaded web page. * @param focusedFromFakebox Whether the user entered the omnibox by tapping the fakebox on the * native NTP. This should be false on all other pages. */ - public void startZeroSuggest(Profile profile, String omniboxText, String url, + public void startZeroSuggest(Profile profile, String omniboxText, String url, String title, boolean focusedFromFakebox) { if (profile == null || TextUtils.isEmpty(url)) return; @@ -162,8 +163,8 @@ mNativeAutocompleteControllerAndroid = nativeInit(profile); if (mNativeAutocompleteControllerAndroid != 0) { if (mUseCachedZeroSuggestResults) mWaitingForSuggestionsToCache = true; - nativeOnOmniboxFocused( - mNativeAutocompleteControllerAndroid, omniboxText, url, focusedFromFakebox); + nativeOnOmniboxFocused(mNativeAutocompleteControllerAndroid, omniboxText, url, title, + focusedFromFakebox); } } @@ -356,7 +357,7 @@ boolean focusedFromFakebox, long elapsedTimeSinceModified, int completedLength, WebContents webContents); private native void nativeOnOmniboxFocused(long nativeAutocompleteControllerAndroid, - String omniboxText, String currentUrl, boolean focusedFromFakebox); + String omniboxText, String currentUrl, String currentTitle, boolean focusedFromFakebox); private native void nativeDeleteSuggestion(long nativeAutocompleteControllerAndroid, int selectedIndex); private native String nativeUpdateMatchDestinationURLWithQueryFormulationTime(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index cb7f7c42..70216777 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -1128,7 +1128,7 @@ if (mNativeInitialized && mUrlHasFocus && mToolbarDataProvider.hasTab()) { mAutocomplete.startZeroSuggest(mToolbarDataProvider.getProfile(), mUrlBar.getTextWithAutocomplete(), mToolbarDataProvider.getCurrentUrl(), - mUrlFocusedFromFakebox); + getCurrentTab().getTitle(), mUrlFocusedFromFakebox); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/AndroidVSyncHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/AndroidVSyncHelper.java index a28b975..3470263b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/AndroidVSyncHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/AndroidVSyncHelper.java
@@ -4,8 +4,11 @@ package org.chromium.chrome.browser.vr_shell; +import android.content.Context; import android.view.Choreographer; +import android.view.WindowManager; +import org.chromium.base.ContextUtils; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; @@ -43,5 +46,13 @@ Choreographer.getInstance().removeFrameCallback(mCallback); } + @CalledByNative + private float getRefreshRate() { + Context context = ContextUtils.getApplicationContext(); + WindowManager windowManager = + (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + return windowManager.getDefaultDisplay().getRefreshRate(); + } + private native void nativeOnVSync(long nativeAndroidVSyncHelper, long frameTimeNanos); }
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni index 97ce81fe..fccb374c 100644 --- a/chrome/android/java_sources.gni +++ b/chrome/android/java_sources.gni
@@ -415,6 +415,7 @@ "java/src/org/chromium/chrome/browser/feedback/FeedbackCollector.java", "java/src/org/chromium/chrome/browser/feedback/FeedbackReporter.java", "java/src/org/chromium/chrome/browser/feedback/FeedbackSource.java", + "java/src/org/chromium/chrome/browser/feedback/FeedbackSourceProvider.java", "java/src/org/chromium/chrome/browser/feedback/HistogramFeedbackSource.java", "java/src/org/chromium/chrome/browser/feedback/IMEFeedbackSource.java", "java/src/org/chromium/chrome/browser/feedback/LowEndDeviceFeedbackSource.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManagerTest.java index 880f24d..f3dbf6c 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadForegroundServiceManagerTest.java
@@ -211,7 +211,9 @@ mDownloadServiceManager.updateDownloadStatus( mContext, DownloadStatus.PAUSE, FAKE_DOWNLOAD_1, mNotification); assertFalse(mDownloadServiceManager.mIsServiceBound); - assertFalse(mDownloadServiceManager.mIsNotificationKilled); + + assertEquals(mDownloadServiceManager.isPreLollipop(), + mDownloadServiceManager.mIsNotificationKilled); assertTrue(mDownloadServiceManager.mIsNotificationDetached); // Service restarts and then is cancelled, so notification is killed.
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index d29bf1f..d6802fe2 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -1140,10 +1140,20 @@ </if> <!-- Framebust / Blocked Redirection intervention message --> + <message name="IDS_REDIRECT_BLOCKED_MESSAGE" desc="The message stating that a redirect (noun) was blocked on this page. This will be followed on a separate line with the address the user was being redirected to."> + Chromium stopped this site from taking you to + </message> <if expr="is_android"> - <!-- TODO(https://crbug.com/754754) only implemented in Android for now. --> - <message name="IDS_REDIRECT_BLOCKED_MESSAGE" desc="The message stating that a redirect (noun) was blocked on this page. This will be followed on a separate line with the address the user was being redirected to."> - Chromium stopped this site from taking you to + <message name="IDS_REDIRECT_BLOCKED_SHORT_MESSAGE" desc="The short message stating that a redirect (noun) was blocked on this page."> + Redirect blocked. + </message> + </if> + <if expr="not is_android"> + <message name="IDS_REDIRECT_BLOCKED_TITLE" desc="The short message stating that a redirect (noun) was blocked on this page. Same as IDS_REDIRECT_BLOCKED_SHORT_MESSAGE but without the period."> + Redirect blocked + </message> + <message name="IDS_REDIRECT_BLOCKED_TOOLTIP" desc="Tooltip text that appears when the user hovers over the "Redirect blocked" icon in the address bar. It means that a redirect (noun) was blocked by Chrome on this page."> + Redirect blocked on this page. </message> </if>
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index 5e18bdd..ee79ac8 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -1157,10 +1157,20 @@ </if> <!-- Framebust / Blocked Redirection intervention message --> + <message name="IDS_REDIRECT_BLOCKED_MESSAGE" desc="The message stating that a redirect (noun) was blocked on this page. This will be followed on a separate line with the address the user was being redirected to."> + Chrome stopped this site from taking you to + </message> <if expr="is_android"> - <!-- TODO(https://crbug.com/754754) only implemented in Android for now. --> - <message name="IDS_REDIRECT_BLOCKED_MESSAGE" desc="The message stating that a redirect (noun) was blocked on this page. This will be followed on a separate line with the address the user was being redirected to."> - Chrome stopped this site from taking you to + <message name="IDS_REDIRECT_BLOCKED_SHORT_MESSAGE" desc="The short message stating that a redirect (noun) was blocked on this page."> + Redirect blocked. + </message> + </if> + <if expr="not is_android"> + <message name="IDS_REDIRECT_BLOCKED_TITLE" desc="The short message stating that a redirect (noun) was blocked on this page. Same as IDS_REDIRECT_BLOCKED_SHORT_MESSAGE but without the period."> + Redirect blocked + </message> + <message name="IDS_REDIRECT_BLOCKED_TOOLTIP" desc="Tooltip text that appears when the user hovers over the "Redirect blocked" icon in the address bar. It means that a redirect (noun) was blocked by Chrome on this page."> + Redirect blocked on this page. </message> </if>
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index 31d3041..676ef6e 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -16,10 +16,11 @@ "add.icon", "apps.icon", "blocked_badge.icon", - "browser_tools_animated.1x.icon", - "browser_tools_animated.icon", + "blocked_redirect.icon", "browser_tools.1x.icon", "browser_tools.icon", + "browser_tools_animated.1x.icon", + "browser_tools_animated.icon", "browser_tools_error.icon", "browser_tools_update.icon", "caret_down.1x.icon",
diff --git a/chrome/app/vector_icons/blocked_redirect.icon b/chrome/app/vector_icons/blocked_redirect.icon new file mode 100644 index 0000000..2961e701 --- /dev/null +++ b/chrome/app/vector_icons/blocked_redirect.icon
@@ -0,0 +1,31 @@ +// 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. + +MOVE_TO, 32, 12.02f, +LINE_TO, 16, 12, +R_CUBIC_TO, -2.2f, 0, -4, 1.8f, -4, 4, +R_V_LINE_TO, 6, +R_H_LINE_TO, 4, +R_V_LINE_TO, -6, +R_H_LINE_TO, 16, +R_V_LINE_TO, 16, +H_LINE_TO, 16, +R_V_LINE_TO, -6, +R_H_LINE_TO, -4, +R_V_LINE_TO, 6, +R_CUBIC_TO, 0, 2.2f, 1.8f, 4, 4, 4, +R_H_LINE_TO, 16, +R_CUBIC_TO, 2.2f, 0, 4, -1.8f, 4, -4, +V_LINE_TO, 16, +R_CUBIC_TO, 0, -2.2f, -1.8f, -3.98f, -4, -3.98f, +CLOSE, +MOVE_TO, 24, 24, +R_LINE_TO, -6, -6, +R_V_LINE_TO, 4, +R_H_LINE_TO, -6, +R_V_LINE_TO, 4, +R_H_LINE_TO, 6, +R_V_LINE_TO, 4, +CLOSE, +END
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 5cd3211..1f798d4 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -779,6 +779,8 @@ "net/profile_network_context_service.h", "net/profile_network_context_service_factory.cc", "net/profile_network_context_service_factory.h", + "net/proxy_config_monitor.cc", + "net/proxy_config_monitor.h", "net/proxy_service_factory.cc", "net/proxy_service_factory.h", "net/quota_policy_channel_id_store.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 7b4d9f0..4ab76d4 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -3137,8 +3137,8 @@ {"omnibox-display-title-for-current-url", flag_descriptions::kOmniboxDisplayTitleForCurrentUrlName, - flag_descriptions::kOmniboxDisplayTitleForCurrentUrlDescription, - kOsDesktop, FEATURE_VALUE_TYPE(omnibox::kDisplayTitleForCurrentUrl)}, + flag_descriptions::kOmniboxDisplayTitleForCurrentUrlDescription, kOsAll, + FEATURE_VALUE_TYPE(omnibox::kDisplayTitleForCurrentUrl)}, {"force-color-profile", flag_descriptions::kForceColorProfileName, flag_descriptions::kForceColorProfileDescription, kOsAll,
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.cc b/chrome/browser/android/omnibox/autocomplete_controller_android.cc index 3ad1b302..7fa03c5 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.cc +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.cc
@@ -180,6 +180,7 @@ const JavaParamRef<jobject>& obj, const JavaParamRef<jstring>& j_omnibox_text, const JavaParamRef<jstring>& j_current_url, + const JavaParamRef<jstring>& j_current_title, jboolean focused_from_fakebox) { if (!autocomplete_controller_) return; @@ -190,6 +191,7 @@ return; base::string16 url = ConvertJavaStringToUTF16(env, j_current_url); + base::string16 current_title = ConvertJavaStringToUTF16(env, j_current_title); const GURL current_url = GURL(url); base::string16 omnibox_text = ConvertJavaStringToUTF16(env, j_omnibox_text); @@ -204,6 +206,7 @@ ClassifyPage(current_url, focused_from_fakebox), ChromeAutocompleteSchemeClassifier(profile_)); input_.set_current_url(current_url); + input_.set_current_title(current_title); input_.set_from_omnibox_focus(true); autocomplete_controller_->Start(input_); }
diff --git a/chrome/browser/android/omnibox/autocomplete_controller_android.h b/chrome/browser/android/omnibox/autocomplete_controller_android.h index a879f1f..e604b837 100644 --- a/chrome/browser/android/omnibox/autocomplete_controller_android.h +++ b/chrome/browser/android/omnibox/autocomplete_controller_android.h
@@ -53,6 +53,7 @@ const base::android::JavaParamRef<jobject>& obj, const base::android::JavaParamRef<jstring>& j_omnibox_text, const base::android::JavaParamRef<jstring>& j_current_url, + const base::android::JavaParamRef<jstring>& j_current_title, jboolean focused_from_fakebox); void Stop(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj,
diff --git a/chrome/browser/android/vr_shell/android_vsync_helper.cc b/chrome/browser/android/vr_shell/android_vsync_helper.cc index 277af265..0587d3d 100644 --- a/chrome/browser/android/vr_shell/android_vsync_helper.cc +++ b/chrome/browser/android/vr_shell/android_vsync_helper.cc
@@ -6,6 +6,7 @@ #include "base/android/jni_android.h" #include "base/callback_helpers.h" +#include "base/logging.h" #include "jni/AndroidVSyncHelper_jni.h" using base::android::AttachCurrentThread; @@ -17,6 +18,9 @@ JNIEnv* env = AttachCurrentThread(); j_object_.Reset( Java_AndroidVSyncHelper_create(env, reinterpret_cast<jlong>(this))); + float refresh_rate = Java_AndroidVSyncHelper_getRefreshRate(env, j_object_); + display_vsync_interval_ = base::TimeDelta::FromSecondsD(1.0 / refresh_rate); + DVLOG(1) << "display_vsync_interval_=" << display_vsync_interval_; } AndroidVSyncHelper::~AndroidVSyncHelper() {
diff --git a/chrome/browser/android/vr_shell/android_vsync_helper.h b/chrome/browser/android/vr_shell/android_vsync_helper.h index 4c04df9..a12246b 100644 --- a/chrome/browser/android/vr_shell/android_vsync_helper.h +++ b/chrome/browser/android/vr_shell/android_vsync_helper.h
@@ -24,11 +24,18 @@ void RequestVSync(const base::Callback<void(base::TimeTicks)>& callback); void CancelVSyncRequest(); + + // The last interval will be a multiple of the actual refresh interval, use + // with care. base::TimeDelta LastVSyncInterval() { return last_interval_; } + // Nominal display VSync interval from Java Display.getRefreshRate() + base::TimeDelta DisplayVSyncInterval() { return display_vsync_interval_; } + private: base::TimeTicks last_vsync_; base::TimeDelta last_interval_; + base::TimeDelta display_vsync_interval_; base::Callback<void(base::TimeTicks)> callback_; base::android::ScopedJavaGlobalRef<jobject> j_object_;
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.cc b/chrome/browser/android/vr_shell/vr_shell_gl.cc index e1c73fc..86d5647 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.cc +++ b/chrome/browser/android/vr_shell/vr_shell_gl.cc
@@ -29,6 +29,7 @@ #include "chrome/browser/vr/model/camera_model.h" #include "chrome/browser/vr/model/model.h" #include "chrome/browser/vr/pose_util.h" +#include "chrome/browser/vr/sliding_average.h" #include "chrome/browser/vr/ui.h" #include "chrome/browser/vr/ui_element_renderer.h" #include "chrome/browser/vr/ui_scene.h" @@ -227,8 +228,9 @@ binding_(this), browser_(browser_interface), fps_meter_(new vr::FPSMeter()), - webvr_js_time_(new vr::SlidingAverage(kWebVRSlidingAverageSize)), - webvr_render_time_(new vr::SlidingAverage(kWebVRSlidingAverageSize)), + webvr_js_time_(new vr::SlidingTimeDeltaAverage(kWebVRSlidingAverageSize)), + webvr_render_time_( + new vr::SlidingTimeDeltaAverage(kWebVRSlidingAverageSize)), weak_ptr_factory_(this) { GvrInit(gvr_api); } @@ -1160,12 +1162,8 @@ webvr_time_pose_[frame_index % kPoseRingBufferSize]; base::TimeTicks js_submit_time = webvr_time_js_submit_[frame_index % kPoseRingBufferSize]; - int64_t pose_to_js_submit_us = - (js_submit_time - pose_time).InMicroseconds(); - webvr_js_time_->AddSample(pose_to_js_submit_us); - int64_t js_submit_to_gvr_submit_us = - (now - js_submit_time).InMicroseconds(); - webvr_render_time_->AddSample(js_submit_to_gvr_submit_us); + webvr_js_time_->AddSample(js_submit_time - pose_time); + webvr_render_time_->AddSample(now - js_submit_time); } // After saving the timestamp, fps will be available via GetFPS(). @@ -1364,22 +1362,22 @@ } } -int64_t VrShellGl::GetPredictedFrameTimeNanos() { - int64_t frame_time_micros = - vsync_helper_.LastVSyncInterval().InMicroseconds(); +base::TimeDelta VrShellGl::GetPredictedFrameTime() { + base::TimeDelta frame_interval = vsync_helper_.DisplayVSyncInterval(); // If we aim to submit at vsync, that frame will start scanning out // one vsync later. Add a half frame to split the difference between // left and right eye. - int64_t js_micros = webvr_js_time_->GetAverageOrDefault(frame_time_micros); - int64_t render_micros = - webvr_render_time_->GetAverageOrDefault(frame_time_micros); - int64_t overhead_micros = frame_time_micros * 3 / 2; - int64_t expected_frame_micros = js_micros + render_micros + overhead_micros; + base::TimeDelta js_time = webvr_js_time_->GetAverageOrDefault(frame_interval); + base::TimeDelta render_time = + webvr_render_time_->GetAverageOrDefault(frame_interval); + base::TimeDelta overhead_time = frame_interval * 3 / 2; + base::TimeDelta expected_frame_time = js_time + render_time + overhead_time; TRACE_COUNTER2("gpu", "WebVR frame time (ms)", "javascript", - js_micros / 1000.0, "rendering", render_micros / 1000.0); + js_time.InMilliseconds(), "rendering", + render_time.InMilliseconds()); TRACE_COUNTER1("gpu", "WebVR pose prediction (ms)", - expected_frame_micros / 1000.0); - return expected_frame_micros * 1000; + expected_frame_time.InMilliseconds()); + return expected_frame_time; } void VrShellGl::SendVSync(base::TimeTicks time, GetVSyncCallback callback) { @@ -1387,7 +1385,7 @@ TRACE_EVENT1("input", "VrShellGl::SendVSync", "frame", frame_index); - int64_t prediction_nanos = GetPredictedFrameTimeNanos(); + int64_t prediction_nanos = GetPredictedFrameTime().InMicroseconds() * 1000; gfx::Transform head_mat; device::mojom::VRPosePtr pose =
diff --git a/chrome/browser/android/vr_shell/vr_shell_gl.h b/chrome/browser/android/vr_shell/vr_shell_gl.h index 827bde0..8896d79 100644 --- a/chrome/browser/android/vr_shell/vr_shell_gl.h +++ b/chrome/browser/android/vr_shell/vr_shell_gl.h
@@ -51,7 +51,7 @@ namespace vr { class BrowserUiInterface; class FPSMeter; -class SlidingAverage; +class SlidingTimeDeltaAverage; class Ui; } // namespace vr @@ -155,7 +155,7 @@ void OnWebVrTimeoutImminent(); void OnWebVrFrameTimedOut(); - int64_t GetPredictedFrameTimeNanos(); + base::TimeDelta GetPredictedFrameTime(); void OnVSync(base::TimeTicks frame_time); @@ -255,8 +255,8 @@ std::unique_ptr<vr::FPSMeter> fps_meter_; - std::unique_ptr<vr::SlidingAverage> webvr_js_time_; - std::unique_ptr<vr::SlidingAverage> webvr_render_time_; + std::unique_ptr<vr::SlidingTimeDeltaAverage> webvr_js_time_; + std::unique_ptr<vr::SlidingTimeDeltaAverage> webvr_render_time_; gfx::Point3F pointer_start_;
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.cc b/chrome/browser/autofill/android/personal_data_manager_android.cc index 33386a9e..c188c6ef 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.cc +++ b/chrome/browser/autofill/android/personal_data_manager_android.cc
@@ -314,7 +314,6 @@ : weak_java_obj_(env, obj), personal_data_manager_(PersonalDataManagerFactory::GetForProfile( ProfileManager::GetActiveUserProfile())), - address_normalizer_(AddressNormalizerFactory::GetInstance()), subkey_requester_(base::MakeUnique<ChromeMetadataSource>( I18N_ADDRESS_VALIDATION_DATA_URL, g_browser_process->system_request_context()), @@ -695,8 +694,8 @@ JNIEnv* env, const base::android::JavaParamRef<jobject>& unused_obj, const base::android::JavaParamRef<jstring>& jregion_code) { - address_normalizer_->LoadRulesForRegion( - ConvertJavaStringToUTF8(env, jregion_code)); + AddressNormalizer* normalizer = AddressNormalizerFactory::GetInstance(); + normalizer->LoadRulesForRegion(ConvertJavaStringToUTF8(env, jregion_code)); } void PersonalDataManagerAndroid::LoadRulesForSubKeys( @@ -717,7 +716,8 @@ PopulateNativeProfileFromJava(jprofile, env, &profile); // Start the normalization. - address_normalizer_->NormalizeAddressAsync( + AddressNormalizer* normalizer = AddressNormalizerFactory::GetInstance(); + normalizer->NormalizeAddressAsync( profile, jtimeout_seconds, base::BindOnce(&OnAddressNormalized, ScopedJavaGlobalRef<jobject>(jdelegate)));
diff --git a/chrome/browser/autofill/android/personal_data_manager_android.h b/chrome/browser/autofill/android/personal_data_manager_android.h index 86224af..e13609a 100644 --- a/chrome/browser/autofill/android/personal_data_manager_android.h +++ b/chrome/browser/autofill/android/personal_data_manager_android.h
@@ -14,12 +14,9 @@ #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/personal_data_manager_observer.h" #include "components/autofill/core/browser/subkey_requester.h" -#include "third_party/libaddressinput/chromium/chrome_address_validator.h" namespace autofill { -class AddressNormalizer; - // Android wrapper of the PersonalDataManager which provides access from the // Java layer. Note that on Android, there's only a single profile, and // therefore a single instance of this wrapper. @@ -380,9 +377,6 @@ // Pointer to the PersonalDataManager for the main profile. PersonalDataManager* personal_data_manager_; - // The address validator used to normalize addresses. - AddressNormalizer* address_normalizer_; - // Used for subkey request. SubKeyRequester subkey_requester_;
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index f4e6950..8437b48 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1973,12 +1973,22 @@ return prefs && prefs->GetBoolean(prefs::kDataSaverEnabled); } -std::unique_ptr<net::HttpRequestHeaders> -ChromeContentBrowserClient::GetAdditionalNavigationRequestHeaders( - content::BrowserContext* context, - const GURL& url) const { - return client_hints::GetAdditionalNavigationRequestClientHintsHeaders(context, - url); +void ChromeContentBrowserClient::NavigationRequestStarted( + int frame_tree_node_id, + const GURL& url, + std::unique_ptr<net::HttpRequestHeaders>* extra_headers, + int* extra_load_flags) { + WebContents* web_contents = + WebContents::FromFrameTreeNodeId(frame_tree_node_id); + *extra_headers = + client_hints::GetAdditionalNavigationRequestClientHintsHeaders( + web_contents->GetBrowserContext(), url); + prerender::PrerenderContents* prerender_contents = + prerender::PrerenderContents::FromWebContents(web_contents); + if (prerender_contents) { + if (prerender_contents->prerender_mode() == prerender::PREFETCH_ONLY) + *extra_load_flags = net::LOAD_PREFETCH; + } } bool ChromeContentBrowserClient::AllowAppCache( @@ -3709,6 +3719,22 @@ #endif } +bool ChromeContentBrowserClient::AllowRenderingMhtmlOverHttp( + content::NavigationUIData* navigation_ui_data) const { +#if BUILDFLAG(ENABLE_OFFLINE_PAGES) + // It is OK to load the saved offline copy, in MHTML format. + ChromeNavigationUIData* chrome_navigation_ui_data = + static_cast<ChromeNavigationUIData*>(navigation_ui_data); + if (!chrome_navigation_ui_data) + return false; + offline_pages::OfflinePageNavigationUIData* offline_page_data = + chrome_navigation_ui_data->GetOfflinePageNavigationUIData(); + return offline_page_data && offline_page_data->is_offline_page(); +#else + return false; +#endif +} + // Static; handles rewriting Web UI URLs. bool ChromeContentBrowserClient::HandleWebUI( GURL* url,
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index 19b64a9..03606bc 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -160,9 +160,11 @@ std::string GetAcceptLangs(content::BrowserContext* context) override; const gfx::ImageSkia* GetDefaultFavicon() override; bool IsDataSaverEnabled(content::BrowserContext* context) override; - std::unique_ptr<net::HttpRequestHeaders> - GetAdditionalNavigationRequestHeaders(content::BrowserContext* context, - const GURL& url) const override; + void NavigationRequestStarted( + int frame_tree_node_id, + const GURL& url, + std::unique_ptr<net::HttpRequestHeaders>* extra_headers, + int* extra_load_flags) override; bool AllowAppCache(const GURL& manifest_url, const GURL& first_party, content::ResourceContext* context) override; @@ -385,6 +387,8 @@ content::RenderFrameHost* frame_host, const GURL& frame_url, NonNetworkURLLoaderFactoryMap* factories) override; + bool AllowRenderingMhtmlOverHttp( + content::NavigationUIData* navigation_ui_data) const override; protected: static bool HandleWebUI(GURL* url, content::BrowserContext* browser_context);
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc index 8bd9af9..156f504 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.cc
@@ -105,10 +105,13 @@ disks::DiskMountManager::GetInstance()->RemoveObserver(this); } -void KioskExternalUpdater::OnDiskEvent( +void KioskExternalUpdater::OnAutoMountableDiskEvent( disks::DiskMountManager::DiskEvent event, - const disks::DiskMountManager::Disk* disk) { -} + const disks::DiskMountManager::Disk& disk) {} + +void KioskExternalUpdater::OnBootDeviceDiskEvent( + disks::DiskMountManager::DiskEvent event, + const disks::DiskMountManager::Disk& disk) {} void KioskExternalUpdater::OnDeviceEvent( disks::DiskMountManager::DeviceEvent event,
diff --git a/chrome/browser/chromeos/app_mode/kiosk_external_updater.h b/chrome/browser/chromeos/app_mode/kiosk_external_updater.h index e52a6ec..22c72649 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_external_updater.h +++ b/chrome/browser/chromeos/app_mode/kiosk_external_updater.h
@@ -57,8 +57,12 @@ }; // disks::DiskMountManager::Observer overrides. - void OnDiskEvent(disks::DiskMountManager::DiskEvent event, - const disks::DiskMountManager::Disk* disk) override; + void OnAutoMountableDiskEvent( + disks::DiskMountManager::DiskEvent event, + const disks::DiskMountManager::Disk& disk) override; + void OnBootDeviceDiskEvent( + disks::DiskMountManager::DiskEvent event, + const disks::DiskMountManager::Disk& disk) override; void OnDeviceEvent(disks::DiskMountManager::DeviceEvent event, const std::string& device_path) override; void OnMountEvent(
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc index a343963..eb4b2a0 100644 --- a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc +++ b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
@@ -35,6 +35,7 @@ #include "components/arc/arc_service_manager.h" #include "components/arc/arc_session_runner.h" #include "components/arc/arc_util.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_arc_session.h" #include "components/prefs/pref_member.h" #include "components/prefs/pref_service.h" @@ -212,6 +213,7 @@ ArcServiceManager::Get()->arc_bridge_service(); ASSERT_TRUE(arc_bridge_service); arc_bridge_service->auth()->SetInstance(&auth_instance); + WaitForInstanceReady(arc_bridge_service->auth()); base::RunLoop run_loop; auth_instance.RequestAccountInfo(run_loop.QuitClosure()); @@ -224,6 +226,8 @@ auth_instance.account_info()->account_type); EXPECT_FALSE(auth_instance.account_info()->enrollment_token); EXPECT_FALSE(auth_instance.account_info()->is_managed); + + arc_bridge_service->auth()->SetInstance(nullptr, 0); } } // namespace arc
diff --git a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc index 063e216..d767b690 100644 --- a/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/bluetooth/arc_bluetooth_bridge_unittest.cc
@@ -15,6 +15,7 @@ #include "components/arc/arc_bridge_service.h" #include "components/arc/bluetooth/bluetooth_type_converters.h" #include "components/arc/common/bluetooth.mojom.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_bluetooth_instance.h" #include "device/bluetooth/dbus/bluez_dbus_manager.h" #include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h" @@ -90,12 +91,13 @@ std::make_unique<bluez::FakeBluetoothGattDescriptorClient>()); arc_bridge_service_ = std::make_unique<ArcBridgeService>(); - fake_bluetooth_instance_ = std::make_unique<FakeBluetoothInstance>(); - arc_bridge_service_->bluetooth()->SetInstance( - fake_bluetooth_instance_.get(), 2); // TODO(hidehiko): Use Singleton instance tied to BrowserContext. arc_bluetooth_bridge_ = std::make_unique<ArcBluetoothBridge>( nullptr, arc_bridge_service_.get()); + fake_bluetooth_instance_ = std::make_unique<FakeBluetoothInstance>(); + arc_bridge_service_->bluetooth()->SetInstance( + fake_bluetooth_instance_.get(), 2); + WaitForInstanceReady(arc_bridge_service_->bluetooth()); device::BluetoothAdapterFactory::GetAdapter(base::Bind( &ArcBluetoothBridgeTest::OnAdapterInitialized, base::Unretained(this))); @@ -103,6 +105,12 @@ get_adapter_run_loop_.Run(); } + void TearDown() override { + arc_bridge_service_->bluetooth()->SetInstance(nullptr, 0); + arc_bluetooth_bridge_.reset(); + arc_bridge_service_.reset(); + } + // Helper methods for multi advertisement tests. int32_t ReserveAdvertisementHandle() { constexpr int kSentinelHandle = -2;
diff --git a/chrome/browser/chromeos/arc/enterprise/arc_cert_store_bridge_browsertest.cc b/chrome/browser/chromeos/arc/enterprise/arc_cert_store_bridge_browsertest.cc index c53a4118..7c0f966e 100644 --- a/chrome/browser/chromeos/arc/enterprise/arc_cert_store_bridge_browsertest.cc +++ b/chrome/browser/chromeos/arc/enterprise/arc_cert_store_bridge_browsertest.cc
@@ -31,6 +31,7 @@ #include "components/arc/arc_service_manager.h" #include "components/arc/arc_util.h" #include "components/arc/common/cert_store.mojom.h" +#include "components/arc/test/connection_holder_util.h" #include "components/policy/policy_constants.h" #include "content/public/browser/browser_thread.h" #include "crypto/scoped_test_system_nss_key_slot.h" @@ -134,11 +135,12 @@ instance_ = std::make_unique<FakeArcCertStoreInstance>(); ASSERT_TRUE(arc_bridge()); arc_bridge()->cert_store()->SetInstance(instance_.get()); + WaitForInstanceReady(arc_bridge()->cert_store()); } void TearDownOnMainThread() override { ASSERT_TRUE(arc_bridge()); - arc_bridge()->cert_store()->SetInstance(nullptr); + arc_bridge()->cert_store()->SetInstance(nullptr, 0); instance_.reset(); // Since ArcServiceLauncher is (re-)set up with profile() in
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc index edaa17b..6969b57 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_async_file_util_unittest.cc
@@ -17,6 +17,7 @@ #include "chrome/test/base/testing_profile.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_service_manager.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_file_system_instance.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -56,10 +57,17 @@ profile_.get(), &CreateArcFileSystemOperationRunnerForTesting); arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( &fake_file_system_); + WaitForInstanceReady( + arc_service_manager_->arc_bridge_service()->file_system()); async_file_util_ = std::make_unique<ArcContentFileSystemAsyncFileUtil>(); } + void TearDown() override { + arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( + nullptr, 0); + } + protected: storage::FileSystemURL ExternalFileURLToFileSystemURL(const GURL& url) { base::FilePath mount_point_virtual_path =
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc index 9d76ff1..940e1f3 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_content_file_system_file_stream_reader_unittest.cc
@@ -15,6 +15,7 @@ #include "chrome/test/base/testing_profile.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_service_manager.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_file_system_instance.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -83,6 +84,13 @@ profile_.get(), &CreateFileSystemOperationRunnerForTesting); arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( &fake_file_system_); + WaitForInstanceReady( + arc_service_manager_->arc_bridge_service()->file_system()); + } + + void TearDown() override { + arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( + nullptr, 0); } private:
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc index 53a251b..3448826 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_documents_provider_root_unittest.cc
@@ -17,6 +17,7 @@ #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_service_manager.h" #include "components/arc/common/file_system.mojom.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_file_system_instance.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -130,9 +131,10 @@ profile_.get(), &CreateFileSystemOperationRunnerForTesting); arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( &fake_file_system_); + WaitForInstanceReady( + arc_service_manager_->arc_bridge_service()->file_system()); // Run the message loop until FileSystemInstance::Init() is called. - base::RunLoop().RunUntilIdle(); ASSERT_TRUE(fake_file_system_.InitCalled()); root_ = std::make_unique<ArcDocumentsProviderRoot>( @@ -142,6 +144,9 @@ void TearDown() override { root_.reset(); + arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( + nullptr); + // Run all pending tasks before destroying testing profile. base::RunLoop().RunUntilIdle(); }
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc index 23a513e..b2050aa 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_bridge_unittest.cc
@@ -19,6 +19,7 @@ #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/fake_virtual_file_provider_client.h" #include "components/arc/arc_bridge_service.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_file_system_instance.h" #include "components/drive/chromeos/fake_file_system.h" #include "components/drive/service/fake_drive_service.h" @@ -56,9 +57,10 @@ Profile* profile = profile_manager_->CreateTestingProfile(kTestingProfileName); - arc_bridge_service_.file_system()->SetInstance(&fake_file_system_); arc_file_system_bridge_ = std::make_unique<ArcFileSystemBridge>(profile, &arc_bridge_service_); + arc_bridge_service_.file_system()->SetInstance(&fake_file_system_); + WaitForInstanceReady(arc_bridge_service_.file_system()); // Create the drive integration service for the profile. integration_service_factory_callback_ = @@ -72,6 +74,7 @@ void TearDown() override { integration_service_factory_scope_.reset(); + arc_bridge_service_.file_system()->SetInstance(nullptr, 0); arc_file_system_bridge_.reset(); profile_manager_.reset(); chromeos::DBusThreadManager::Shutdown();
diff --git a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_unittest.cc b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_unittest.cc index c64e0a7..ae0db71 100644 --- a/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_unittest.cc +++ b/chrome/browser/chromeos/arc/fileapi/arc_file_system_operation_runner_unittest.cc
@@ -14,6 +14,7 @@ #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_service_manager.h" #include "components/arc/common/file_system.mojom.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_file_system_instance.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -48,13 +49,16 @@ profile_.get(), arc_service_manager_->arc_bridge_service()); arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( &file_system_instance_); + WaitForInstanceReady( + arc_service_manager_->arc_bridge_service()->file_system()); // Run the message loop until FileSystemInstance::Init() is called. - base::RunLoop().RunUntilIdle(); ASSERT_TRUE(file_system_instance_.InitCalled()); } void TearDown() override { + arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( + nullptr, 0); // Explicitly calls Shutdown() to detach from services. if (runner_) runner_->Shutdown();
diff --git a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc index e13db3c0..7e3d875 100644 --- a/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc +++ b/chrome/browser/chromeos/arc/intent_helper/arc_settings_service_browsertest.cc
@@ -28,6 +28,7 @@ #include "components/arc/arc_prefs.h" #include "components/arc/arc_service_manager.h" #include "components/arc/arc_util.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_intent_helper_instance.h" #include "components/policy/core/browser/browser_policy_connector.h" #include "components/policy/core/common/mock_configuration_policy_provider.h" @@ -231,17 +232,19 @@ EXPECT_CALL(provider_, IsInitializationComplete(_)) .WillRepeatedly(Return(true)); policy::BrowserPolicyConnector::SetPolicyProviderForTesting(&provider_); - fake_intent_helper_instance_.reset(new FakeIntentHelperInstance()); } void SetUpOnMainThread() override { SetupNetworkEnvironment(); RunUntilIdle(); + fake_intent_helper_instance_ = std::make_unique<FakeIntentHelperInstance>(); ArcServiceManager::Get() ->arc_bridge_service() ->intent_helper() ->SetInstance(fake_intent_helper_instance_.get()); + WaitForInstanceReady( + ArcServiceManager::Get()->arc_bridge_service()->intent_helper()); } void TearDownOnMainThread() override { @@ -249,6 +252,7 @@ ->arc_bridge_service() ->intent_helper() ->SetInstance(nullptr); + fake_intent_helper_instance_.reset(); } void UpdatePolicy(const policy::PolicyMap& policy) {
diff --git a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc index 7aa583a..c1d7fe0 100644 --- a/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc +++ b/chrome/browser/chromeos/arc/policy/arc_policy_bridge_unittest.cc
@@ -15,6 +15,7 @@ #include "chrome/test/base/testing_profile_manager.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_prefs.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_policy_instance.h" #include "components/policy/core/common/mock_policy_service.h" #include "components/policy/core/common/policy_map.h" @@ -126,9 +127,6 @@ EXPECT_CALL(policy_service_, AddObserver(policy::POLICY_DOMAIN_CHROME, _)) .Times(1); - policy_instance_ = std::make_unique<FakePolicyInstance>(); - bridge_service_->policy()->SetInstance(policy_instance_.get()); - // Setting up user profile for ReportCompliance() tests. chromeos::FakeChromeUserManager* const fake_user_manager = new chromeos::FakeChromeUserManager(); @@ -148,6 +146,15 @@ policy_bridge_ = std::make_unique<ArcPolicyBridge>( profile_, bridge_service_.get(), &policy_service_); policy_bridge_->OverrideIsManagedForTesting(true); + + policy_instance_ = std::make_unique<FakePolicyInstance>(); + bridge_service_->policy()->SetInstance(policy_instance_.get()); + WaitForInstanceReady(bridge_service_->policy()); + } + + void TearDown() override { + bridge_service_->policy()->SetInstance(nullptr, 0); + policy_instance_.reset(); } protected:
diff --git a/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc b/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc index 0215672..12c0962 100644 --- a/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc +++ b/chrome/browser/chromeos/arc/user_session/arc_user_session_service_browsertest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> + #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "chrome/browser/chromeos/arc/user_session/arc_user_session_service.h" @@ -9,6 +11,7 @@ #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_service_manager.h" #include "components/arc/arc_util.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_intent_helper_instance.h" #include "components/session_manager/core/session_manager.h" @@ -49,17 +52,16 @@ arc::SetArcAvailableCommandLineForTesting(command_line); } - void SetUpInProcessBrowserTestFixture() override { - fake_intent_helper_instance_.reset(new FakeIntentHelperInstance()); - } - void SetUpOnMainThread() override { RunUntilIdle(); + fake_intent_helper_instance_ = std::make_unique<FakeIntentHelperInstance>(); ArcServiceManager::Get() ->arc_bridge_service() ->intent_helper() ->SetInstance(fake_intent_helper_instance_.get()); + WaitForInstanceReady( + ArcServiceManager::Get()->arc_bridge_service()->intent_helper()); } void TearDownOnMainThread() override { @@ -67,6 +69,7 @@ ->arc_bridge_service() ->intent_helper() ->SetInstance(nullptr); + fake_intent_helper_instance_.reset(nullptr); } protected:
diff --git a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc index 66d1c9d..55f682e8 100644 --- a/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc +++ b/chrome/browser/chromeos/arc/voice_interaction/arc_voice_interaction_framework_service_unittest.cc
@@ -20,6 +20,7 @@ #include "chromeos/dbus/fake_cras_audio_client.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_util.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_arc_session.h" #include "components/arc/test/fake_voice_interaction_framework_instance.h" #include "components/prefs/pref_service.h" @@ -191,6 +192,7 @@ std::make_unique<FakeVoiceInteractionFrameworkInstance>(); arc_bridge_service_->voice_interaction_framework()->SetInstance( framework_instance_.get()); + WaitForInstanceReady(arc_bridge_service_->voice_interaction_framework()); // Flushing is required for the AttachClient call to get through to the // highligther controller. FlushHighlighterControllerMojo(); @@ -202,6 +204,7 @@ } void TearDown() override { + arc_bridge_service_->voice_interaction_framework()->SetInstance(nullptr); framework_instance_.reset(); framework_service_.reset(); arc_bridge_service_.reset(); @@ -378,6 +381,7 @@ // The client should become attached again. arc_bridge_service()->voice_interaction_framework()->SetInstance( framework_instance()); + WaitForInstanceReady(arc_bridge_service()->voice_interaction_framework()); FlushHighlighterControllerMojo(); EXPECT_TRUE(highlighter_controller()->client_attached());
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc index 648e6c9..ce93bc5 100644 --- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc +++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
@@ -24,6 +24,7 @@ #include "chromeos/cryptohome/system_salt_getter.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_service_manager.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_wallpaper_instance.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/testing_pref_service.h" @@ -95,13 +96,15 @@ chromeos::WallpaperManager::Initialize(); // Arc services - wallpaper_instance_ = std::make_unique<arc::FakeWallpaperInstance>(); arc_service_manager_.set_browser_context(&testing_profile_); - arc_service_manager_.arc_bridge_service()->wallpaper()->SetInstance( - wallpaper_instance_.get()); service_ = arc::ArcWallpaperService::GetForBrowserContext(&testing_profile_); ASSERT_TRUE(service_); + wallpaper_instance_ = std::make_unique<arc::FakeWallpaperInstance>(); + arc_service_manager_.arc_bridge_service()->wallpaper()->SetInstance( + wallpaper_instance_.get()); + WaitForInstanceReady( + arc_service_manager_.arc_bridge_service()->wallpaper()); // Salt std::vector<uint8_t> salt = {0x01, 0x02, 0x03}; @@ -109,6 +112,10 @@ } void TearDown() override { + arc_service_manager_.arc_bridge_service()->wallpaper()->SetInstance( + nullptr); + wallpaper_instance_.reset(); + chromeos::WallpaperManager::Shutdown(); TestingBrowserProcess::GetGlobal()->SetLocalState(nullptr); AshTestBase::TearDown();
diff --git a/chrome/browser/chromeos/file_manager/fake_disk_mount_manager.cc b/chrome/browser/chromeos/file_manager/fake_disk_mount_manager.cc index 664bad8..91f0699 100644 --- a/chrome/browser/chromeos/file_manager/fake_disk_mount_manager.cc +++ b/chrome/browser/chromeos/file_manager/fake_disk_mount_manager.cc
@@ -153,8 +153,10 @@ void FakeDiskMountManager::InvokeDiskEventForTest( chromeos::disks::DiskMountManager::DiskEvent event, const chromeos::disks::DiskMountManager::Disk* disk) { - for (auto& observer : observers_) - observer.OnDiskEvent(event, disk); + for (auto& observer : observers_) { + disk->IsAutoMountable() ? observer.OnAutoMountableDiskEvent(event, *disk) + : observer.OnBootDeviceDiskEvent(event, *disk); + } } } // namespace file_manager
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.cc b/chrome/browser/chromeos/file_manager/volume_manager.cc index b08419d..6f0c1dc 100644 --- a/chrome/browser/chromeos/file_manager/volume_manager.cc +++ b/chrome/browser/chromeos/file_manager/volume_manager.cc
@@ -530,30 +530,30 @@ DoUnmountEvent(chromeos::MOUNT_ERROR_NONE, *Volume::CreateForDrive(profile_)); } -void VolumeManager::OnDiskEvent( +void VolumeManager::OnAutoMountableDiskEvent( chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk* disk) { + const chromeos::disks::DiskMountManager::Disk& disk) { DCHECK_CURRENTLY_ON(content::BrowserThread::UI); // Disregard hidden devices. - if (disk->is_hidden()) + if (disk.is_hidden()) return; switch (event) { case chromeos::disks::DiskMountManager::DISK_ADDED: case chromeos::disks::DiskMountManager::DISK_CHANGED: { - if (disk->device_path().empty()) { - DVLOG(1) << "Empty system path for " << disk->device_path(); + if (disk.device_path().empty()) { + DVLOG(1) << "Empty system path for " << disk.device_path(); return; } bool mounting = false; - if (disk->mount_path().empty() && disk->has_media() && + if (disk.mount_path().empty() && disk.has_media() && !profile_->GetPrefs()->GetBoolean(prefs::kExternalStorageDisabled)) { // TODO(crbug.com/774890): Remove |mount_label| when the issue gets // resolved. Currently we suggest a mount point name, because in case // when disk's name contains '#', content will not load in Files App. - std::string mount_label = disk->device_label(); + std::string mount_label = disk.device_label(); std::replace(mount_label.begin(), mount_label.end(), '#', '_'); // If disk is not mounted yet and it has media and there is no policy @@ -561,7 +561,7 @@ // Initiate disk mount operation. MountPath auto-detects the filesystem // format if the second argument is empty. The third argument (mount // label) is not used in a disk mount operation. - disk_mount_manager_->MountPath(disk->device_path(), std::string(), + disk_mount_manager_->MountPath(disk.device_path(), std::string(), mount_label, chromeos::MOUNT_TYPE_DEVICE, GetExternalStorageAccessMode(profile_)); mounting = true; @@ -569,27 +569,30 @@ // Notify to observers. for (auto& observer : observers_) - observer.OnDiskAdded(*disk, mounting); + observer.OnDiskAdded(disk, mounting); return; } case chromeos::disks::DiskMountManager::DISK_REMOVED: // If the disk is already mounted, unmount it. - if (!disk->mount_path().empty()) { + if (!disk.mount_path().empty()) { disk_mount_manager_->UnmountPath( - disk->mount_path(), - chromeos::UNMOUNT_OPTIONS_LAZY, + disk.mount_path(), chromeos::UNMOUNT_OPTIONS_LAZY, chromeos::disks::DiskMountManager::UnmountPathCallback()); } // Notify to observers. for (auto& observer : observers_) - observer.OnDiskRemoved(*disk); + observer.OnDiskRemoved(disk); return; } NOTREACHED(); } +void VolumeManager::OnBootDeviceDiskEvent( + chromeos::disks::DiskMountManager::DiskEvent event, + const chromeos::disks::DiskMountManager::Disk& disk) {} + void VolumeManager::OnDeviceEvent( chromeos::disks::DiskMountManager::DeviceEvent event, const std::string& device_path) {
diff --git a/chrome/browser/chromeos/file_manager/volume_manager.h b/chrome/browser/chromeos/file_manager/volume_manager.h index cb095dc..d99a2435d 100644 --- a/chrome/browser/chromeos/file_manager/volume_manager.h +++ b/chrome/browser/chromeos/file_manager/volume_manager.h
@@ -287,9 +287,12 @@ void OnFileSystemBeingUnmounted() override; // chromeos::disks::DiskMountManager::Observer overrides. - void OnDiskEvent( + void OnAutoMountableDiskEvent( chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk* disk) override; + const chromeos::disks::DiskMountManager::Disk& disk) override; + void OnBootDeviceDiskEvent( + chromeos::disks::DiskMountManager::DiskEvent event, + const chromeos::disks::DiskMountManager::Disk& disk) override; void OnDeviceEvent(chromeos::disks::DiskMountManager::DeviceEvent event, const std::string& device_path) override; void OnMountEvent(chromeos::disks::DiskMountManager::MountEvent event,
diff --git a/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc b/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc index 0d7f15f..464ee23e 100644 --- a/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc +++ b/chrome/browser/chromeos/file_manager/volume_manager_unittest.cc
@@ -256,8 +256,31 @@ ASSERT_EQ(0U, observer.events().size()); volume_manager()->RemoveObserver(&observer); } +TEST_F(VolumeManagerTest, OnBootDeviceDiskEvent) { + LoggingObserver observer; + volume_manager()->AddObserver(&observer); -TEST_F(VolumeManagerTest, OnDiskEvent_Hidden) { + const chromeos::disks::DiskMountManager::Disk disk( + "device1", "", false, "", "", "", "", "", "", "", "", "", "", + chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, true, false, false, + "", ""); + + volume_manager()->OnBootDeviceDiskEvent( + chromeos::disks::DiskMountManager::DISK_ADDED, disk); + EXPECT_EQ(0U, observer.events().size()); + + volume_manager()->OnBootDeviceDiskEvent( + chromeos::disks::DiskMountManager::DISK_REMOVED, disk); + EXPECT_EQ(0U, observer.events().size()); + + volume_manager()->OnBootDeviceDiskEvent( + chromeos::disks::DiskMountManager::DISK_CHANGED, disk); + EXPECT_EQ(0U, observer.events().size()); + + volume_manager()->RemoveObserver(&observer); +} + +TEST_F(VolumeManagerTest, OnAutoMountableDiskEvent_Hidden) { LoggingObserver observer; volume_manager()->AddObserver(&observer); @@ -267,22 +290,22 @@ chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false, kIsHidden, "", ""); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_ADDED, &kDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_ADDED, kDisk); EXPECT_EQ(0U, observer.events().size()); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_REMOVED, &kDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_REMOVED, kDisk); EXPECT_EQ(0U, observer.events().size()); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_CHANGED, &kDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_CHANGED, kDisk); EXPECT_EQ(0U, observer.events().size()); volume_manager()->RemoveObserver(&observer); } -TEST_F(VolumeManagerTest, OnDiskEvent_Added) { +TEST_F(VolumeManagerTest, OnAutoMountableDiskEvent_Added) { // Enable external storage. profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false); @@ -294,8 +317,8 @@ "", false, "", "", "", "", "", "", "", "", "", "", chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false, false, "", ""); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_ADDED, &kEmptyDevicePathDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_ADDED, kEmptyDevicePathDisk); EXPECT_EQ(0U, observer.events().size()); const bool kHasMedia = true; @@ -303,8 +326,8 @@ "device1", "", false, "", "", "", "", "", "", "", "", "", "", chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, kHasMedia, false, false, false, "", ""); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_ADDED, kMediaDisk); ASSERT_EQ(1U, observer.events().size()); const LoggingObserver::Event& event = observer.events()[0]; EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type); @@ -322,7 +345,7 @@ volume_manager()->RemoveObserver(&observer); } -TEST_F(VolumeManagerTest, OnDiskEvent_AddedNonMounting) { +TEST_F(VolumeManagerTest, OnAutoMountableDiskEvent_AddedNonMounting) { // Enable external storage. profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageDisabled, false); @@ -336,8 +359,8 @@ "device1", "mounted", false, "", "", "", "", "", "", "", "", "", "", chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, kHasMedia, false, false, false, "", ""); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_ADDED, &kMountedMediaDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_ADDED, kMountedMediaDisk); ASSERT_EQ(1U, observer.events().size()); const LoggingObserver::Event& event = observer.events()[0]; EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type); @@ -359,8 +382,8 @@ "device1", "", false, "", "", "", "", "", "", "", "", "", "", chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, kWithoutMedia, false, false, false, "", ""); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_ADDED, &kNoMediaDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_ADDED, kNoMediaDisk); ASSERT_EQ(1U, observer.events().size()); const LoggingObserver::Event& event = observer.events()[0]; EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type); @@ -384,8 +407,8 @@ "device1", "", false, "", "", "", "", "", "", "", "", "", "", chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, kHasMedia, false, false, false, "", ""); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_ADDED, kMediaDisk); ASSERT_EQ(1U, observer.events().size()); const LoggingObserver::Event& event = observer.events()[0]; EXPECT_EQ(LoggingObserver::Event::DISK_ADDED, event.type); @@ -398,7 +421,7 @@ } } -TEST_F(VolumeManagerTest, OnDiskEvent_Removed) { +TEST_F(VolumeManagerTest, OnDiskAutoMountableEvent_Removed) { LoggingObserver observer; volume_manager()->AddObserver(&observer); @@ -406,8 +429,8 @@ "device1", "mount_path", false, "", "", "", "", "", "", "", "", "", "", chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false, false, "", ""); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_REMOVED, &kMountedDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_REMOVED, kMountedDisk); ASSERT_EQ(1U, observer.events().size()); const LoggingObserver::Event& event = observer.events()[0]; @@ -423,7 +446,7 @@ volume_manager()->RemoveObserver(&observer); } -TEST_F(VolumeManagerTest, OnDiskEvent_RemovedNotMounted) { +TEST_F(VolumeManagerTest, OnAutoMountableDiskEvent_RemovedNotMounted) { LoggingObserver observer; volume_manager()->AddObserver(&observer); @@ -431,8 +454,8 @@ "device1", "", false, "", "", "", "", "", "", "", "", "", "", chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, false, false, false, false, "", ""); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_REMOVED, &kNotMountedDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_REMOVED, kNotMountedDisk); ASSERT_EQ(1U, observer.events().size()); const LoggingObserver::Event& event = observer.events()[0]; @@ -444,7 +467,7 @@ volume_manager()->RemoveObserver(&observer); } -TEST_F(VolumeManagerTest, OnDiskEvent_Changed) { +TEST_F(VolumeManagerTest, OnAutoMountableDiskEvent_Changed) { // Changed event should cause mounting (if possible). LoggingObserver observer; volume_manager()->AddObserver(&observer); @@ -453,8 +476,8 @@ "device1", "", false, "", "", "", "", "", "", "", "", "", "", chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, true, false, false, false, "", ""); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_CHANGED, &kDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_CHANGED, kDisk); EXPECT_EQ(1U, observer.events().size()); EXPECT_EQ(1U, disk_mount_manager_->mount_requests().size()); @@ -466,7 +489,7 @@ volume_manager()->RemoveObserver(&observer); } -TEST_F(VolumeManagerTest, OnDiskEvent_ChangedInReadonly) { +TEST_F(VolumeManagerTest, OnAutoMountableDiskEvent_ChangedInReadonly) { profile()->GetPrefs()->SetBoolean(prefs::kExternalStorageReadOnly, true); // Changed event should cause mounting (if possible). @@ -477,8 +500,8 @@ "device1", "", false, "", "", "", "", "", "", "", "", "", "", chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, true, false, false, false, "", ""); - volume_manager()->OnDiskEvent(chromeos::disks::DiskMountManager::DISK_CHANGED, - &kDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_CHANGED, kDisk); EXPECT_EQ(1U, observer.events().size()); EXPECT_EQ(1U, disk_mount_manager_->mount_requests().size()); @@ -783,10 +806,10 @@ "device1", "", false, "", "", "", "", "", "", "", "", "", "", chromeos::DEVICE_TYPE_UNKNOWN, 0, false, false, true, false, false, false, "", ""); - volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk); - secondary.volume_manager()->OnDiskEvent( - chromeos::disks::DiskMountManager::DISK_ADDED, &kMediaDisk); + volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_ADDED, kMediaDisk); + secondary.volume_manager()->OnAutoMountableDiskEvent( + chromeos::disks::DiskMountManager::DISK_ADDED, kMediaDisk); // The profile with external storage enabled should have mounted the volume. bool has_volume_mounted = false;
diff --git a/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc b/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc index fe176b3..e365f975 100644 --- a/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc +++ b/chrome/browser/chromeos/fileapi/recent_arc_media_source_unittest.cc
@@ -19,6 +19,7 @@ #include "components/arc/arc_bridge_service.h" #include "components/arc/arc_service_manager.h" #include "components/arc/common/file_system.mojom.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_file_system_instance.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "content/public/test/test_browser_thread_bundle.h" @@ -78,6 +79,11 @@ source_ = base::MakeUnique<RecentArcMediaSource>(profile_.get()); } + void TearDown() override { + arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( + nullptr); + } + protected: void AddDocumentsToFakeFileSystemInstance() { auto root_doc = @@ -104,6 +110,8 @@ void EnableFakeFileSystemInstance() { arc_service_manager_->arc_bridge_service()->file_system()->SetInstance( &fake_file_system_); + arc::WaitForInstanceReady( + arc_service_manager_->arc_bridge_service()->file_system()); } std::vector<RecentFile> GetRecentFiles() {
diff --git a/chrome/browser/chromeos/note_taking_helper_unittest.cc b/chrome/browser/chromeos/note_taking_helper_unittest.cc index f54550e4..a29d442 100644 --- a/chrome/browser/chromeos/note_taking_helper_unittest.cc +++ b/chrome/browser/chromeos/note_taking_helper_unittest.cc
@@ -37,6 +37,7 @@ #include "components/arc/arc_util.h" #include "components/arc/common/intent_helper.mojom.h" #include "components/arc/intent_helper/arc_intent_helper_bridge.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_intent_helper_instance.h" #include "components/crx_file/id_util.h" #include "components/sync_preferences/testing_pref_service_syncable.h" @@ -218,6 +219,10 @@ void TearDown() override { if (initialized_) { + arc::ArcServiceManager::Get() + ->arc_bridge_service() + ->intent_helper() + ->SetInstance(nullptr); NoteTakingHelper::Shutdown(); intent_helper_bridge_.reset(); arc_test_.TearDown(); @@ -279,6 +284,8 @@ ->arc_bridge_service() ->intent_helper() ->SetInstance(&intent_helper_); + WaitForInstanceReady( + arc::ArcServiceManager::Get()->arc_bridge_service()->intent_helper()); if (flags & ENABLE_PALETTE) { base::CommandLine::ForCurrentProcess()->AppendSwitch(
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc index b42ac80..1aa115d 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.cc +++ b/chrome/browser/content_settings/tab_specific_content_settings.cc
@@ -54,6 +54,10 @@ #include "storage/common/fileapi/file_system_types.h" #include "url/origin.h" +#if !defined(OS_ANDROID) +#include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" +#endif + using content::BrowserThread; using content::NavigationController; using content::NavigationEntry; @@ -732,6 +736,21 @@ OnContentBlocked(CONTENT_SETTINGS_TYPE_SOUND); } +void TabSpecificContentSettings::OnFramebustBlocked(const GURL& blocked_url) { +#if !defined(OS_ANDROID) + FramebustBlockTabHelper* framebust_block_tab_helper = + FramebustBlockTabHelper::FromWebContents(web_contents()); + if (!framebust_block_tab_helper) + return; + + framebust_block_tab_helper->AddBlockedUrl(blocked_url); + content::NotificationService::current()->Notify( + chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, + content::Source<WebContents>(web_contents()), + content::NotificationService::NoDetails()); +#endif // !defined(OS_ANDROID) +} + void TabSpecificContentSettings::SetPepperBrokerAllowed(bool allowed) { if (allowed) { OnContentAllowed(CONTENT_SETTINGS_TYPE_PPAPI_BROKER);
diff --git a/chrome/browser/content_settings/tab_specific_content_settings.h b/chrome/browser/content_settings/tab_specific_content_settings.h index def6bc82..247a3d3 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.h +++ b/chrome/browser/content_settings/tab_specific_content_settings.h
@@ -203,6 +203,9 @@ // Called when audio has been blocked on the page. void OnAudioBlocked(); + // Updates the blocked framebust icon in the location bar. + void OnFramebustBlocked(const GURL& blocked_url); + // Returns whether a particular kind of content has been blocked for this // page. bool IsContentBlocked(ContentSettingsType content_type) const;
diff --git a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc index 23278aec..b62b194 100644 --- a/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc +++ b/chrome/browser/extensions/api/streams_private/streams_private_apitest.cc
@@ -227,10 +227,9 @@ // The |manager| should have |download| in its list of downloads. void DeleteDownloadAndWaitForFlush(DownloadItem* download, DownloadManager* manager) { - scoped_refptr<content::DownloadTestFlushObserver> flush_observer( - new content::DownloadTestFlushObserver(manager)); + content::DownloadTestFlushObserver flush_observer(manager); download->Remove(); - flush_observer->WaitForFlush(); + flush_observer.WaitForFlush(); } protected:
diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index f052ba9..d144111c 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc
@@ -55,7 +55,6 @@ #include "components/policy/policy_constants.h" #include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_service.h" -#include "components/proxy_config/pref_proxy_config_tracker.h" #include "components/variations/variations_associated_data.h" #include "components/version_info/version_info.h" #include "content/public/browser/browser_thread.h" @@ -334,11 +333,6 @@ g_browser_process->platform_part()->browser_policy_connector_chromeos(); allow_gssapi_library_load_ = connector->IsActiveDirectoryManaged(); #endif - pref_proxy_config_tracker_.reset( - ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( - local_state)); - system_proxy_config_service_ = ProxyServiceFactory::CreateProxyConfigService( - pref_proxy_config_tracker_.get()); ChromeNetworkDelegate::InitializePrefsOnUIThread( &system_enable_referrers_, nullptr, @@ -394,7 +388,6 @@ // be multiply constructed. BrowserThread::SetIOThreadDelegate(nullptr); - pref_proxy_config_tracker_->DetachFromPrefService(); DCHECK(!globals_); // Destroy the old distributor to check that the observers list it holds is @@ -588,7 +581,6 @@ // Shutdown the HistogramWatcher on the IO thread. net::NetworkChangeNotifier::ShutdownHistogramWatcher(); - system_proxy_config_service_.reset(); delete globals_; globals_ = nullptr; @@ -730,9 +722,8 @@ return pac_https_url_stripping_enabled_.GetValue(); } -void IOThread::SetUpProxyConfigService( - content::URLRequestContextBuilderMojo* builder, - std::unique_ptr<net::ProxyConfigService> proxy_config_service) const { +void IOThread::SetUpProxyService( + content::URLRequestContextBuilderMojo* builder) const { const base::CommandLine& command_line = *base::CommandLine::ForCurrentProcess(); @@ -757,7 +748,6 @@ PacHttpsUrlStrippingEnabled() ? net::ProxyService::SanitizeUrlPolicy::SAFE : net::ProxyService::SanitizeUrlPolicy::UNSAFE); - builder->set_proxy_config_service(std::move(proxy_config_service)); } content::mojom::NetworkService* IOThread::GetNetworkServiceOnUIThread() { @@ -826,8 +816,7 @@ builder->set_ct_verifier(std::move(ct_verifier)); - SetUpProxyConfigService(builder.get(), - std::move(system_proxy_config_service_)); + SetUpProxyService(builder.get()); globals_->network_service = content::NetworkService::Create( std::move(network_service_request_), net_log_);
diff --git a/chrome/browser/io_thread.h b/chrome/browser/io_thread.h index 5a4c264d..33e4ce8e 100644 --- a/chrome/browser/io_thread.h +++ b/chrome/browser/io_thread.h
@@ -35,7 +35,6 @@ #include "net/base/network_change_notifier.h" #include "net/nqe/network_quality_estimator.h" -class PrefProxyConfigTracker; class PrefService; class PrefRegistrySimple; class SystemNetworkContextManager; @@ -76,7 +75,6 @@ class HttpAuthHandlerFactory; class HttpAuthPreferences; class NetworkQualityEstimator; -class ProxyConfigService; class RTTAndThroughputEstimatesObserver; class SSLConfigService; class URLRequestContext; @@ -212,12 +210,9 @@ bool WpadQuickCheckEnabled() const; bool PacHttpsUrlStrippingEnabled() const; - // Configures |builder|'s ProxyService to use the specified - // |proxy_config_service| and sets a number of proxy-related options based on - // prefs, policies, and the command line. - void SetUpProxyConfigService( - content::URLRequestContextBuilderMojo* builder, - std::unique_ptr<net::ProxyConfigService> proxy_config_service) const; + // Configures |builder|'s ProxyService based on prefs, policies, and the + // command line. + void SetUpProxyService(content::URLRequestContextBuilderMojo* builder) const; // Gets a pointer to the NetworkService. Can only be called on the UI thread. // When out-of-process NetworkService is enabled, this is a reference to the @@ -326,12 +321,6 @@ std::unique_ptr<ssl_config::SSLConfigServiceManager> ssl_config_service_manager_; - // These member variables are initialized by a task posted to the IO thread, - // which gets posted by calling certain member functions of IOThread. - std::unique_ptr<net::ProxyConfigService> system_proxy_config_service_; - - std::unique_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; - scoped_refptr<net::URLRequestContextGetter> system_url_request_context_getter_;
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc index 1e8fc59..1d0aafb 100644 --- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.cc
@@ -992,20 +992,3 @@ return ProfileIOData::FromResourceContext(resource_context)-> CreateClientCertStore(); } - -bool ChromeResourceDispatcherHostDelegate::AllowRenderingMhtmlOverHttp( - net::URLRequest* request) const { -#if BUILDFLAG(ENABLE_OFFLINE_PAGES) - // It is OK to load the saved offline copy, in MHTML format. - const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); - ChromeNavigationUIData* navigation_data = - static_cast<ChromeNavigationUIData*>(info->GetNavigationUIData()); - if (!navigation_data) - return false; - offline_pages::OfflinePageNavigationUIData* offline_page_data = - navigation_data->GetOfflinePageNavigationUIData(); - return offline_page_data && offline_page_data->is_offline_page(); -#else - return false; -#endif -}
diff --git a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h index c5e300a..b1026c5 100644 --- a/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h +++ b/chrome/browser/loader/chrome_resource_dispatcher_host_delegate.h
@@ -93,7 +93,6 @@ net::URLRequest* request) const override; std::unique_ptr<net::ClientCertStore> CreateClientCertStore( content::ResourceContext* resource_context) override; - bool AllowRenderingMhtmlOverHttp(net::URLRequest* request) const override; // Called on the UI thread. Allows switching out the // ExternalProtocolHandler::Delegate for testing code.
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc index c94d9e9..3ef47eea 100644 --- a/chrome/browser/net/network_context_configuration_browsertest.cc +++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -4,6 +4,7 @@ #include <string> +#include "base/command_line.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" @@ -11,6 +12,7 @@ #include "base/strings/stringprintf.h" #include "base/test/scoped_feature_list.h" #include "base/threading/thread_restrictions.h" +#include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/net/profile_network_context_service.h" #include "chrome/browser/net/profile_network_context_service_factory.h" @@ -19,6 +21,9 @@ #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" #include "components/network_session_configurator/common/network_switches.h" +#include "components/prefs/pref_service.h" +#include "components/proxy_config/proxy_config_dictionary.h" +#include "components/proxy_config/proxy_config_pref_names.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/content_features.h" @@ -34,6 +39,7 @@ #include "content/public/test/test_url_loader_client.h" #include "mojo/common/data_pipe_utils.h" #include "net/base/filename_util.h" +#include "net/base/host_port_pair.h" #include "net/base/net_errors.h" #include "net/http/http_response_headers.h" #include "net/test/embedded_test_server/embedded_test_server.h" @@ -134,6 +140,49 @@ return StorageType::kNone; } + // Sets the proxy preference on a PrefService based on the NetworkContextType, + // and waits for it to be applied. + void SetProxyPref(const net::HostPortPair& host_port_pair) { + // Get the correct PrefService. + PrefService* pref_service = nullptr; + switch (GetParam().network_context_type) { + case NetworkContextType::kSystem: + pref_service = g_browser_process->local_state(); + break; + case NetworkContextType::kProfile: + pref_service = browser()->profile()->GetPrefs(); + break; + case NetworkContextType::kIncognitoProfile: + // Incognito uses the non-incognito prefs. + pref_service = + browser()->profile()->GetOffTheRecordProfile()->GetPrefs(); + break; + } + + pref_service->Set(proxy_config::prefs::kProxy, + *ProxyConfigDictionary::CreateFixedServers( + host_port_pair.ToString(), std::string())); + + // Wait for the new ProxyConfig to be passed over the pipe. Needed because + // Mojo doesn't guarantee ordering of events on different Mojo pipes, and + // requests are sent on a separate pipe from ProxyConfigs. + switch (GetParam().network_context_type) { + case NetworkContextType::kSystem: + g_browser_process->system_network_context_manager() + ->FlushProxyConfigMonitorForTesting(); + break; + case NetworkContextType::kProfile: + ProfileNetworkContextServiceFactory::GetForContext(browser()->profile()) + ->FlushProxyConfigMonitorForTesting(); + break; + case NetworkContextType::kIncognitoProfile: + ProfileNetworkContextServiceFactory::GetForContext( + browser()->profile()->GetOffTheRecordProfile()) + ->FlushProxyConfigMonitorForTesting(); + break; + } + } + private: content::mojom::NetworkContext* network_context_ = nullptr; content::mojom::URLLoaderFactory* loader_factory_ = nullptr; @@ -330,6 +379,28 @@ } } +IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationBrowserTest, ProxyConfig) { + SetProxyPref(embedded_test_server()->host_port_pair()); + + std::unique_ptr<content::ResourceRequest> request = + std::make_unique<content::ResourceRequest>(); + // This URL should be directed to the test server because of the proxy. + request->url = GURL("http://jabberwocky.com:1872/echo"); + + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<content::SimpleURLLoader> simple_loader = + content::SimpleURLLoader::Create(std::move(request), + TRAFFIC_ANNOTATION_FOR_TESTS); + + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + loader_factory(), simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + + EXPECT_EQ(net::OK, simple_loader->NetError()); + ASSERT_TRUE(simple_loader_helper.response_body()); + EXPECT_EQ(*simple_loader_helper.response_body(), "Echo"); +} + class NetworkContextConfigurationFixedPortBrowserTest : public NetworkContextConfigurationBrowserTest { public: @@ -342,8 +413,6 @@ base::StringPrintf("%u", embedded_test_server()->port())); LOG(WARNING) << base::StringPrintf("%u", embedded_test_server()->port()); } - - private: }; // Test that the command line switch makes it to the network service and is @@ -370,6 +439,42 @@ EXPECT_EQ(*simple_loader_helper.response_body(), "Echo"); } +class NetworkContextConfigurationProxyOnStartBrowserTest + : public NetworkContextConfigurationBrowserTest { + public: + NetworkContextConfigurationProxyOnStartBrowserTest() {} + ~NetworkContextConfigurationProxyOnStartBrowserTest() override {} + + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitchASCII( + switches::kProxyServer, + embedded_test_server()->host_port_pair().ToString()); + } +}; + +// Test that when there's a proxy configuration at startup, the initial requests +// use that configuration. +IN_PROC_BROWSER_TEST_P(NetworkContextConfigurationProxyOnStartBrowserTest, + TestInitialProxyConfig) { + std::unique_ptr<content::ResourceRequest> request = + std::make_unique<content::ResourceRequest>(); + // This URL should be directed to the test server because of the proxy. + request->url = GURL("http://jabberwocky.com:1872/echo"); + + content::SimpleURLLoaderTestHelper simple_loader_helper; + std::unique_ptr<content::SimpleURLLoader> simple_loader = + content::SimpleURLLoader::Create(std::move(request), + TRAFFIC_ANNOTATION_FOR_TESTS); + + simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie( + loader_factory(), simple_loader_helper.GetCallback()); + simple_loader_helper.WaitForCallback(); + + EXPECT_EQ(net::OK, simple_loader->NetError()); + ASSERT_TRUE(simple_loader_helper.response_body()); + EXPECT_EQ(*simple_loader_helper.response_body(), "Echo"); +} + // Instiates tests with a prefix indicating which NetworkContext is being // tested, and a suffix of "/0" if the network service is disabled and "/1" if // it's enabled. @@ -398,5 +503,7 @@ INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE(NetworkContextConfigurationBrowserTest); INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE( NetworkContextConfigurationFixedPortBrowserTest); +INSTANTIATE_TEST_CASES_FOR_TEST_FIXTURE( + NetworkContextConfigurationProxyOnStartBrowserTest); } // namespace
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc index 0a339aed..3d3d057 100644 --- a/chrome/browser/net/profile_network_context_service.cc +++ b/chrome/browser/net/profile_network_context_service.cc
@@ -28,57 +28,8 @@ #include "mojo/public/cpp/bindings/associated_interface_ptr.h" #include "net/net_features.h" -namespace { - -content::mojom::NetworkContextParamsPtr CreateMainNetworkContextParams( - Profile* profile) { - // TODO(mmenke): Set up parameters here. - content::mojom::NetworkContextParamsPtr network_context_params = - CreateDefaultNetworkContextParams(); - - network_context_params->context_name = std::string("main"); - - // Always enable the HTTP cache. - network_context_params->http_cache_enabled = true; - - // Configure on-disk storage for non-OTR profiles. OTR profiles just use - // default behavior (in memory storage, default sizes). - PrefService* prefs = profile->GetPrefs(); - if (!profile->IsOffTheRecord()) { - // Configure the HTTP cache path and size. - base::FilePath base_cache_path; - chrome::GetUserCacheDirectory(profile->GetPath(), &base_cache_path); - base::FilePath disk_cache_dir = prefs->GetFilePath(prefs::kDiskCacheDir); - if (!disk_cache_dir.empty()) - base_cache_path = disk_cache_dir.Append(base_cache_path.BaseName()); - network_context_params->http_cache_path = - base_cache_path.Append(chrome::kCacheDirname); - network_context_params->http_cache_max_size = - prefs->GetInteger(prefs::kDiskCacheSize); - - // Currently this just contains HttpServerProperties, but that will likely - // change. - network_context_params->http_server_properties_path = - profile->GetPath().Append(chrome::kNetworkPersistentStateFilename); - } - - // NOTE(mmenke): Keep these protocol handlers and - // ProfileIOData::SetUpJobFactoryDefaultsForBuilder in sync with - // ProfileIOData::IsHandledProtocol(). - // TODO(mmenke): Find a better way of handling tracking supported schemes. - network_context_params->enable_data_url_support = true; - network_context_params->enable_file_url_support = true; -#if !BUILDFLAG(DISABLE_FTP_SUPPORT) - network_context_params->enable_ftp_url_support = true; -#endif // !BUILDFLAG(DISABLE_FTP_SUPPORT) - - return network_context_params; -} - -} // namespace - ProfileNetworkContextService::ProfileNetworkContextService(Profile* profile) - : profile_(profile) { + : profile_(profile), proxy_config_monitor_(profile) { quic_allowed_.Init( prefs::kQuicAllowed, profile->GetPrefs(), base::Bind(&ProfileNetworkContextService::DisableQuicIfNotAllowed, @@ -105,7 +56,7 @@ content::mojom::NetworkContextPtr network_context; content::GetNetworkService()->CreateNetworkContext( - MakeRequest(&network_context), CreateMainNetworkContextParams(profile_)); + MakeRequest(&network_context), CreateMainNetworkContextParams()); return network_context; } @@ -124,7 +75,7 @@ } if (!base::FeatureList::IsEnabled(features::kNetworkService)) { - *network_context_params = CreateMainNetworkContextParams(profile_); + *network_context_params = CreateMainNetworkContextParams(); return; } @@ -149,3 +100,54 @@ g_browser_process->system_network_context_manager()->DisableQuic(); } + +void ProfileNetworkContextService::FlushProxyConfigMonitorForTesting() { + proxy_config_monitor_.FlushForTesting(); +} + +content::mojom::NetworkContextParamsPtr +ProfileNetworkContextService::CreateMainNetworkContextParams() { + // TODO(mmenke): Set up parameters here. + content::mojom::NetworkContextParamsPtr network_context_params = + CreateDefaultNetworkContextParams(); + + network_context_params->context_name = std::string("main"); + + // Always enable the HTTP cache. + network_context_params->http_cache_enabled = true; + + // Configure on-disk storage for non-OTR profiles. OTR profiles just use + // default behavior (in memory storage, default sizes). + PrefService* prefs = profile_->GetPrefs(); + if (!profile_->IsOffTheRecord()) { + // Configure the HTTP cache path and size. + base::FilePath base_cache_path; + chrome::GetUserCacheDirectory(profile_->GetPath(), &base_cache_path); + base::FilePath disk_cache_dir = prefs->GetFilePath(prefs::kDiskCacheDir); + if (!disk_cache_dir.empty()) + base_cache_path = disk_cache_dir.Append(base_cache_path.BaseName()); + network_context_params->http_cache_path = + base_cache_path.Append(chrome::kCacheDirname); + network_context_params->http_cache_max_size = + prefs->GetInteger(prefs::kDiskCacheSize); + + // Currently this just contains HttpServerProperties, but that will likely + // change. + network_context_params->http_server_properties_path = + profile_->GetPath().Append(chrome::kNetworkPersistentStateFilename); + } + + // NOTE(mmenke): Keep these protocol handlers and + // ProfileIOData::SetUpJobFactoryDefaultsForBuilder in sync with + // ProfileIOData::IsHandledProtocol(). + // TODO(mmenke): Find a better way of handling tracking supported schemes. + network_context_params->enable_data_url_support = true; + network_context_params->enable_file_url_support = true; +#if !BUILDFLAG(DISABLE_FTP_SUPPORT) + network_context_params->enable_ftp_url_support = true; +#endif // !BUILDFLAG(DISABLE_FTP_SUPPORT) + + proxy_config_monitor_.AddToNetworkContextParams(network_context_params.get()); + + return network_context_params; +}
diff --git a/chrome/browser/net/profile_network_context_service.h b/chrome/browser/net/profile_network_context_service.h index cdc9f63..8de0d08 100644 --- a/chrome/browser/net/profile_network_context_service.h +++ b/chrome/browser/net/profile_network_context_service.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_NET_PROFILE_NETWORK_CONTEXT_SERVICE_H_ #include "base/macros.h" +#include "chrome/browser/net/proxy_config_monitor.h" #include "components/keyed_service/core/keyed_service.h" #include "components/prefs/pref_member.h" #include "content/public/common/network_service.mojom.h" @@ -53,12 +54,21 @@ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); + // Flushes all pending proxy configuration changes. + void FlushProxyConfigMonitorForTesting(); + private: // Checks |quic_allowed_|, and disables QUIC if needed. void DisableQuicIfNotAllowed(); + // Creates parameters for the NetworkContext. May only be called once, since + // it initializes some class members. + content::mojom::NetworkContextParamsPtr CreateMainNetworkContextParams(); + Profile* const profile_; + ProxyConfigMonitor proxy_config_monitor_; + // This is a NetworkContext interface that uses ProfileIOData's // NetworkContext. If the network service is disabled, ownership is passed to // StoragePartition when CreateMainNetworkContext is called. Otherwise,
diff --git a/chrome/browser/net/proxy_config_monitor.cc b/chrome/browser/net/proxy_config_monitor.cc new file mode 100644 index 0000000..620ff27 --- /dev/null +++ b/chrome/browser/net/proxy_config_monitor.cc
@@ -0,0 +1,109 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/net/proxy_config_monitor.h" + +#include "build/build_config.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/net/proxy_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "components/proxy_config/pref_proxy_config_tracker_impl.h" +#include "content/public/browser/browser_thread.h" +#include "mojo/public/cpp/bindings/associated_interface_ptr.h" + +#if defined(OS_CHROMEOS) +#include "chrome/browser/chromeos/profiles/profile_helper.h" +#endif // defined(OS_CHROMEOS) + +ProxyConfigMonitor::ProxyConfigMonitor(Profile* profile) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + DCHECK(profile); + +// If this is the ChromeOS sign-in profile, just create the tracker from global +// state. +#if defined(OS_CHROMEOS) + if (chromeos::ProfileHelper::IsSigninProfile(profile)) { + pref_proxy_config_tracker_.reset( + ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( + g_browser_process->local_state())); + } +#endif // defined(OS_CHROMEOS) + + if (!pref_proxy_config_tracker_) { + pref_proxy_config_tracker_.reset( + ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile( + profile->GetPrefs(), g_browser_process->local_state())); + } + + proxy_config_service_ = ProxyServiceFactory::CreateProxyConfigService( + pref_proxy_config_tracker_.get()); + + proxy_config_service_->AddObserver(this); +} + +ProxyConfigMonitor::ProxyConfigMonitor() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + pref_proxy_config_tracker_.reset( + ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( + g_browser_process->local_state())); + + proxy_config_service_ = ProxyServiceFactory::CreateProxyConfigService( + pref_proxy_config_tracker_.get()); + + proxy_config_service_->AddObserver(this); +} + +ProxyConfigMonitor::~ProxyConfigMonitor() { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + proxy_config_service_->RemoveObserver(this); + pref_proxy_config_tracker_->DetachFromPrefService(); +} + +void ProxyConfigMonitor::AddToNetworkContextParams( + content::mojom::NetworkContextParams* network_context_params) { + content::mojom::ProxyConfigClientPtr proxy_config_client; + network_context_params->proxy_config_client_request = + mojo::MakeRequest(&proxy_config_client); + proxy_config_client_set_.AddPtr(std::move(proxy_config_client)); + + binding_set_.AddBinding( + this, + mojo::MakeRequest(&network_context_params->proxy_config_poller_client)); + net::ProxyConfig proxy_config; + net::ProxyConfigService::ConfigAvailability availability = + proxy_config_service_->GetLatestProxyConfig(&proxy_config); + if (availability != net::ProxyConfigService::CONFIG_PENDING) + network_context_params->initial_proxy_config = proxy_config; +} + +void ProxyConfigMonitor::FlushForTesting() { + proxy_config_client_set_.FlushForTesting(); +} + +void ProxyConfigMonitor::OnProxyConfigChanged( + const net::ProxyConfig& config, + net::ProxyConfigService::ConfigAvailability availability) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + proxy_config_client_set_.ForAllPtrs( + [config, + availability](content::mojom::ProxyConfigClient* proxy_config_client) { + switch (availability) { + case net::ProxyConfigService::CONFIG_VALID: + proxy_config_client->OnProxyConfigUpdated(config); + break; + case net::ProxyConfigService::CONFIG_UNSET: + proxy_config_client->OnProxyConfigUpdated( + net::ProxyConfig::CreateDirect()); + break; + case net::ProxyConfigService::CONFIG_PENDING: + NOTREACHED(); + break; + } + }); +} + +void ProxyConfigMonitor::OnLazyProxyConfigPoll() { + proxy_config_service_->OnLazyPoll(); +}
diff --git a/chrome/browser/net/proxy_config_monitor.h b/chrome/browser/net/proxy_config_monitor.h new file mode 100644 index 0000000..c58bfcf --- /dev/null +++ b/chrome/browser/net/proxy_config_monitor.h
@@ -0,0 +1,75 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NET_PROXY_CONFIG_MONITOR_H_ +#define CHROME_BROWSER_NET_PROXY_CONFIG_MONITOR_H_ + +#include <memory> + +#include "base/macros.h" +#include "content/public/common/network_service.mojom.h" +#include "content/public/common/proxy_config.mojom.h" +#include "mojo/public/cpp/bindings/binding_set.h" +#include "mojo/public/cpp/bindings/interface_ptr_set.h" +#include "net/proxy/proxy_config_service.h" + +namespace net { +class ProxyConfig; +} + +class Profile; +class PrefProxyConfigTracker; + +// Tracks the ProxyConfig to use, and passes any updates to a NetworkContext's +// ProxyConfigClient. +class ProxyConfigMonitor : public net::ProxyConfigService::Observer, + public content::mojom::ProxyConfigPollerClient { + public: + // Creates a ProxyConfigMonitor that gets proxy settings from |profile| and + // watches for changes. The created ProxyConfigMonitor must be destroyed + // before |profile|. + explicit ProxyConfigMonitor(Profile* profile); + + // Creates a ProxyConfigMonitor that gets proxy settings from the + // BrowserProcess's |local_state_|, for use with NetworkContexts not + // assocaited with a profile. Must be destroyed before the BrowserProcess's + // |local_state_|. + ProxyConfigMonitor(); + + ~ProxyConfigMonitor() override; + + // Populates proxy-related fields of |network_context_params|. Updated + // ProxyConfigs will be sent to a NetworkContext created with those params + // whenever the configuration changes. Can be called more than once to inform + // multiple NetworkContexts of proxy changes. + void AddToNetworkContextParams( + content::mojom::NetworkContextParams* network_context_params); + + // Flushes all pending data on the pipe, blocking the current thread until + // they're received, to allow tests to wait until all pending proxy + // configuration changes have been applied. + void FlushForTesting(); + + private: + // net::ProxyConfigService::Observer implementation: + void OnProxyConfigChanged( + const net::ProxyConfig& config, + net::ProxyConfigService::ConfigAvailability availability) override; + + // content::mojom::ProxyConfigPollerClient implementation: + void OnLazyProxyConfigPoll() override; + + std::unique_ptr<net::ProxyConfigService> proxy_config_service_; + // Monitors global and Profile prefs related to proxy configuration. + std::unique_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; + + mojo::BindingSet<content::mojom::ProxyConfigPollerClient> binding_set_; + + mojo::InterfacePtrSet<content::mojom::ProxyConfigClient> + proxy_config_client_set_; + + DISALLOW_COPY_AND_ASSIGN(ProxyConfigMonitor); +}; + +#endif // CHROME_BROWSER_NET_PROXY_CONFIG_MONITOR_H_
diff --git a/chrome/browser/net/proxy_service_factory.cc b/chrome/browser/net/proxy_service_factory.cc index 17c0e53..5ce2abc 100644 --- a/chrome/browser/net/proxy_service_factory.cc +++ b/chrome/browser/net/proxy_service_factory.cc
@@ -35,7 +35,7 @@ // include command line and configuration policy). base_service = net::ProxyService::CreateSystemProxyConfigService( - BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); + BrowserThread::GetTaskRunnerForThread(BrowserThread::UI)); #endif // !defined(OS_CHROMEOS) return tracker->CreateTrackingProxyConfigService(std::move(base_service)); @@ -47,12 +47,10 @@ PrefService* profile_prefs, PrefService* local_state_prefs) { #if defined(OS_CHROMEOS) - return new chromeos::ProxyConfigServiceImpl( - profile_prefs, local_state_prefs, - BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); + return new chromeos::ProxyConfigServiceImpl(profile_prefs, local_state_prefs, + nullptr); #else - return new PrefProxyConfigTrackerImpl( - profile_prefs, BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); + return new PrefProxyConfigTrackerImpl(profile_prefs, nullptr); #endif // defined(OS_CHROMEOS) } @@ -61,12 +59,9 @@ ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( PrefService* local_state_prefs) { #if defined(OS_CHROMEOS) - return new chromeos::ProxyConfigServiceImpl( - nullptr, local_state_prefs, - BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); + return new chromeos::ProxyConfigServiceImpl(nullptr, local_state_prefs, + nullptr); #else - return new PrefProxyConfigTrackerImpl( - local_state_prefs, - BrowserThread::GetTaskRunnerForThread(BrowserThread::IO)); + return new PrefProxyConfigTrackerImpl(local_state_prefs, nullptr); #endif // defined(OS_CHROMEOS) }
diff --git a/chrome/browser/net/system_network_context_manager.cc b/chrome/browser/net/system_network_context_manager.cc index 590efe8..12398d9 100644 --- a/chrome/browser/net/system_network_context_manager.cc +++ b/chrome/browser/net/system_network_context_manager.cc
@@ -28,25 +28,6 @@ namespace { -content::mojom::NetworkContextParamsPtr CreateNetworkContextParams() { - // TODO(mmenke): Set up parameters here (in memory cookie store, etc). - content::mojom::NetworkContextParamsPtr network_context_params = - CreateDefaultNetworkContextParams(); - - network_context_params->context_name = std::string("system"); - - network_context_params->http_cache_enabled = false; - - // These are needed for PAC scripts that use file or data URLs (Or FTP URLs?). - network_context_params->enable_data_url_support = true; - network_context_params->enable_file_url_support = true; -#if !BUILDFLAG(DISABLE_FTP_SUPPORT) - network_context_params->enable_ftp_url_support = true; -#endif - - return network_context_params; -} - // Called on IOThread to disable QUIC for HttpNetworkSessions not using the // network service. Note that re-enabling QUIC dynamically is not supported for // simpliciy and requires a browser restart. @@ -101,7 +82,13 @@ content::mojom::NetworkContextParamsPtr* network_context_params, bool* is_quic_allowed) { *network_context_request = mojo::MakeRequest(&io_thread_network_context_); - *network_context_params = CreateNetworkContextParams(); + if (!base::FeatureList::IsEnabled(features::kNetworkService)) { + *network_context_params = CreateNetworkContextParams(); + } else { + // Just use defaults if the network service is enabled, since + // CreateNetworkContextParams() can only be called once. + *network_context_params = CreateDefaultNetworkContextParams(); + } *is_quic_allowed = is_quic_allowed_; } @@ -140,3 +127,29 @@ base::BindOnce(&DisableQuicOnIOThread, io_thread, base::Unretained(safe_browsing_service))); } + +void SystemNetworkContextManager::FlushProxyConfigMonitorForTesting() { + proxy_config_monitor_.FlushForTesting(); +} + +content::mojom::NetworkContextParamsPtr +SystemNetworkContextManager::CreateNetworkContextParams() { + // TODO(mmenke): Set up parameters here (in memory cookie store, etc). + content::mojom::NetworkContextParamsPtr network_context_params = + CreateDefaultNetworkContextParams(); + + network_context_params->context_name = std::string("system"); + + network_context_params->http_cache_enabled = false; + + // These are needed for PAC scripts that use file or data URLs (Or FTP URLs?). + network_context_params->enable_data_url_support = true; + network_context_params->enable_file_url_support = true; +#if !BUILDFLAG(DISABLE_FTP_SUPPORT) + network_context_params->enable_ftp_url_support = true; +#endif + + proxy_config_monitor_.AddToNetworkContextParams(network_context_params.get()); + + return network_context_params; +}
diff --git a/chrome/browser/net/system_network_context_manager.h b/chrome/browser/net/system_network_context_manager.h index 529031c2b..515e605 100644 --- a/chrome/browser/net/system_network_context_manager.h +++ b/chrome/browser/net/system_network_context_manager.h
@@ -8,8 +8,11 @@ #include <memory> #include "base/macros.h" +#include "chrome/browser/net/proxy_config_monitor.h" #include "content/public/common/network_service.mojom.h" +class ProxyConfigMonitor; + // Responsible for creating and managing access to the system NetworkContext. // Lives on the UI thread. The NetworkContext this owns is intended for requests // not associated with a profile. It stores no data on disk, and has no HTTP @@ -62,7 +65,16 @@ // NetworkService, and for those using the network service (if enabled). void DisableQuic(); + // Flushes all pending proxy configuration changes. + void FlushProxyConfigMonitorForTesting(); + private: + // Creates parameters for the NetworkContext. May only be called once, since + // it initializes some class members. + content::mojom::NetworkContextParamsPtr CreateNetworkContextParams(); + + ProxyConfigMonitor proxy_config_monitor_; + // NetworkContext using the network service, if the network service is // enabled. nullptr, otherwise. content::mojom::NetworkContextPtr network_service_network_context_;
diff --git a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc index 704abbb..23501fa6 100644 --- a/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc +++ b/chrome/browser/prerender/prerender_nostate_prefetch_browsertest.cc
@@ -29,12 +29,14 @@ #include "chrome/common/chrome_switches.h" #include "chrome/test/base/ui_test_utils.h" #include "content/public/browser/appcache_service.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/storage_partition.h" #include "content/public/common/content_features.h" #include "content/public/common/result_codes.h" #include "content/public/common/url_constants.h" #include "content/public/test/browser_test_utils.h" +#include "content/public/test/url_loader_interceptor.h" #include "net/base/escape.h" #include "net/base/load_flags.h" #include "net/dns/mock_host_resolver.h" @@ -161,6 +163,15 @@ expected_final_status); } + content::StoragePartition* GetStoragePartition() { + return browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetMainFrame() + ->GetProcess() + ->GetStoragePartition(); + } + private: // Schedule a task to retrieve AppCacheInfo from |appcache_service|. This sets // |found_manifest| if an appcache exists for |manifest_url|. |callback| will @@ -221,29 +232,38 @@ // Check that the LOAD_PREFETCH flag is set. IN_PROC_BROWSER_TEST_P(NoStatePrefetchBrowserTest, PrefetchLoadFlag) { - // TODO(jam): use URLLoaderFactory for subresource. - // This will need a separate code path for network service: - // -add way for the - // storage_partition->GetNetworkContext()->CreateURLLoaderFactory - // to return test defined factoory - // -also add a URLLoader unittest to verify that if ResourceRequest has that - // flag it is passed to the net::URLRequest - RequestCounter main_counter; - RequestCounter script_counter; - auto verify_prefetch_only = base::Bind([](net::URLRequest* request) { - EXPECT_TRUE(request->load_flags() & net::LOAD_PREFETCH); - }); + GURL prefetch_page = src_server()->GetURL(kPrefetchPage); + GURL prefetch_script = src_server()->GetURL(kPrefetchScript); - prerender::test_utils::InterceptRequestAndCount( - src_server()->GetURL(kPrefetchPage), &main_counter, verify_prefetch_only); - prerender::test_utils::InterceptRequestAndCount( - src_server()->GetURL(kPrefetchScript), &script_counter, - verify_prefetch_only); + bool use_interceptor_for_frame_requests = + base::FeatureList::IsEnabled(features::kNetworkService); + if (!use_interceptor_for_frame_requests) { + // Until http://crbug.com/747130 is fixed, navigation requests won't go + // through URLLoader. + prerender::test_utils::InterceptRequest( + prefetch_page, + base::Bind([](net::URLRequest* request) { + EXPECT_TRUE(request->load_flags() & net::LOAD_PREFETCH); + })); + } + + content::URLLoaderInterceptor interceptor( + base::Bind( + [](const GURL& prefetch_page, const GURL& prefetch_script, + content::URLLoaderInterceptor::RequestParams* params) { + if (params->url_request.url == prefetch_page || + params->url_request.url == prefetch_script) { + EXPECT_TRUE(params->url_request.load_flags & net::LOAD_PREFETCH); + } + return false; + }, + prefetch_page, prefetch_script), + GetStoragePartition(), use_interceptor_for_frame_requests, true); std::unique_ptr<TestPrerender> test_prerender = PrefetchFromFile(kPrefetchPage, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); - main_counter.WaitForCount(1); - script_counter.WaitForCount(1); + WaitForRequestCount(prefetch_page, 1); + WaitForRequestCount(prefetch_script, 1); // Verify that the page load did not happen. test_prerender->WaitForLoads(0); @@ -384,18 +404,33 @@ "/server-redirect/?" + net::EscapeQueryParamValue(kPrefetchPage, false); GURL redirect_url = src_server()->GetURL(redirect_path); GURL page_url = src_server()->GetURL(kPrefetchPage); - RequestCounter redirect_counter; auto verify_prefetch_only = base::Bind([](net::URLRequest* request) { EXPECT_TRUE(request->load_flags() & net::LOAD_PREFETCH); }); - prerender::test_utils::InterceptRequestAndCount( - redirect_url, &redirect_counter, verify_prefetch_only); - RequestCounter page_counter; - prerender::test_utils::InterceptRequestAndCount(page_url, &page_counter, - verify_prefetch_only); + + bool use_interceptor = false; + if (base::FeatureList::IsEnabled(features::kNetworkService)) { + use_interceptor = true; + } else { + // Until http://crbug.com/747130 is fixed, navigation requests won't go + // through URLLoader. + prerender::test_utils::InterceptRequest(page_url, verify_prefetch_only); + } + + content::URLLoaderInterceptor interceptor( + base::Bind( + [](const GURL& page_url, + content::URLLoaderInterceptor::RequestParams* params) { + if (params->url_request.url == page_url) + EXPECT_TRUE(params->url_request.load_flags & net::LOAD_PREFETCH); + return false; + }, + redirect_url), + GetStoragePartition(), use_interceptor, false); + PrefetchFromFile(redirect_path, FINAL_STATUS_NOSTATE_PREFETCH_FINISHED); - redirect_counter.WaitForCount(1); - page_counter.WaitForCount(1); + WaitForRequestCount(redirect_url, 1); + WaitForRequestCount(page_url, 1); } // Checks that a subresource 301 redirect is followed.
diff --git a/chrome/browser/prerender/prerender_resource_throttle.cc b/chrome/browser/prerender/prerender_resource_throttle.cc index c90cad0..e12cdcf9 100644 --- a/chrome/browser/prerender/prerender_resource_throttle.cc +++ b/chrome/browser/prerender/prerender_resource_throttle.cc
@@ -85,7 +85,6 @@ PrerenderResourceThrottle::PrerenderResourceThrottle(net::URLRequest* request) : request_(request), - load_flags_(net::LOAD_NORMAL), prerender_throttle_info_(new PrerenderThrottleInfo()) { // Priorities for prerendering requests are lowered, to avoid competing with // other page loads, except on Android where this is less likely to be a @@ -170,7 +169,6 @@ void PrerenderResourceThrottle::ResumeHandler() { DCHECK_CURRENTLY_ON(BrowserThread::IO); - request_->SetLoadFlags(request_->load_flags() | load_flags_); Resume(); } @@ -201,10 +199,6 @@ prerender_throttle_info->Set(prerender_contents->prerender_mode(), prerender_contents->origin(), prerender_contents->prerender_manager()); - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&PrerenderResourceThrottle::SetPrerenderMode, throttle, - prerender_contents->prerender_mode())); // Abort any prerenders that spawn requests that use unsupported HTTP // methods or schemes. @@ -329,9 +323,4 @@ return PrerenderContents::FromWebContents(web_contents_getter.Run()); } -void PrerenderResourceThrottle::SetPrerenderMode(PrerenderMode mode) { - DCHECK_CURRENTLY_ON(BrowserThread::IO); - load_flags_ = (mode == PREFETCH_ONLY) ? net::LOAD_PREFETCH : net::LOAD_NORMAL; -} - } // namespace prerender
diff --git a/chrome/browser/prerender/prerender_resource_throttle.h b/chrome/browser/prerender/prerender_resource_throttle.h index 0302ec5..a117d9bd 100644 --- a/chrome/browser/prerender/prerender_resource_throttle.h +++ b/chrome/browser/prerender/prerender_resource_throttle.h
@@ -89,11 +89,7 @@ const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter); - // Sets the prerender mode. Must be called before |ResumeHandler()|. - void SetPrerenderMode(PrerenderMode mode); - net::URLRequest* request_; - int load_flags_; // Load flags to be OR'ed with the existing request flags. // The throttle changes most request priorities to IDLE during prerendering. // The priority is reset back to the original priority when prerendering is
diff --git a/chrome/browser/prerender/prerender_test_utils.cc b/chrome/browser/prerender/prerender_test_utils.cc index 300db3d0..2964947 100644 --- a/chrome/browser/prerender/prerender_test_utils.cc +++ b/chrome/browser/prerender/prerender_test_utils.cc
@@ -107,16 +107,19 @@ class CountingInterceptorWithCallback : public net::URLRequestInterceptor { public: // Inserts the interceptor object to intercept requests to |url|. Can be - // called on any thread. Assumes that |counter| lives on the UI thread. The - // |callback_io| will be called on IO thread with the net::URLrequest - // provided. + // called on any thread. Assumes that |counter| (if non-null) lives on the UI + // thread. The |callback_io| will be called on IO thread with the + // net::URLrequest provided. static void Initialize(const GURL& url, RequestCounter* counter, base::Callback<void(net::URLRequest*)> callback_io) { + base::WeakPtr<RequestCounter> weakptr; + if (counter) + weakptr = counter->AsWeakPtr(); content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, base::BindOnce(&CountingInterceptorWithCallback::CreateAndAddOnIO, url, - counter->AsWeakPtr(), callback_io)); + weakptr, callback_io)); } // net::URLRequestInterceptor: @@ -853,6 +856,11 @@ url, base::MakeUnique<CountingInterceptor>(file, counter)); } +void InterceptRequest(const GURL& url, + base::Callback<void(net::URLRequest*)> callback_io) { + CountingInterceptorWithCallback::Initialize(url, nullptr, callback_io); +} + void InterceptRequestAndCount( const GURL& url, RequestCounter* counter,
diff --git a/chrome/browser/prerender/prerender_test_utils.h b/chrome/browser/prerender/prerender_test_utils.h index 00d9fe3d..8d93a2d 100644 --- a/chrome/browser/prerender/prerender_test_utils.h +++ b/chrome/browser/prerender/prerender_test_utils.h
@@ -434,6 +434,12 @@ const base::WeakPtr<RequestCounter>& counter); // When the |url| hits the net::URLRequestFilter (on the IO thread), executes +// the |callback_io| providing the request to it. Does not modify the behavior +// or the request job. +void InterceptRequest(const GURL& url, + base::Callback<void(net::URLRequest*)> callback_io); + +// When the |url| hits the net::URLRequestFilter (on the IO thread), executes // the |callback_io| providing the request to it, also pings the |counter| on UI // thread. Does not modify the behavior or the request job. void InterceptRequestAndCount(
diff --git a/chrome/browser/printing/print_job.cc b/chrome/browser/printing/print_job.cc index 50c467c9..5fa6170 100644 --- a/chrome/browser/printing/print_job.cc +++ b/chrome/browser/printing/print_job.cc
@@ -373,7 +373,6 @@ break; } case JobEventDetails::NEW_DOC: - case JobEventDetails::NEW_PAGE: case JobEventDetails::JOB_DONE: case JobEventDetails::ALL_PAGES_REQUESTED: { // Don't care.
diff --git a/chrome/browser/printing/print_job.h b/chrome/browser/printing/print_job.h index 239456b..b4979af6 100644 --- a/chrome/browser/printing/print_job.h +++ b/chrome/browser/printing/print_job.h
@@ -186,9 +186,6 @@ // A new document started printing. NEW_DOC, - // A new page started printing. - NEW_PAGE, - // A page is done printing. PAGE_DONE,
diff --git a/chrome/browser/printing/print_job_manager.cc b/chrome/browser/printing/print_job_manager.cc index 60fcd135..44b60df 100644 --- a/chrome/browser/printing/print_job_manager.cc +++ b/chrome/browser/printing/print_job_manager.cc
@@ -138,7 +138,6 @@ case JobEventDetails::USER_INIT_DONE: case JobEventDetails::USER_INIT_CANCELED: case JobEventDetails::DEFAULT_INIT_DONE: - case JobEventDetails::NEW_PAGE: case JobEventDetails::PAGE_DONE: case JobEventDetails::DOC_DONE: case JobEventDetails::ALL_PAGES_REQUESTED: {
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc index 6f185aef..3ba4ffe 100644 --- a/chrome/browser/printing/print_job_worker.cc +++ b/chrome/browser/printing/print_job_worker.cc
@@ -403,13 +403,6 @@ DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK_NE(page_number_, PageNumber::npos()); - // Signal everyone that the page is about to be printed. - owner_->PostTask( - FROM_HERE, - base::Bind(&NotificationCallback, base::RetainedRef(owner_), - JobEventDetails::NEW_PAGE, printing_context_->job_id(), - base::RetainedRef(document_), base::RetainedRef(page))); - // Preprocess. if (printing_context_->NewPage() != PrintingContext::OK) { OnFailure();
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc index bdc6e4d8..d13aa8e 100644 --- a/chrome/browser/printing/print_view_manager_base.cc +++ b/chrome/browser/printing/print_view_manager_base.cc
@@ -363,7 +363,6 @@ break; } case JobEventDetails::NEW_DOC: - case JobEventDetails::NEW_PAGE: case JobEventDetails::PAGE_DONE: case JobEventDetails::DOC_DONE: { // Don't care about the actual printing process.
diff --git a/chrome/browser/printing/printing_layout_browsertest.cc b/chrome/browser/printing/printing_layout_browsertest.cc index 3ac9b9bb..ce02d320 100644 --- a/chrome/browser/printing/printing_layout_browsertest.cc +++ b/chrome/browser/printing/printing_layout_browsertest.cc
@@ -98,7 +98,6 @@ case printing::JobEventDetails::NEW_DOC: case printing::JobEventDetails::USER_INIT_DONE: case printing::JobEventDetails::DEFAULT_INIT_DONE: - case printing::JobEventDetails::NEW_PAGE: case printing::JobEventDetails::PAGE_DONE: case printing::JobEventDetails::DOC_DONE: case printing::JobEventDetails::ALL_PAGES_REQUESTED: {
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc index ffe884f..6ef2a78 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.cc +++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -31,7 +31,6 @@ #include "chrome/browser/download/download_core_service_factory.h" #include "chrome/browser/io_thread.h" #include "chrome/browser/net/chrome_url_request_context_getter.h" -#include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/permissions/permission_manager.h" #include "chrome/browser/permissions/permission_manager_factory.h" #include "chrome/browser/plugins/chrome_plugin_service_filter.h" @@ -53,7 +52,6 @@ #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" #include "components/prefs/json_pref_store.h" -#include "components/proxy_config/pref_proxy_config_tracker.h" #include "components/sync_preferences/pref_service_syncable.h" #include "components/user_prefs/user_prefs.h" #include "content/public/browser/browser_thread.h" @@ -73,7 +71,6 @@ #if defined(OS_ANDROID) #include "components/prefs/scoped_user_pref_update.h" -#include "components/proxy_config/proxy_prefs.h" #else // !defined(OS_ANDROID) #include "chrome/browser/ui/zoom/chrome_zoom_level_otr_delegate.h" #include "components/zoom/zoom_event_manager.h" @@ -223,9 +220,6 @@ base::BindOnce(&NotifyOTRProfileDestroyedOnIOThread, profile_, this)); #endif - if (pref_proxy_config_tracker_) - pref_proxy_config_tracker_->DetachFromPrefService(); - // Clears any data the network stack contains that may be related to the // OTR session. g_browser_process->io_thread()->ChangedToOnTheRecord(); @@ -527,12 +521,6 @@ } #endif // defined(OS_CHROMEOS) -PrefProxyConfigTracker* OffTheRecordProfileImpl::GetProxyConfigTracker() { - if (!pref_proxy_config_tracker_) - pref_proxy_config_tracker_.reset(CreateProxyConfigTracker()); - return pref_proxy_config_tracker_.get(); -} - chrome_browser_net::Predictor* OffTheRecordProfileImpl::GetNetworkPredictor() { // We do not store information about websites visited in OTR profiles which // is necessary for a Predictor, so we do not have a Predictor at all. @@ -610,14 +598,3 @@ ->OnDefaultZoomLevelChanged(); } #endif // !defined(OS_ANDROID) - -PrefProxyConfigTracker* OffTheRecordProfileImpl::CreateProxyConfigTracker() { -#if defined(OS_CHROMEOS) - if (chromeos::ProfileHelper::IsSigninProfile(this)) { - return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( - g_browser_process->local_state()); - } -#endif // defined(OS_CHROMEOS) - return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile( - GetPrefs(), g_browser_process->local_state()); -}
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h index 93a5931..60816549 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.h +++ b/chrome/browser/profiles/off_the_record_profile_impl.h
@@ -88,8 +88,6 @@ void InitChromeOSPreferences() override; #endif // defined(OS_CHROMEOS) - PrefProxyConfigTracker* GetProxyConfigTracker() override; - chrome_browser_net::Predictor* GetNetworkPredictor() override; GURL GetHomePage() override; @@ -122,11 +120,6 @@ void TrackZoomLevelsFromParent(); #endif // !defined(OS_ANDROID) -#if defined(OS_ANDROID) - void UseSystemProxy(); -#endif // defined(OS_ANDROID) - - PrefProxyConfigTracker* CreateProxyConfigTracker(); #if !defined(OS_ANDROID) // Callback function for tracking parent's zoom level changes. void OnParentZoomLevelChanged( @@ -151,8 +144,6 @@ base::FilePath last_selected_directory_; - std::unique_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; - DISALLOW_COPY_AND_ASSIGN(OffTheRecordProfileImpl); };
diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h index 1cd9fe03..255c865 100644 --- a/chrome/browser/profiles/profile.h +++ b/chrome/browser/profiles/profile.h
@@ -23,7 +23,6 @@ #endif class ExtensionSpecialStoragePolicy; -class PrefProxyConfigTracker; class PrefService; class TestingProfile; @@ -251,10 +250,6 @@ virtual void InitChromeOSPreferences() = 0; #endif // defined(OS_CHROMEOS) - // Returns the helper object that provides the proxy configuration service - // access to the the proxy configuration possibly defined by preferences. - virtual PrefProxyConfigTracker* GetProxyConfigTracker() = 0; - // Returns the Predictor object used for dns prefetch. virtual chrome_browser_net::Predictor* GetNetworkPredictor() = 0;
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 1dba4b4..5e6ae44 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -53,7 +53,6 @@ #include "chrome/browser/download/download_core_service_factory.h" #include "chrome/browser/media/media_device_id_salt.h" #include "chrome/browser/net/predictor.h" -#include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/permissions/permission_manager.h" #include "chrome/browser/permissions/permission_manager_factory.h" #include "chrome/browser/plugins/chrome_plugin_service_filter.h" @@ -108,7 +107,6 @@ #include "components/policy/core/browser/browser_policy_connector.h" #include "components/pref_registry/pref_registry_syncable.h" #include "components/prefs/scoped_user_pref_update.h" -#include "components/proxy_config/pref_proxy_config_tracker.h" #include "components/signin/core/browser/signin_manager.h" #include "components/signin/core/browser/signin_pref_names.h" #include "components/ssl_config/ssl_config_service_manager.h" @@ -749,9 +747,6 @@ BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices( this); - if (pref_proxy_config_tracker_) - pref_proxy_config_tracker_->DetachFromPrefService(); - // This causes the Preferences file to be written to disk. if (prefs_loaded) SetExitType(EXIT_NORMAL); @@ -1252,12 +1247,6 @@ #endif // defined(OS_CHROMEOS) -PrefProxyConfigTracker* ProfileImpl::GetProxyConfigTracker() { - if (!pref_proxy_config_tracker_) - pref_proxy_config_tracker_.reset(CreateProxyConfigTracker()); - return pref_proxy_config_tracker_.get(); -} - chrome_browser_net::Predictor* ProfileImpl::GetNetworkPredictor() { return predictor_; } @@ -1352,17 +1341,6 @@ *max_size = prefs_->GetInteger(prefs::kMediaCacheSize); } -PrefProxyConfigTracker* ProfileImpl::CreateProxyConfigTracker() { -#if defined(OS_CHROMEOS) - if (chromeos::ProfileHelper::IsSigninProfile(this)) { - return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfLocalState( - g_browser_process->local_state()); - } -#endif // defined(OS_CHROMEOS) - return ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile( - GetPrefs(), g_browser_process->local_state()); -} - std::unique_ptr<domain_reliability::DomainReliabilityMonitor> ProfileImpl::CreateDomainReliabilityMonitor(PrefService* local_state) { domain_reliability::DomainReliabilityService* service =
diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index 22759afcd..025ad0a 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h
@@ -150,8 +150,6 @@ void InitChromeOSPreferences() override; #endif // defined(OS_CHROMEOS) - PrefProxyConfigTracker* GetProxyConfigTracker() override; - private: #if defined(OS_CHROMEOS) friend class chromeos::KioskTest; @@ -193,8 +191,6 @@ void GetMediaCacheParameters(base::FilePath* cache_path, int* max_size); - PrefProxyConfigTracker* CreateProxyConfigTracker(); - std::unique_ptr<domain_reliability::DomainReliabilityMonitor> CreateDomainReliabilityMonitor(PrefService* local_state); @@ -262,8 +258,6 @@ std::unique_ptr<chromeos::LocaleChangeGuard> locale_change_guard_; #endif - std::unique_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; - // TODO(mmenke): This should be removed from the Profile, and use a // BrowserContextKeyedService instead. // See https://crbug.com/713733
diff --git a/chrome/browser/profiles/profile_io_data.cc b/chrome/browser/profiles/profile_io_data.cc index 07ca9b0..f03c54f3 100644 --- a/chrome/browser/profiles/profile_io_data.cc +++ b/chrome/browser/profiles/profile_io_data.cc
@@ -39,7 +39,6 @@ #include "chrome/browser/net/loading_predictor_observer.h" #include "chrome/browser/net/profile_network_context_service.h" #include "chrome/browser/net/profile_network_context_service_factory.h" -#include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/policy/cloud/policy_header_service_factory.h" #include "chrome/browser/policy/policy_helpers.h" #include "chrome/browser/predictors/loading_predictor.h" @@ -80,6 +79,7 @@ #include "content/public/browser/notification_service.h" #include "content/public/browser/resource_context.h" #include "content/public/common/content_switches.h" +#include "content/public/common/proxy_config_traits.h" #include "content/public/network/ignore_errors_cert_verifier.h" #include "content/public/network/url_request_context_builder_mojo.h" #include "extensions/features/features.h" @@ -97,9 +97,6 @@ #include "net/http/transport_security_persister.h" #include "net/net_features.h" #include "net/nqe/network_quality_estimator.h" -#include "net/proxy/proxy_config_service_fixed.h" -#include "net/proxy/proxy_script_fetcher_impl.h" -#include "net/proxy/proxy_service.h" #include "net/reporting/reporting_service.h" #include "net/ssl/channel_id_service.h" #include "net/ssl/client_cert_store.h" @@ -465,8 +462,6 @@ } #endif - params->proxy_config_service = ProxyServiceFactory::CreateProxyConfigService( - profile->GetProxyConfigTracker()); #if defined(OS_CHROMEOS) user_manager::UserManager* user_manager = user_manager::UserManager::Get(); if (user_manager) { @@ -1107,8 +1102,7 @@ builder->set_shared_http_auth_handler_factory( io_thread_globals->system_request_context->http_auth_handler_factory()); - io_thread->SetUpProxyConfigService( - builder.get(), std::move(profile_params_->proxy_config_service)); + io_thread->SetUpProxyService(builder.get()); builder->set_network_delegate(std::move(network_delegate));
diff --git a/chrome/browser/profiles/profile_io_data.h b/chrome/browser/profiles/profile_io_data.h index 32807e7..86ced5e0 100644 --- a/chrome/browser/profiles/profile_io_data.h +++ b/chrome/browser/profiles/profile_io_data.h
@@ -82,7 +82,6 @@ class ClientCertStore; class CookieStore; class HttpTransactionFactory; -class ProxyConfigService; class ReportingService; class ReportSender; class SSLConfigService; @@ -341,11 +340,6 @@ // and then passed to the list of request_interceptors on the IO thread. std::unique_ptr<net::URLRequestInterceptor> new_tab_page_interceptor; - // We need to initialize the ProxyConfigService from the UI thread - // because on linux it relies on initializing things through gconf, - // and needs to be on the main thread. - std::unique_ptr<net::ProxyConfigService> proxy_config_service; - #if defined(OS_CHROMEOS) std::unique_ptr<policy::PolicyCertVerifier> policy_cert_verifier; std::string username_hash;
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 c7892f5..4054234c4 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/background_test.extjs
@@ -1312,3 +1312,33 @@ .replay(); }); }); + +TEST_F('BackgroundTest', 'NodeVsSubnode', function() { + var mockFeedback = this.createMockFeedback(); + this.runWithLoadedTree(function(root) {/*! + <a href="#">test</a> + */}, function(root) { + var link = root.find({role: RoleType.LINK}); + function outputLinkRange(start, end) { + return function() { + new Output().withSpeech(new cursors.Range(new cursors.Cursor(link, start), + new cursors.Cursor(link, end))).go(); + }; + } + + mockFeedback.call(outputLinkRange(0, 0)) + .expectSpeech('test', 'Link') + .call(outputLinkRange(0, 1)) + .expectSpeech('t') + .call(outputLinkRange(1, 1)) + .expectSpeech('test', 'Link') + .call(outputLinkRange(1, 2)) + .expectSpeech('e') + .call(outputLinkRange(1, 3)) + .expectNextSpeechUtteranceIsNot('Link') + .expectSpeech('es') + .call(outputLinkRange(0, 4)) + .expectSpeech('test', 'Link') + .replay(); + }); +});
diff --git a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js index edb1d3f7..58ec5483e 100644 --- a/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js +++ b/chrome/browser/resources/chromeos/chromevox/cvox2/background/cursors.js
@@ -666,12 +666,15 @@ }, /** - * Returns true if this range covers a single node's text content or less. + * Returns true if this range covers less than a node. * @return {boolean} */ isSubNode: function() { - return this.start.node === this.end.node && this.start.index > -1 && - this.end.index > -1; + var startIndex = this.start.index; + var endIndex = this.end.index; + return this.start.node === this.end.node && startIndex != -1 && + endIndex != -1 && startIndex != endIndex && + (startIndex != 0 || endIndex != this.start.getText().length); }, /**
diff --git a/chrome/browser/resources/print_preview/new/app.html b/chrome/browser/resources/print_preview/new/app.html index bde13b1..83bdf21 100644 --- a/chrome/browser/resources/print_preview/new/app.html +++ b/chrome/browser/resources/print_preview/new/app.html
@@ -82,7 +82,8 @@ document-info="[[documentInfo]]" hidden$="[[!settings.scaling.available]]"> </print-preview-scaling-settings> - <print-preview-other-options-settings settings="{{settings}}"> + <print-preview-other-options-settings settings="{{settings}}" + hidden$="[[!settings.otherOptions.available]]"> </print-preview-other-options-settings> <print-preview-advanced-options-settings settings="{{settings}}" hidden$="[[!settings.vendorItems.available]]">
diff --git a/chrome/browser/resources/print_preview/new/model.js b/chrome/browser/resources/print_preview/new/model.js index 2925555..ee102c1 100644 --- a/chrome/browser/resources/print_preview/new/model.js +++ b/chrome/browser/resources/print_preview/new/model.js
@@ -49,6 +49,7 @@ * headerFooter: !print_preview_new.Setting, * rasterize: !print_preview_new.Setting, * vendorItems: !print_preview_new.Setting, + * otherOptions: !print_preview_new.Setting, * }} */ settings: { @@ -154,6 +155,14 @@ available: true, updatesPreview: false, }, + // This does not represent a real setting value, and is used only to + // expose the availability of the other options settings section. + otherOptions: { + value: null, + valid: true, + available: true, + updatesPreview: false, + }, }, }, @@ -301,7 +310,16 @@ 'settings.selectionOnly.available', this.documentInfo.isModifiable && this.documentInfo.hasSelection); this.set('settings.headerFooter.available', this.documentInfo.isModifiable); - this.set('settings.rasterize.available', !this.documentInfo.isModifiable); + this.set( + 'settings.rasterize.available', + !this.documentInfo.isModifiable && !cr.isWindows && !cr.isMac); + this.set( + 'settings.otherOptions.available', + this.settings.duplex.available || + this.settings.cssBackground.available || + this.settings.selectionOnly.available || + this.settings.headerFooter.available || + this.settings.rasterize.available); }, /** @param {?print_preview.CddCapabilities} caps The printer capabilities. */
diff --git a/chrome/browser/resources/print_preview/new/other_options_settings.html b/chrome/browser/resources/print_preview/new/other_options_settings.html index 71349530..f6397776 100644 --- a/chrome/browser/resources/print_preview/new/other_options_settings.html +++ b/chrome/browser/resources/print_preview/new/other_options_settings.html
@@ -11,31 +11,35 @@ <print-preview-settings-section class="multirow-controls"> <span slot="title" id="options-label">$i18n{optionsLabel}</span> <div slot="controls" class="checkbox"> - <div id="header-footer-container"> + <div id="header-footer-container" + hidden$="[[!settings.headerFooter.available]]"> <label aria-live="polite"> <input type="checkbox"> <span>$i18n{optionHeaderFooter}</span> </label> </div> - <div id="duplex-container"> + <div id="duplex-container" hidden$="[[!settings.duplex.available]]"> <label aria-live="polite"> <input type="checkbox" checked="{{duplexValue_::change}}"> <span>$i18n{optionTwoSided}</span> </label> </div> - <div id="css-background-container"> + <div id="css-background-container" + hidden$="[[!settings.cssBackground.available]]"> <label aria-live="polite"> <input type="checkbox"> <span>$i18n{optionBackgroundColorsAndImages}</span> </label> </div> - <div id="rasterize-container"> + <div id="rasterize-container" + hidden$="[[!settings.rasterize.available]]"> <label aria-live="polite"> <input type="checkbox"> <span>$i18n{optionRasterize}</span> </label> </div> - <div id="selection-only-container"> + <div id="selection-only-container" + hidden$="[[!settings.selectionOnly.available]]"> <label aria-live="polite"> <input type="checkbox"> <span>$i18n{optionSelectionOnly}</span>
diff --git a/chrome/browser/sync/test/integration/sync_arc_package_helper.cc b/chrome/browser/sync/test/integration/sync_arc_package_helper.cc index 18c5240..4bce447 100644 --- a/chrome/browser/sync/test/integration/sync_arc_package_helper.cc +++ b/chrome/browser/sync/test/integration/sync_arc_package_helper.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service.h" #include "chromeos/chromeos_switches.h" #include "components/arc/connection_holder.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_app_instance.h" namespace arc { @@ -130,6 +131,7 @@ arc_app_list_prefs->app_connection_holder()->SetInstance(nullptr); arc_app_list_prefs->app_connection_holder()->SetInstance( instance_map_[profile].get()); + WaitForInstanceReady(arc_app_list_prefs->app_connection_holder()); // OnPackageListRefreshed will be called when AppInstance is ready. // For fakeAppInstance we use SendRefreshPackageList to make sure that // OnPackageListRefreshed will be called.
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 26a7a14..290e389d 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -685,6 +685,8 @@ "apps/chrome_app_window_client.h", "apps/directory_access_confirmation_dialog.cc", "apps/directory_access_confirmation_dialog.h", + "blocked_content/framebust_block_tab_helper.cc", + "blocked_content/framebust_block_tab_helper.h", "blocked_content/popunder_preventer.cc", "blocked_content/popunder_preventer.h", "bluetooth/bluetooth_chooser_controller.cc",
diff --git a/chrome/browser/ui/app_list/arc/arc_app_test.cc b/chrome/browser/ui/app_list/arc/arc_app_test.cc index ee475f0..2917de0a 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_test.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_test.cc
@@ -22,6 +22,7 @@ #include "components/arc/arc_service_manager.h" #include "components/arc/arc_session_runner.h" #include "components/arc/arc_util.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_app_instance.h" #include "components/arc/test/fake_arc_session.h" #include "components/user_manager/scoped_user_manager.h" @@ -113,6 +114,7 @@ app_instance_.reset(new arc::FakeAppInstance(arc_app_list_pref_)); arc_service_manager_->arc_bridge_service()->app()->SetInstance( app_instance_.get()); + WaitForInstanceReady(arc_service_manager_->arc_bridge_service()->app()); } void ArcAppTest::WaitForDefaultApps() { @@ -206,6 +208,7 @@ bridge_service->app()->SetInstance(nullptr); app_instance_ = base::MakeUnique<arc::FakeAppInstance>(arc_app_list_pref_); bridge_service->app()->SetInstance(app_instance_.get()); + WaitForInstanceReady(bridge_service->app()); } const user_manager::User* ArcAppTest::CreateUserAndLogin() {
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc index 46411ae..e3b94b57 100644 --- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc +++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -1946,7 +1946,6 @@ display::kInvalidDisplayId); EXPECT_FALSE(launcher1.app_launched()); - EXPECT_FALSE(launcher2.app_launched()); arc_test()->WaitForDefaultApps();
diff --git a/chrome/browser/ui/app_list/test/fake_profile.cc b/chrome/browser/ui/app_list/test/fake_profile.cc index f56f04d..98392a6 100644 --- a/chrome/browser/ui/app_list/test/fake_profile.cc +++ b/chrome/browser/ui/app_list/test/fake_profile.cc
@@ -186,10 +186,6 @@ void FakeProfile::OnLogin() {} void FakeProfile::InitChromeOSPreferences() {} -PrefProxyConfigTracker* FakeProfile::GetProxyConfigTracker() { - return nullptr; -} - chrome_browser_net::Predictor* FakeProfile::GetNetworkPredictor() { return nullptr; }
diff --git a/chrome/browser/ui/app_list/test/fake_profile.h b/chrome/browser/ui/app_list/test/fake_profile.h index 08b1847..6933a603 100644 --- a/chrome/browser/ui/app_list/test/fake_profile.h +++ b/chrome/browser/ui/app_list/test/fake_profile.h
@@ -86,7 +86,6 @@ void OnLogin() override; void InitChromeOSPreferences() override; - PrefProxyConfigTracker* GetProxyConfigTracker() override; chrome_browser_net::Predictor* GetNetworkPredictor() override; GURL GetHomePage() override; bool WasCreatedByVersionOrLater(const std::string& version) override;
diff --git a/chrome/browser/ui/blocked_content/framebust_block_tab_helper.cc b/chrome/browser/ui/blocked_content/framebust_block_tab_helper.cc new file mode 100644 index 0000000..7a4dcac6 --- /dev/null +++ b/chrome/browser/ui/blocked_content/framebust_block_tab_helper.cc
@@ -0,0 +1,44 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" + +#include "base/logging.h" + +DEFINE_WEB_CONTENTS_USER_DATA_KEY(FramebustBlockTabHelper); + +FramebustBlockTabHelper::~FramebustBlockTabHelper() = default; + +// static +void FramebustBlockTabHelper::AddBlockedUrl(const GURL& blocked_url) { + blocked_urls_.push_back(blocked_url); + + if (observer_) + observer_->OnBlockedUrlAdded(blocked_url); +} + +bool FramebustBlockTabHelper::HasBlockedUrls() const { + return !blocked_urls_.empty(); +} + +void FramebustBlockTabHelper::OnBlockedUrlClicked(size_t index) { + web_contents_->OpenURL(content::OpenURLParams( + blocked_urls_[index], content::Referrer(), + WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_LINK, false)); + blocked_urls_.clear(); +} + +void FramebustBlockTabHelper::SetObserver(Observer* observer) { + DCHECK(!observer_); + observer_ = observer; +} + +void FramebustBlockTabHelper::ClearObserver() { + DCHECK(observer_); + observer_ = nullptr; +} + +FramebustBlockTabHelper::FramebustBlockTabHelper( + content::WebContents* web_contents) + : web_contents_(web_contents) {}
diff --git a/chrome/browser/ui/blocked_content/framebust_block_tab_helper.h b/chrome/browser/ui/blocked_content/framebust_block_tab_helper.h new file mode 100644 index 0000000..ae47410 --- /dev/null +++ b/chrome/browser/ui/blocked_content/framebust_block_tab_helper.h
@@ -0,0 +1,74 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_BLOCKED_CONTENT_FRAMEBUST_BLOCK_TAB_HELPER_H_ +#define CHROME_BROWSER_UI_BLOCKED_CONTENT_FRAMEBUST_BLOCK_TAB_HELPER_H_ + +#include <vector> + +#include "base/macros.h" +#include "content/public/browser/web_contents_user_data.h" +#include "url/gurl.h" + +// A tab helper that keeps track of blocked Framebusts that happened on each +// page. Only used for the desktop version of the blocked Framebust UI. +class FramebustBlockTabHelper + : public content::WebContentsUserData<FramebustBlockTabHelper> { + public: + // There is expected to be at most one observer at a time. + class Observer { + public: + // Called whenever a new URL was blocked. + virtual void OnBlockedUrlAdded(const GURL& blocked_url) = 0; + + protected: + virtual ~Observer() = default; + }; + + ~FramebustBlockTabHelper() override; + + // Shows the blocked Framebust icon in the Omnibox for the |blocked_url|. + // If the icon is already visible, that URL is instead added to the vector of + // currently blocked URLs and the bubble view is updated. + void AddBlockedUrl(const GURL& blocked_url); + + // Returns true if at least one Framebust was blocked on this page. + bool HasBlockedUrls() const; + + // Handles navigating to the blocked URL specified by |index| and clearing the + // vector of blocked URLs. + void OnBlockedUrlClicked(size_t index); + + // Sets and clears the current observer. + void SetObserver(Observer* observer); + void ClearObserver(); + + // Returns all of the currently blocked URLs. + const std::vector<GURL>& blocked_urls() const { return blocked_urls_; } + + // Remembers if the animation has run. + void set_animation_has_run() { animation_has_run_ = true; } + bool animation_has_run() const { return animation_has_run_; } + + private: + friend class content::WebContentsUserData<FramebustBlockTabHelper>; + + explicit FramebustBlockTabHelper(content::WebContents* web_contents); + + content::WebContents* web_contents_; + + // Remembers all the currently blocked URLs. This is cleared on each + // navigation. + std::vector<GURL> blocked_urls_; + + // Remembers if the animation has run. + bool animation_has_run_ = false; + + // Points to the unique observer of this class. + Observer* observer_ = nullptr; + + DISALLOW_COPY_AND_ASSIGN(FramebustBlockTabHelper); +}; + +#endif // CHROME_BROWSER_UI_BLOCKED_CONTENT_FRAMEBUST_BLOCK_TAB_HELPER_H_
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 0fc32db..4a247ecb 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -89,6 +89,7 @@ #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/translate/chrome_translate_client.h" #include "chrome/browser/ui/autofill/chrome_autofill_client.h" +#include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" #include "chrome/browser/ui/blocked_content/popup_blocker_tab_helper.h" #include "chrome/browser/ui/blocked_content/popup_tracker.h" #include "chrome/browser/ui/bluetooth/bluetooth_chooser_controller.h" @@ -1399,6 +1400,14 @@ sound_content_setting_observer->OnAudioStateChanged(is_audible); } +void Browser::OnDidBlockFramebust(content::WebContents* web_contents, + const GURL& url) { + TabSpecificContentSettings* content_settings = + TabSpecificContentSettings::FromWebContents(web_contents); + DCHECK(content_settings); + content_settings->OnFramebustBlocked(url); +} + bool Browser::IsMouseLocked() const { return exclusive_access_manager_->mouse_lock_controller()->IsMouseLocked(); }
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index fa3047d..3b0c514 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -487,6 +487,8 @@ const GURL& resource_url) override; void OnAudioStateChanged(content::WebContents* web_contents, bool is_audible) override; + void OnDidBlockFramebust(content::WebContents* web_contents, + const GURL& url) override; bool is_type_tabbed() const { return type_ == TYPE_TABBED; } bool is_type_popup() const { return type_ == TYPE_POPUP; }
diff --git a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_browsertest.mm b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_browsertest.mm index 73d4f45..35b7eddc 100644 --- a/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_browsertest.mm +++ b/chrome/browser/ui/cocoa/content_settings/content_setting_bubble_cocoa_browsertest.mm
@@ -105,6 +105,12 @@ for (const auto& model : models) { ContentSettingBubbleModel* bubble = model->CreateBubbleModel(nullptr, web_contents(), profile()); + + // Skip this test for the ContentSettingFramebustBlockBubbleModel, which + // doesn't have a Cocoa version. + if (bubble->AsFramebustBlockBubbleModel()) + continue; + ContentSettingBubbleController* controller = CreateBubbleController(bubble); // No bubble except the one for media should have media menus. if (!bubble->AsMediaStreamBubbleModel())
diff --git a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm index 032edcf..6ba07af5 100644 --- a/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm +++ b/chrome/browser/ui/cocoa/location_bar/content_setting_decoration.mm
@@ -299,7 +299,9 @@ return true; } - if (chrome::ShowAllDialogsWithViewsToolkit()) { + // The blocked Framebust bubble only has a toolkit-views implementation. + if (chrome::ShowAllDialogsWithViewsToolkit() || + model->AsFramebustBlockBubbleModel()) { gfx::Point origin = gfx::ScreenPointFromNSPoint(anchor); NSWindow* bubble = chrome::ContentSettingBubbleViewsBridge::Show( [web_contents->GetTopLevelNativeWindow() contentView], model,
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc index 1440dea..7d7775c 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -38,6 +38,7 @@ #include "chrome/common/insecure_content_renderer.mojom.h" #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" +#include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" #include "components/content_settings/core/browser/content_settings_utils.h" @@ -1588,6 +1589,88 @@ CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS); } +// ContentSettingFramebustBlockBubbleModel ------------------------------------- + +ContentSettingFramebustBlockBubbleModel:: + ContentSettingFramebustBlockBubbleModel(Delegate* delegate, + WebContents* web_contents, + Profile* profile) + : ContentSettingBubbleModel(delegate, web_contents, profile) { + if (!web_contents) + return; + + set_manage_text_style(ContentSettingBubbleModel::ManageTextStyle::kNone); + set_show_learn_more(false); + set_title(l10n_util::GetStringUTF16(IDS_REDIRECT_BLOCKED_MESSAGE)); + set_done_button_text(l10n_util::GetStringUTF16(IDS_OK)); + + auto* helper = FramebustBlockTabHelper::FromWebContents(web_contents); + + // Build the blocked urls list. + for (const auto& blocked_url : helper->blocked_urls()) + AddListItem(CreateListItem(blocked_url)); + + helper->SetObserver(this); +} + +ContentSettingFramebustBlockBubbleModel:: + ~ContentSettingFramebustBlockBubbleModel() { + if (web_contents()) + FramebustBlockTabHelper::FromWebContents(web_contents())->ClearObserver(); +} + +void ContentSettingFramebustBlockBubbleModel::Observe( + int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) { + // The order is important because ContentSettingBubbleModel::Observer() clears + // the value of |web_contents()|. + if (type == content::NOTIFICATION_WEB_CONTENTS_DESTROYED) + FramebustBlockTabHelper::FromWebContents(web_contents())->ClearObserver(); + ContentSettingBubbleModel::Observe(type, source, details); +} + +void ContentSettingFramebustBlockBubbleModel::OnListItemClicked( + int index, + int event_flags) { + if (!web_contents()) + return; + + FramebustBlockTabHelper::FromWebContents(web_contents()) + ->OnBlockedUrlClicked(index); +} + +ContentSettingFramebustBlockBubbleModel* +ContentSettingFramebustBlockBubbleModel::AsFramebustBlockBubbleModel() { + return this; +} + +void ContentSettingFramebustBlockBubbleModel::OnBlockedUrlAdded( + const GURL& blocked_url) { + AddListItem(CreateListItem(blocked_url)); +} + +ContentSettingBubbleModel::ListItem +ContentSettingFramebustBlockBubbleModel::CreateListItem(const GURL& url) { + // Skip empty URLS. + base::string16 title = !url.spec().empty() + ? base::UTF8ToUTF16(url.spec()) + : l10n_util::GetStringUTF16(IDS_TAB_LOADING_TITLE); + + const bool use_md = ui::MaterialDesignController::IsSecondaryUiMaterial(); + if (use_md) { + // Format the title to include the unicode single dot bullet code-point + // \u2022 and two spaces. + title = l10n_util::GetStringFUTF16(IDS_LIST_BULLET, title); + } + + gfx::Image image = + use_md ? gfx::Image() + : ui::ResourceBundle::GetSharedInstance().GetImageNamed( + IDR_DEFAULT_FAVICON); + return ListItem(image, title, true, 0); +} + // ContentSettingBubbleModel --------------------------------------------------- // static @@ -1716,6 +1799,11 @@ return nullptr; } +ContentSettingFramebustBlockBubbleModel* +ContentSettingBubbleModel::AsFramebustBlockBubbleModel() { + return nullptr; +} + void ContentSettingBubbleModel::AddListItem(const ListItem& item) { bubble_content_.list_items.push_back(item); if (owner_)
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.h b/chrome/browser/ui/content_settings/content_setting_bubble_model.h index debc711b..db94491c 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model.h +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.h
@@ -15,7 +15,9 @@ #include "base/compiler_specific.h" #include "base/macros.h" #include "base/strings/string16.h" +#include "build/build_config.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" +#include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" #include "chrome/common/custom_handlers/protocol_handler.h" #include "components/content_settings/core/common/content_settings.h" #include "components/content_settings/core/common/content_settings_types.h" @@ -52,12 +54,14 @@ // ContentSettingPopupBubbleModel - popups // ContentSettingSubresourceFilterBubbleModel - filtered subresources // ContentSettingDownloadsBubbleModel - automatic downloads +// ContentSettingFramebustBlockBubbleModel - blocked framebusts // Forward declaration necessary for downcasts. class ContentSettingMediaStreamBubbleModel; class ContentSettingSimpleBubbleModel; class ContentSettingSubresourceFilterBubbleModel; class ContentSettingDownloadsBubbleModel; +class ContentSettingFramebustBlockBubbleModel; // This model provides data for ContentSettingBubble, and also controls // the action triggered when the allow / block radio buttons are triggered. @@ -203,6 +207,10 @@ // Cast this bubble into ContentSettingDownloadsBubbleModel if possible. virtual ContentSettingDownloadsBubbleModel* AsDownloadsBubbleModel(); + // Cast this bubble into ContentSettingFramebustBlockBubbleModel if possible. + virtual ContentSettingFramebustBlockBubbleModel* + AsFramebustBlockBubbleModel(); + // Sets the Rappor service used for testing. void SetRapporServiceImplForTesting( rappor::RapporServiceImpl* rappor_service) { @@ -443,4 +451,36 @@ DISALLOW_COPY_AND_ASSIGN(ContentSettingDownloadsBubbleModel); }; +#if !defined(OS_ANDROID) +// The model for the blocked Framebust bubble. +class ContentSettingFramebustBlockBubbleModel + : public ContentSettingBubbleModel, + public FramebustBlockTabHelper::Observer { + public: + ContentSettingFramebustBlockBubbleModel(Delegate* delegate, + content::WebContents* web_contents, + Profile* profile); + + ~ContentSettingFramebustBlockBubbleModel() override; + + // content::NotificationObserver: + void Observe(int type, + const content::NotificationSource& source, + const content::NotificationDetails& details) override; + + // ContentSettingBubbleModel: + void OnListItemClicked(int index, int event_flags) override; + ContentSettingFramebustBlockBubbleModel* AsFramebustBlockBubbleModel() + override; + + // FramebustBlockTabHelper::Observer: + void OnBlockedUrlAdded(const GURL& blocked_url) override; + + private: + ListItem CreateListItem(const GURL& url); + + DISALLOW_COPY_AND_ASSIGN(ContentSettingFramebustBlockBubbleModel); +}; +#endif // !defined(OS_ANDROID) + #endif // CHROME_BROWSER_UI_CONTENT_SETTINGS_CONTENT_SETTING_BUBBLE_MODEL_H_
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.cc b/chrome/browser/ui/content_settings/content_setting_image_model.cc index f9944c0..fb39987f 100644 --- a/chrome/browser/ui/content_settings/content_setting_image_model.cc +++ b/chrome/browser/ui/content_settings/content_setting_image_model.cc
@@ -16,7 +16,9 @@ #include "chrome/browser/plugins/plugin_utils.h" #include "chrome/browser/prerender/prerender_manager.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" #include "chrome/common/chrome_features.h" +#include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/vector_icons/vector_icons.h" @@ -40,6 +42,7 @@ // ContentSettingDownloadsImageModel - automatic downloads // ContentSettingMediaImageModel - media // ContentSettingSubresourceFilterImageModel - deceptive content +// ContentSettingFramebustBlockImageModel - blocked framebust class ContentSettingBlockedImageModel : public ContentSettingSimpleImageModel { public: @@ -470,6 +473,51 @@ } } +// Blocked Framebust ----------------------------------------------------------- + +ContentSettingFramebustBlockImageModel::ContentSettingFramebustBlockImageModel() + : ContentSettingImageModel() {} + +void ContentSettingFramebustBlockImageModel::UpdateFromWebContents( + WebContents* web_contents) { + set_visible(false); + + if (!web_contents) + return; + + // Early exit if no blocked Framebust. + if (!FramebustBlockTabHelper::FromWebContents(web_contents)->HasBlockedUrls()) + return; + + set_icon(kBlockedRedirectIcon, kBlockedBadgeIcon); + set_explanatory_string_id(IDS_REDIRECT_BLOCKED_TITLE); + set_tooltip(l10n_util::GetStringUTF16(IDS_REDIRECT_BLOCKED_TOOLTIP)); + set_visible(true); +} + +ContentSettingBubbleModel* +ContentSettingFramebustBlockImageModel::CreateBubbleModel( + ContentSettingBubbleModel::Delegate* delegate, + WebContents* web_contents, + Profile* profile) { + return new ContentSettingFramebustBlockBubbleModel(delegate, web_contents, + profile); +} + +bool ContentSettingFramebustBlockImageModel::ShouldRunAnimation( + WebContents* web_contents) { + return web_contents && !FramebustBlockTabHelper::FromWebContents(web_contents) + ->animation_has_run(); +} + +void ContentSettingFramebustBlockImageModel::SetAnimationHasRun( + WebContents* web_contents) { + if (!web_contents) + return; + FramebustBlockTabHelper::FromWebContents(web_contents) + ->set_animation_has_run(); +} + // Protocol handlers ----------------------------------------------------------- ContentSettingRPHImageModel::ContentSettingRPHImageModel() @@ -612,6 +660,12 @@ } result.push_back(std::move(model)); } + + // The framebust blocking UI reuses the code for displaying an icon with + // ContentSettingImageModel and ContentSettingBubbleModel, even though + // framebust blocking is not a content setting. + result.push_back(base::MakeUnique<ContentSettingFramebustBlockImageModel>()); + return result; }
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.h b/chrome/browser/ui/content_settings/content_setting_image_model.h index 727d9c3..2b5e571f 100644 --- a/chrome/browser/ui/content_settings/content_setting_image_model.h +++ b/chrome/browser/ui/content_settings/content_setting_image_model.h
@@ -140,4 +140,22 @@ DISALLOW_COPY_AND_ASSIGN(ContentSettingSubresourceFilterImageModel); }; +class ContentSettingFramebustBlockImageModel : public ContentSettingImageModel { + public: + ContentSettingFramebustBlockImageModel(); + + void UpdateFromWebContents(content::WebContents* web_contents) override; + + ContentSettingBubbleModel* CreateBubbleModel( + ContentSettingBubbleModel::Delegate* delegate, + content::WebContents* web_contents, + Profile* profile) override; + + bool ShouldRunAnimation(content::WebContents* web_contents) override; + void SetAnimationHasRun(content::WebContents* web_contents) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ContentSettingFramebustBlockImageModel); +}; + #endif // CHROME_BROWSER_UI_CONTENT_SETTINGS_CONTENT_SETTING_IMAGE_MODEL_H_
diff --git a/chrome/browser/ui/content_settings/framebust_block_browsertest.cc b/chrome/browser/ui/content_settings/framebust_block_browsertest.cc new file mode 100644 index 0000000..e31dd911 --- /dev/null +++ b/chrome/browser/ui/content_settings/framebust_block_browsertest.cc
@@ -0,0 +1,54 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_content_setting_bubble_model_delegate.h" +#include "chrome/browser/ui/content_settings/content_setting_bubble_model.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "chrome/common/webui_url_constants.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "content/public/test/test_navigation_observer.h" +#include "ui/events/event_constants.h" +#include "url/gurl.h" + +class ContentSettingFramebustBlockBubbleModelTest + : public InProcessBrowserTest { + public: + content::WebContents* GetWebContents() { + return browser()->tab_strip_model()->GetActiveWebContents(); + } + + void WaitForNavigation() { + content::TestNavigationObserver observer(GetWebContents()); + observer.Wait(); + } +}; + +// Tests that clicking an item in the list of blocked URLs trigger a navigation +// to that URL. +IN_PROC_BROWSER_TEST_F(ContentSettingFramebustBlockBubbleModelTest, + AllowRedirection) { + const GURL blocked_urls[] = { + GURL(chrome::kChromeUIHistoryURL), GURL(chrome::kChromeUISettingsURL), + GURL(chrome::kChromeUIVersionURL), + }; + + // Signal that a blocked redirection happened. + auto* helper = FramebustBlockTabHelper::FromWebContents(GetWebContents()); + for (const GURL& url : blocked_urls) + helper->AddBlockedUrl(url); + EXPECT_TRUE(helper->HasBlockedUrls()); + + // Simulate clicking on the second blocked URL. + ContentSettingFramebustBlockBubbleModel framebust_block_bubble_model( + browser()->content_setting_bubble_model_delegate(), GetWebContents(), + browser()->profile()); + framebust_block_bubble_model.OnListItemClicked(/* index = */ 1, + ui::EF_LEFT_MOUSE_BUTTON); + WaitForNavigation(); + + EXPECT_FALSE(helper->HasBlockedUrls()); + EXPECT_EQ(blocked_urls[1], GetWebContents()->GetLastCommittedURL()); +}
diff --git a/chrome/browser/ui/passwords/destination_file_system.cc b/chrome/browser/ui/passwords/destination_file_system.cc index 0a14712..730d01f 100644 --- a/chrome/browser/ui/passwords/destination_file_system.cc +++ b/chrome/browser/ui/passwords/destination_file_system.cc
@@ -7,12 +7,27 @@ #include <utility> #include "base/files/file_util.h" +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "components/strings/grit/components_strings.h" +#include "ui/base/l10n/l10n_util.h" DestinationFileSystem::DestinationFileSystem(base::FilePath destination_path) : destination_path_(std::move(destination_path)) {} -bool DestinationFileSystem::Write(const std::string& data) { - return base::WriteFile(destination_path_, data.c_str(), data.size()); +base::string16 DestinationFileSystem::Write(const std::string& data) { + if (base::WriteFile(destination_path_, data.c_str(), data.size())) { + return base::string16(); + } else { +#if defined(OS_WIN) + base::string16 folder_name(destination_path_.DirName().BaseName().value()); +#else + base::string16 folder_name( + base::UTF8ToUTF16(destination_path_.DirName().BaseName().value())); +#endif + return l10n_util::GetStringFUTF16( + IDS_PASSWORD_MANAGER_EXPORT_TO_FILE_FAILED, std::move(folder_name)); + } } const base::FilePath& DestinationFileSystem::GetDestinationPathForTesting() {
diff --git a/chrome/browser/ui/passwords/destination_file_system.h b/chrome/browser/ui/passwords/destination_file_system.h index a6ea278..8ae9167 100644 --- a/chrome/browser/ui/passwords/destination_file_system.h +++ b/chrome/browser/ui/passwords/destination_file_system.h
@@ -17,7 +17,7 @@ ~DestinationFileSystem() override = default; // password_manager::Destination - bool Write(const std::string& data) override; + base::string16 Write(const std::string& data) override; // Get this instance's target. const base::FilePath& GetDestinationPathForTesting();
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 78fa05c..d6977ad 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -117,6 +117,10 @@ #include "components/zoom/zoom_controller.h" #endif // defined(OS_ANDROID) +#if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) +#include "chrome/browser/ui/blocked_content/framebust_block_tab_helper.h" +#endif + #if BUILDFLAG(ENABLE_OFFLINE_PAGES) #include "chrome/browser/offline_pages/offline_page_tab_helper.h" #include "chrome/browser/offline_pages/recent_tab_helper.h" @@ -280,6 +284,7 @@ extensions::ChromeExtensionWebContentsObserver::CreateForWebContents( web_contents); extensions::WebNavigationTabObserver::CreateForWebContents(web_contents); + FramebustBlockTabHelper::CreateForWebContents(web_contents); HungPluginTabHelper::CreateForWebContents(web_contents); JavaScriptDialogTabHelper::CreateForWebContents(web_contents); ManagePasswordsUIController::CreateForWebContents(web_contents);
diff --git a/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc b/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc index 609badf..bf1da98 100644 --- a/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/arc_app_dialog_view_browsertest.cc
@@ -21,6 +21,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "components/arc/arc_util.h" #include "components/arc/common/app.mojom.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_app_instance.h" #include "content/public/test/test_utils.h" @@ -62,6 +63,7 @@ app_instance_.reset(new arc::FakeAppInstance(arc_app_list_pref_)); arc_app_list_pref_->app_connection_holder()->SetInstance( app_instance_.get()); + WaitForInstanceReady(arc_app_list_pref_->app_connection_holder()); // In this setup, we have one app and one shortcut which share one package. mojom::AppInfo app; @@ -88,6 +90,8 @@ } void TearDownOnMainThread() override { + arc_app_list_pref_->app_connection_holder()->SetInstance(nullptr); + app_instance_.reset(); ArcSessionManager::Get()->Shutdown(); }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index df8ef2b..766633a 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -1726,7 +1726,6 @@ } } - button->SetMinSize(gfx::Size()); button->set_context_menu_controller(this); button->set_drag_controller(this); if (node->is_url()) {
diff --git a/chrome/browser/ui/views/page_info/permission_selector_row.cc b/chrome/browser/ui/views/page_info/permission_selector_row.cc index 2fba9b4..6d41fc87 100644 --- a/chrome/browser/ui/views/page_info/permission_selector_row.cc +++ b/chrome/browser/ui/views/page_info/permission_selector_row.cc
@@ -400,14 +400,12 @@ // Update the menu button text to reflect the new setting. if (menu_button_) { - menu_button_->SetText(PageInfoUI::PermissionActionToUIString( - profile_, permission.type, permission.setting, - permission.default_setting, content_settings::SETTING_SOURCE_USER)); - menu_button_->SizeToPreferredSize(); // Re-layout will be done at the |PageInfoBubbleView| level, since // that view may need to resize itself to accomodate the new sizes of its // contents. - menu_button_->InvalidateLayout(); + menu_button_->SetText(PageInfoUI::PermissionActionToUIString( + profile_, permission.type, permission.setting, + permission.default_setting, content_settings::SETTING_SOURCE_USER)); } else if (combobox_) { bool use_default = permission.setting == CONTENT_SETTING_DEFAULT; combobox_->UpdateSelectedIndex(use_default);
diff --git a/chrome/browser/ui/views/profiles/avatar_button.cc b/chrome/browser/ui/views/profiles/avatar_button.cc index cb4ba02f..2de5f57 100644 --- a/chrome/browser/ui/views/profiles/avatar_button.cc +++ b/chrome/browser/ui/views/profiles/avatar_button.cc
@@ -449,9 +449,6 @@ : gfx::ShadowValues( 10, gfx::ShadowValue(gfx::Vector2d(), 2.0f, SK_ColorDKGRAY))); - // We want the button to resize if the new text is shorter. - SetMinSize(gfx::Size()); - if (use_generic_button) { SetImage(views::Button::STATE_NORMAL, generic_avatar_); } else if (error_controller_.HasAvatarError()) {
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc index 421f6955..38ebd8d59 100644 --- a/chrome/browser/ui/views/translate/translate_bubble_view.cc +++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -971,28 +971,15 @@ } void TranslateBubbleView::UpdateAdvancedView() { - DCHECK(source_language_combobox_); - DCHECK(target_language_combobox_); - DCHECK(advanced_done_button_); - - base::string16 source_language_name = - model_->GetLanguageNameAt(model_->GetOriginalLanguageIndex()); - base::string16 target_language_name = - model_->GetLanguageNameAt(model_->GetTargetLanguageIndex()); - // "Always translate" checkbox doesn't exist in an incognito window. if (advanced_always_translate_checkbox_) { advanced_always_translate_checkbox_->SetText( l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS)); } - base::string16 label; - if (model_->IsPageTranslatedInCurrentLanguages()) - label = l10n_util::GetStringUTF16(IDS_DONE); - else - label = l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ACCEPT); - advanced_done_button_->SetText(label); - advanced_done_button_->SizeToPreferredSize(); - if (advanced_view_) - advanced_view_->Layout(); + DCHECK(advanced_done_button_); + advanced_done_button_->SetText( + l10n_util::GetStringUTF16(model_->IsPageTranslatedInCurrentLanguages() + ? IDS_DONE + : IDS_TRANSLATE_BUBBLE_ACCEPT)); }
diff --git a/chrome/browser/vr/BUILD.gn b/chrome/browser/vr/BUILD.gn index e385d48..5927cd3 100644 --- a/chrome/browser/vr/BUILD.gn +++ b/chrome/browser/vr/BUILD.gn
@@ -153,12 +153,16 @@ "renderers/textured_quad_renderer.h", "renderers/web_vr_renderer.cc", "renderers/web_vr_renderer.h", + "sample_queue.cc", + "sample_queue.h", "service/vr_device_manager.cc", "service/vr_device_manager.h", "service/vr_display_host.cc", "service/vr_display_host.h", "service/vr_service_impl.cc", "service/vr_service_impl.h", + "sliding_average.cc", + "sliding_average.h", "speech_recognizer.cc", "speech_recognizer.h", "target_property.cc", @@ -245,6 +249,7 @@ "gltf_parser_unittest.cc", "pose_util_unittest.cc", "service/vr_device_manager_unittest.cc", + "sliding_average_unittest.cc", "speech_recognizer_unittest.cc", "test/fake_ui_element_renderer.cc", "test/fake_ui_element_renderer.h",
diff --git a/chrome/browser/vr/elements/suggestion.cc b/chrome/browser/vr/elements/suggestion.cc index 625f4095..9d82fc4 100644 --- a/chrome/browser/vr/elements/suggestion.cc +++ b/chrome/browser/vr/elements/suggestion.cc
@@ -9,8 +9,7 @@ namespace vr { Suggestion::Suggestion(base::Callback<void(GURL)> navigate_callback) - : LinearLayout(LinearLayout::kRight), - navigate_callback_(navigate_callback) { + : navigate_callback_(navigate_callback) { EventHandlers event_handlers; event_handlers.button_up = base::Bind(&Suggestion::HandleButtonClick, base::Unretained(this));
diff --git a/chrome/browser/vr/elements/suggestion.h b/chrome/browser/vr/elements/suggestion.h index 570de22..fd5c7b9 100644 --- a/chrome/browser/vr/elements/suggestion.h +++ b/chrome/browser/vr/elements/suggestion.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_VR_ELEMENTS_SUGGESTION_H_ #define CHROME_BROWSER_VR_ELEMENTS_SUGGESTION_H_ -#include "chrome/browser/vr/elements/linear_layout.h" +#include "chrome/browser/vr/elements/ui_element.h" #include "url/gurl.h" namespace vr { @@ -15,7 +15,7 @@ // to bind both necessitates lambda capture, which base::Bind cannot do. This // workaround simplifies the problem. If UI elements gain the ability to use the // VR UI to browser interface, we could eliminate this class. -class Suggestion : public LinearLayout { +class Suggestion : public UiElement { public: explicit Suggestion(base::Callback<void(GURL)> navigate_callback); ~Suggestion() override;
diff --git a/chrome/browser/vr/elements/ui_element_type.cc b/chrome/browser/vr/elements/ui_element_type.cc index a9b25aaf..c2d209c 100644 --- a/chrome/browser/vr/elements/ui_element_type.cc +++ b/chrome/browser/vr/elements/ui_element_type.cc
@@ -17,6 +17,13 @@ "kTypeButtonForeground", "kTypeButtonHitTarget", "kTypeScaledDepthAdjuster", + "kTypeOmniboxSuggestionBackground", + "kTypeOmniboxSuggestionLayout", + "kTypeOmniboxSuggestionTextLayout", + "kTypeOmniboxSuggestionIconField", + "kTypeOmniboxSuggestionIcon", + "kTypeOmniboxSuggestionContentText", + "kTypeOmniboxSuggestionDescriptionText", }; static_assert(
diff --git a/chrome/browser/vr/elements/ui_element_type.h b/chrome/browser/vr/elements/ui_element_type.h index dcb13c5b..1ecdd6d 100644 --- a/chrome/browser/vr/elements/ui_element_type.h +++ b/chrome/browser/vr/elements/ui_element_type.h
@@ -17,6 +17,13 @@ kTypeButtonForeground, kTypeButtonHitTarget, kTypeScaledDepthAdjuster, + kTypeOmniboxSuggestionBackground, + kTypeOmniboxSuggestionLayout, + kTypeOmniboxSuggestionTextLayout, + kTypeOmniboxSuggestionIconField, + kTypeOmniboxSuggestionIcon, + kTypeOmniboxSuggestionContentText, + kTypeOmniboxSuggestionDescriptionText, // This must be last. kNumUiElementTypes,
diff --git a/chrome/browser/vr/fps_meter.cc b/chrome/browser/vr/fps_meter.cc index c4a79526..3ed0967 100644 --- a/chrome/browser/vr/fps_meter.cc +++ b/chrome/browser/vr/fps_meter.cc
@@ -4,8 +4,6 @@ #include "chrome/browser/vr/fps_meter.h" -#include <algorithm> - namespace vr { namespace { @@ -14,28 +12,6 @@ } // namespace -SampleQueue::SampleQueue(size_t window_size) : window_size_(window_size) { - samples_.reserve(window_size); -} - -SampleQueue::~SampleQueue() = default; - -void SampleQueue::AddSample(int64_t value) { - sum_ += value; - - if (samples_.size() < window_size_) { - samples_.push_back(value); - } else { - sum_ -= samples_[current_index_]; - samples_[current_index_] = value; - } - - ++current_index_; - if (current_index_ >= window_size_) { - current_index_ = 0; - } -} - FPSMeter::FPSMeter() : frame_times_(kDefaultNumFrameTimes) {} FPSMeter::FPSMeter(size_t window_size) : frame_times_(window_size) {} @@ -70,18 +46,4 @@ return (frame_times_.GetCount() * 1.0e6) / frame_times_.GetSum(); } -SlidingAverage::SlidingAverage(size_t window_size) : values_(window_size) {} - -SlidingAverage::~SlidingAverage() = default; - -void SlidingAverage::AddSample(int64_t value) { - values_.AddSample(value); -} - -int64_t SlidingAverage::GetAverageOrDefault(int64_t default_value) const { - if (values_.GetCount() == 0) - return default_value; - return values_.GetSum() / values_.GetCount(); -} - } // namespace vr
diff --git a/chrome/browser/vr/fps_meter.h b/chrome/browser/vr/fps_meter.h index 4fd9082..57900d9 100644 --- a/chrome/browser/vr/fps_meter.h +++ b/chrome/browser/vr/fps_meter.h
@@ -5,34 +5,12 @@ #ifndef CHROME_BROWSER_VR_FPS_METER_H_ #define CHROME_BROWSER_VR_FPS_METER_H_ -#include <vector> - #include "base/macros.h" #include "base/time/time.h" +#include "chrome/browser/vr/sample_queue.h" namespace vr { -class SampleQueue { - public: - explicit SampleQueue(size_t window_size); - ~SampleQueue(); - - int64_t GetSum() const { return sum_; } - - void AddSample(int64_t value); - - size_t GetCount() const { return samples_.size(); } - - // Get sliding window size for tests. - size_t GetWindowSize() const { return window_size_; } - - private: - int64_t sum_ = 0; - size_t current_index_ = 0; - size_t window_size_; - std::vector<int64_t> samples_; -}; - // Computes fps based on submitted frame times. class FPSMeter { public: @@ -55,19 +33,6 @@ DISALLOW_COPY_AND_ASSIGN(FPSMeter); }; -class SlidingAverage { - public: - explicit SlidingAverage(size_t window_size); - ~SlidingAverage(); - - void AddSample(int64_t value); - int64_t GetAverageOrDefault(int64_t default_value) const; - int64_t GetAverage() const { return GetAverageOrDefault(0); } - - private: - SampleQueue values_; -}; - } // namespace vr #endif // CHROME_BROWSER_VR_FPS_METER_H_
diff --git a/chrome/browser/vr/fps_meter_unittest.cc b/chrome/browser/vr/fps_meter_unittest.cc index a7e575d..b1625c1 100644 --- a/chrome/browser/vr/fps_meter_unittest.cc +++ b/chrome/browser/vr/fps_meter_unittest.cc
@@ -70,37 +70,4 @@ } } -TEST(SlidingAverage, Basics) { - SlidingAverage meter(5); - - // No values yet - EXPECT_EQ(42, meter.GetAverageOrDefault(42)); - EXPECT_EQ(0, meter.GetAverage()); - - meter.AddSample(100); - EXPECT_EQ(100, meter.GetAverageOrDefault(42)); - EXPECT_EQ(100, meter.GetAverage()); - - meter.AddSample(200); - EXPECT_EQ(150, meter.GetAverage()); - - meter.AddSample(10); - EXPECT_EQ(103, meter.GetAverage()); - - meter.AddSample(10); - EXPECT_EQ(80, meter.GetAverage()); - - meter.AddSample(10); - EXPECT_EQ(66, meter.GetAverage()); - - meter.AddSample(10); - EXPECT_EQ(48, meter.GetAverage()); - - meter.AddSample(10); - EXPECT_EQ(10, meter.GetAverage()); - - meter.AddSample(110); - EXPECT_EQ(30, meter.GetAverage()); -} - } // namespace vr
diff --git a/chrome/browser/vr/model/color_scheme.cc b/chrome/browser/vr/model/color_scheme.cc index 52d4b65..2474154 100644 --- a/chrome/browser/vr/model/color_scheme.cc +++ b/chrome/browser/vr/model/color_scheme.cc
@@ -111,6 +111,11 @@ normal_scheme.timeout_message_background = 0xFF444444; normal_scheme.timeout_message_foreground = normal_scheme.spinner_color; normal_scheme.speech_recognition_circle_background = 0xFF4285F4; + normal_scheme.omnibox_background = 0xFFEEEEEE; + normal_scheme.omnibox_icon = 0xA6000000; + normal_scheme.omnibox_text = 0xFF595959; + normal_scheme.omnibox_suggestion_content = 0xFF595959; + normal_scheme.omnibox_suggestion_description = 0xFF5595FE; g_fullscreen_scheme.Get() = normal_scheme; ColorScheme& fullscreen_scheme = g_fullscreen_scheme.Get();
diff --git a/chrome/browser/vr/model/color_scheme.h b/chrome/browser/vr/model/color_scheme.h index 6c3708a..e094bc39 100644 --- a/chrome/browser/vr/model/color_scheme.h +++ b/chrome/browser/vr/model/color_scheme.h
@@ -88,11 +88,9 @@ UrlBarColors url_bar; - // Screen dimmer colors. SkColor dimmer_outer; SkColor dimmer_inner; - // Splash screen colors. SkColor splash_screen_background; SkColor splash_screen_text_color; @@ -100,11 +98,16 @@ SkColor spinner_background; SkColor spinner_color; - // Timeout UI colors SkColor timeout_message_background; SkColor timeout_message_foreground; SkColor speech_recognition_circle_background; + + SkColor omnibox_background; + SkColor omnibox_icon; + SkColor omnibox_text; + SkColor omnibox_suggestion_content; + SkColor omnibox_suggestion_description; }; } // namespace vr
diff --git a/chrome/browser/vr/sample_queue.cc b/chrome/browser/vr/sample_queue.cc new file mode 100644 index 0000000..c2ca777 --- /dev/null +++ b/chrome/browser/vr/sample_queue.cc
@@ -0,0 +1,31 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/sample_queue.h" + +namespace vr { + +SampleQueue::SampleQueue(size_t window_size) : window_size_(window_size) { + samples_.reserve(window_size); +} + +SampleQueue::~SampleQueue() = default; + +void SampleQueue::AddSample(int64_t value) { + sum_ += value; + + if (samples_.size() < window_size_) { + samples_.push_back(value); + } else { + sum_ -= samples_[current_index_]; + samples_[current_index_] = value; + } + + ++current_index_; + if (current_index_ >= window_size_) { + current_index_ = 0; + } +} + +} // namespace vr
diff --git a/chrome/browser/vr/sample_queue.h b/chrome/browser/vr/sample_queue.h new file mode 100644 index 0000000..c74f316 --- /dev/null +++ b/chrome/browser/vr/sample_queue.h
@@ -0,0 +1,41 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VR_SAMPLE_QUEUE_H_ +#define CHROME_BROWSER_VR_SAMPLE_QUEUE_H_ + +#include <vector> + +#include "base/macros.h" + +namespace vr { + +// Manages a fixed-size queue of samples including their current sum. Old +// samples are automatically dropped when an added sample would exceed the +// requested size. +class SampleQueue { + public: + explicit SampleQueue(size_t window_size); + ~SampleQueue(); + + int64_t GetSum() const { return sum_; } + + void AddSample(int64_t value); + + size_t GetCount() const { return samples_.size(); } + + // Get sliding window size for tests. + size_t GetWindowSize() const { return window_size_; } + + private: + int64_t sum_ = 0; + size_t current_index_ = 0; + size_t window_size_; + std::vector<int64_t> samples_; + DISALLOW_COPY_AND_ASSIGN(SampleQueue); +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_SAMPLE_QUEUE_H_
diff --git a/chrome/browser/vr/sliding_average.cc b/chrome/browser/vr/sliding_average.cc new file mode 100644 index 0000000..4852063 --- /dev/null +++ b/chrome/browser/vr/sliding_average.cc
@@ -0,0 +1,38 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/sliding_average.h" + +namespace vr { + +SlidingAverage::SlidingAverage(size_t window_size) : values_(window_size) {} + +SlidingAverage::~SlidingAverage() = default; + +void SlidingAverage::AddSample(int64_t value) { + values_.AddSample(value); +} + +int64_t SlidingAverage::GetAverageOrDefault(int64_t default_value) const { + if (values_.GetCount() == 0) + return default_value; + return values_.GetSum() / values_.GetCount(); +} + +SlidingTimeDeltaAverage::SlidingTimeDeltaAverage(size_t window_size) + : sample_microseconds_(window_size) {} + +SlidingTimeDeltaAverage::~SlidingTimeDeltaAverage() = default; + +void SlidingTimeDeltaAverage::AddSample(base::TimeDelta value) { + sample_microseconds_.AddSample(value.InMicroseconds()); +} + +base::TimeDelta SlidingTimeDeltaAverage::GetAverageOrDefault( + base::TimeDelta default_value) const { + return base::TimeDelta::FromMicroseconds( + sample_microseconds_.GetAverageOrDefault(default_value.InMicroseconds())); +} + +} // namespace vr
diff --git a/chrome/browser/vr/sliding_average.h b/chrome/browser/vr/sliding_average.h new file mode 100644 index 0000000..7589673b --- /dev/null +++ b/chrome/browser/vr/sliding_average.h
@@ -0,0 +1,50 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_VR_SLIDING_AVERAGE_H_ +#define CHROME_BROWSER_VR_SLIDING_AVERAGE_H_ + +#include <vector> + +#include "base/macros.h" +#include "base/time/time.h" +#include "chrome/browser/vr/sample_queue.h" + +namespace vr { + +class SlidingAverage { + public: + explicit SlidingAverage(size_t window_size); + ~SlidingAverage(); + + void AddSample(int64_t value); + int64_t GetAverageOrDefault(int64_t default_value) const; + int64_t GetAverage() const { return GetAverageOrDefault(0); } + size_t GetCount() const { return values_.GetCount(); } + + private: + SampleQueue values_; + DISALLOW_COPY_AND_ASSIGN(SlidingAverage); +}; + +class SlidingTimeDeltaAverage { + public: + explicit SlidingTimeDeltaAverage(size_t window_size); + virtual ~SlidingTimeDeltaAverage(); + + virtual void AddSample(base::TimeDelta value); + base::TimeDelta GetAverageOrDefault(base::TimeDelta default_value) const; + base::TimeDelta GetAverage() const { + return GetAverageOrDefault(base::TimeDelta()); + } + size_t GetCount() const { return sample_microseconds_.GetCount(); } + + private: + SlidingAverage sample_microseconds_; + DISALLOW_COPY_AND_ASSIGN(SlidingTimeDeltaAverage); +}; + +} // namespace vr + +#endif // CHROME_BROWSER_VR_SLIDING_AVERAGE_H_
diff --git a/chrome/browser/vr/sliding_average_unittest.cc b/chrome/browser/vr/sliding_average_unittest.cc new file mode 100644 index 0000000..a2632ff8 --- /dev/null +++ b/chrome/browser/vr/sliding_average_unittest.cc
@@ -0,0 +1,60 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/vr/sliding_average.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace vr { + +TEST(SlidingAverage, Basics) { + SlidingAverage meter(5); + + // No values yet + EXPECT_EQ(42, meter.GetAverageOrDefault(42)); + EXPECT_EQ(0, meter.GetAverage()); + + meter.AddSample(100); + EXPECT_EQ(100, meter.GetAverageOrDefault(42)); + EXPECT_EQ(100, meter.GetAverage()); + + meter.AddSample(200); + EXPECT_EQ(150, meter.GetAverage()); + + meter.AddSample(10); + EXPECT_EQ(103, meter.GetAverage()); + + meter.AddSample(10); + EXPECT_EQ(80, meter.GetAverage()); + + meter.AddSample(10); + EXPECT_EQ(66, meter.GetAverage()); + + meter.AddSample(10); + EXPECT_EQ(48, meter.GetAverage()); + + meter.AddSample(10); + EXPECT_EQ(10, meter.GetAverage()); + + meter.AddSample(110); + EXPECT_EQ(30, meter.GetAverage()); +} + +TEST(SlidingTimeDeltaAverage, Basics) { + SlidingTimeDeltaAverage meter(5); + + EXPECT_EQ(base::TimeDelta::FromSeconds(42), + meter.GetAverageOrDefault(base::TimeDelta::FromSeconds(42))); + EXPECT_EQ(base::TimeDelta(), meter.GetAverage()); + + meter.AddSample(base::TimeDelta::FromSeconds(100)); + EXPECT_EQ(base::TimeDelta::FromSeconds(100), + meter.GetAverageOrDefault(base::TimeDelta::FromSeconds(42))); + EXPECT_EQ(base::TimeDelta::FromSeconds(100), meter.GetAverage()); + + meter.AddSample(base::TimeDelta::FromMilliseconds(200000)); + EXPECT_EQ(base::TimeDelta::FromSeconds(150), meter.GetAverage()); +} + +} // namespace vr
diff --git a/chrome/browser/vr/testapp/vr_test_context.cc b/chrome/browser/vr/testapp/vr_test_context.cc index 287b042..f3726a2 100644 --- a/chrome/browser/vr/testapp/vr_test_context.cc +++ b/chrome/browser/vr/testapp/vr_test_context.cc
@@ -316,9 +316,12 @@ for (int i = 0; i < num_suggestions; i++) { result->suggestions.emplace_back(OmniboxSuggestion( base::UTF8ToUTF16("Suggestion ") + base::IntToString16(i + 1), - base::UTF8ToUTF16("Description text"), + base::UTF8ToUTF16( + "Very lengthy description of the suggestion that would wrap " + "if not truncated through some other means."), AutocompleteMatch::Type::VOICE_SUGGEST, GURL("http://www.test.com/"))); } + model_->omnibox_input_active = true; ui_->SetOmniboxSuggestions(std::move(result)); }
diff --git a/chrome/browser/vr/ui_scene_constants.h b/chrome/browser/vr/ui_scene_constants.h index 8f3eddd..66140bba 100644 --- a/chrome/browser/vr/ui_scene_constants.h +++ b/chrome/browser/vr/ui_scene_constants.h
@@ -184,19 +184,24 @@ static constexpr float kReticleWidth = 0.025f; static constexpr float kReticleHeight = 0.025f; -static constexpr float kOmniboxContainerWidth = 4.5; -static constexpr float kOmniboxContainerHeight = 12 * 0.02f; -static constexpr float kOmniboxContainerCornerRadius = 0.01; -static constexpr float kOmniboxContainerVeriticalOffset = 0.7; -static constexpr float kOmniboxTextHeight = 0.05; -static constexpr float kOmniboxCloseButtonVerticalOffset = -0.5; -static constexpr float kSuggestionGap = 0.01f; -static constexpr float kSuggestionLineGap = 0.01f; -static constexpr float kSuggestionIconGap = 0.01f; -static constexpr float kSuggestionIconSize = 0.1f; -static constexpr float kSuggestionTextFieldWidth = 0.3f; -static constexpr float kSuggestionContentTextHeight = 0.02f; -static constexpr float kSuggestionDescriptionTextHeight = 0.015f; +static constexpr float kOmniboxWidthDMM = 0.848f; +static constexpr float kOmniboxHeightDMM = 0.088f; +static constexpr float kOmniboxVerticalOffsetDMM = -0.1f; +static constexpr float kOmniboxTextHeightDMM = 0.032f; +static constexpr float kOmniboxTextMarginDMM = 0.024f; +static constexpr float kOmniboxCloseButtonDiameterDMM = 0.088f; +static constexpr float kOmniboxCloseButtonVerticalOffsetDMM = -0.5; + +static constexpr float kSuggestionHeightDMM = 0.088f; +static constexpr float kSuggestionGapDMM = 0.008f; +static constexpr float kSuggestionLineGapDMM = 0.01f; +static constexpr float kSuggestionIconSizeDMM = 0.036f; +static constexpr float kSuggestionIconFieldWidthDMM = 0.104f; +static constexpr float kSuggestionRightMarginDMM = 0.024f; +static constexpr float kSuggestionTextFieldWidthDMM = + kOmniboxWidthDMM - kSuggestionIconFieldWidthDMM - kSuggestionRightMarginDMM; +static constexpr float kSuggestionContentTextHeightDMM = 0.024f; +static constexpr float kSuggestionDescriptionTextHeightDMM = 0.020f; static constexpr int kControllerFadeInMs = 200; static constexpr int kControllerFadeOutMs = 550;
diff --git a/chrome/browser/vr/ui_scene_creator.cc b/chrome/browser/vr/ui_scene_creator.cc index 7855cb0..6f7236d7 100644 --- a/chrome/browser/vr/ui_scene_creator.cc +++ b/chrome/browser/vr/ui_scene_creator.cc
@@ -81,46 +81,76 @@ Model* model, SuggestionBinding* element_binding) { auto icon = base::MakeUnique<VectorIcon>(100); - icon->SetVisible(true); - icon->SetSize(kSuggestionIconSize, kSuggestionIconSize); icon->set_draw_phase(kPhaseForeground); + icon->set_type(kTypeOmniboxSuggestionIcon); + icon->set_hit_testable(false); + icon->SetSize(kSuggestionIconSizeDMM, kSuggestionIconSizeDMM); + BindColor(model, icon.get(), &ColorScheme::omnibox_icon, + &VectorIcon::SetColor); VectorIcon* p_icon = icon.get(); - auto content_text = base::MakeUnique<Text>(512, kSuggestionContentTextHeight); + auto icon_box = base::MakeUnique<UiElement>(); + icon_box->set_draw_phase(kPhaseNone); + icon_box->set_type(kTypeOmniboxSuggestionIconField); + icon_box->SetSize(kSuggestionIconFieldWidthDMM, kSuggestionHeightDMM); + icon_box->AddChild(std::move(icon)); + + auto content_text = + base::MakeUnique<Text>(1024, kSuggestionContentTextHeightDMM); content_text->set_draw_phase(kPhaseForeground); - content_text->SetVisible(true); - content_text->SetSize(kSuggestionTextFieldWidth, 0); + content_text->set_type(kTypeOmniboxSuggestionContentText); + content_text->SetSize(kSuggestionTextFieldWidthDMM, 0); content_text->SetTextAlignment(UiTexture::kTextAlignmentLeft); + content_text->SetMultiLine(false); + BindColor(model, content_text.get(), &ColorScheme::omnibox_suggestion_content, + &Text::SetColor); Text* p_content_text = content_text.get(); auto description_text = - base::MakeUnique<Text>(512, kSuggestionDescriptionTextHeight); - description_text->SetSize(kSuggestionTextFieldWidth, 0); + base::MakeUnique<Text>(1024, kSuggestionDescriptionTextHeightDMM); description_text->set_draw_phase(kPhaseForeground); - description_text->SetVisible(true); + description_text->set_type(kTypeOmniboxSuggestionDescriptionText); + description_text->SetSize(kSuggestionTextFieldWidthDMM, 0); description_text->SetTextAlignment(UiTexture::kTextAlignmentLeft); + description_text->SetMultiLine(false); + BindColor(model, description_text.get(), + &ColorScheme::omnibox_suggestion_description, &Text::SetColor); Text* p_description_text = description_text.get(); auto text_layout = base::MakeUnique<LinearLayout>(LinearLayout::kDown); - text_layout->set_margin(kSuggestionLineGap); + text_layout->set_type(kTypeOmniboxSuggestionTextLayout); + text_layout->set_margin(kSuggestionLineGapDMM); text_layout->AddChild(std::move(content_text)); text_layout->AddChild(std::move(description_text)); text_layout->SetVisible(true); + auto right_margin = base::MakeUnique<UiElement>(); + right_margin->set_draw_phase(kPhaseNone); + right_margin->SetSize(kSuggestionRightMarginDMM, kSuggestionHeightDMM); + + auto suggestion_layout = base::MakeUnique<LinearLayout>(LinearLayout::kRight); + suggestion_layout->set_type(kTypeOmniboxSuggestionLayout); + suggestion_layout->AddChild(std::move(icon_box)); + suggestion_layout->AddChild(std::move(text_layout)); + suggestion_layout->AddChild(std::move(right_margin)); + + auto background = base::MakeUnique<Rect>(); + background->set_type(kTypeOmniboxSuggestionBackground); + background->set_draw_phase(kPhaseForeground); + background->set_bounds_contain_children(true); + background->SetColor(SK_ColorGREEN); + background->AddChild(std::move(suggestion_layout)); + BindColor(model, background.get(), &ColorScheme::omnibox_background, + &Rect::SetColor); + auto suggestion = base::MakeUnique<Suggestion>(base::Bind( [](UiBrowserInterface* browser, Model* m, GURL gurl) { browser->Navigate(gurl); m->omnibox_input_active = false; }, base::Unretained(browser), base::Unretained(model))); - - suggestion->set_margin(kSuggestionIconGap); - suggestion->SetVisible(true); - suggestion->AddChild(std::move(icon)); - suggestion->AddChild(std::move(text_layout)); - Suggestion* p_suggestion = suggestion.get(); - - element_binding->set_view(suggestion.get()); + suggestion->set_bounds_contain_children(true); + suggestion->AddChild(std::move(background)); element_binding->bindings().push_back( VR_BIND_FUNC(base::string16, SuggestionBinding, element_binding, @@ -134,8 +164,9 @@ SetIcon(AutocompleteMatch::TypeToVectorIcon(value)))); element_binding->bindings().push_back(VR_BIND_FUNC( GURL, SuggestionBinding, element_binding, model()->destination, - Suggestion, p_suggestion, set_destination)); + Suggestion, suggestion.get(), set_destination)); + element_binding->set_view(suggestion.get()); scene->AddUiElement(kOmniboxSuggestions, std::move(suggestion)); } @@ -1004,18 +1035,19 @@ omnibox_root->set_draw_phase(kPhaseNone); omnibox_root->SetVisible(false); omnibox_root->set_hit_testable(false); - omnibox_root->SetTranslate(0, kUrlBarVerticalOffset, -kUrlBarDistance); omnibox_root->SetTransitionedProperties({OPACITY}); omnibox_root->AddBinding(VR_BIND_FUNC(bool, Model, model_, omnibox_input_active, UiElement, omnibox_root.get(), SetVisible)); - scene_->AddUiElement(k2dBrowsingRoot, std::move(omnibox_root)); + + auto scaler = base::MakeUnique<ScaledDepthAdjuster>(kUrlBarDistance); + scaler->AddChild(std::move(omnibox_root)); + scene_->AddUiElement(k2dBrowsingRoot, std::move(scaler)); auto omnibox_container = base::MakeUnique<Rect>(); omnibox_container->set_name(kOmniboxContainer); omnibox_container->set_draw_phase(kPhaseForeground); - omnibox_container->SetSize(kOmniboxContainerWidth, kOmniboxContainerHeight); - omnibox_container->set_corner_radius(kOmniboxContainerCornerRadius); + omnibox_container->SetSize(kOmniboxWidthDMM, kOmniboxHeightDMM); omnibox_container->SetColor(SK_ColorWHITE); omnibox_container->SetTransitionedProperties({TRANSFORM}); omnibox_container->AddBinding(base::MakeUnique<Binding<bool>>( @@ -1023,16 +1055,22 @@ base::Unretained(model_)), base::Bind( [](UiElement* e, const bool& v) { - float y_offset = v ? kOmniboxContainerVeriticalOffset : 0; + float y_offset = v ? kOmniboxVerticalOffsetDMM : 0; e->SetTranslate(0, y_offset, 0); }, omnibox_container.get()))); scene_->AddUiElement(kOmniboxRoot, std::move(omnibox_container)); - auto omnibox_text_field = base::MakeUnique<TextInput>( - 512, kOmniboxTextHeight, kSuggestionTextFieldWidth); + float width = kOmniboxWidthDMM - 2 * kOmniboxTextMarginDMM; + auto omnibox_text_field = + base::MakeUnique<TextInput>(1024, kOmniboxTextHeightDMM, width); + omnibox_text_field->SetSize(width, 0); omnibox_text_field->set_name(kOmniboxTextField); omnibox_text_field->set_draw_phase(kPhaseForeground); + omnibox_text_field->set_x_anchoring(LEFT); + omnibox_text_field->set_x_centering(LEFT); + omnibox_text_field->SetTranslate(kOmniboxTextMarginDMM, 0, 0); + omnibox_text_field->SetTextChangedCallback(base::Bind( &UiBrowserInterface::StartAutocomplete, base::Unretained(browser_))); scene_->AddUiElement(kOmniboxContainer, std::move(omnibox_text_field)); @@ -1042,10 +1080,10 @@ base::Bind([](Model* m) { m->omnibox_input_active = false; }, base::Unretained(model_)), vector_icons::kClose16Icon); - close_button->SetSize(kCloseButtonWidth, kCloseButtonHeight); - close_button->set_hover_offset(kButtonZOffsetHoverDMM * kCloseButtonDistance); - close_button->SetTranslate(0, kOmniboxCloseButtonVerticalOffset, 0); - close_button->SetSize(kCloseButtonWidth, kCloseButtonHeight); + close_button->SetSize(kOmniboxCloseButtonDiameterDMM, + kOmniboxCloseButtonDiameterDMM); + close_button->SetTranslate(0, kOmniboxCloseButtonVerticalOffsetDMM, 0); + close_button->set_hover_offset(kButtonZOffsetHoverDMM); BindButtonColors(model_, close_button.get(), &ColorScheme::button_colors, &Button::SetButtonColors); scene_->AddUiElement(kOmniboxContainer, std::move(close_button)); @@ -1060,11 +1098,13 @@ auto suggestions_layout = base::MakeUnique<LinearLayout>(LinearLayout::kUp); suggestions_layout->set_name(kOmniboxSuggestions); suggestions_layout->set_draw_phase(kPhaseNone); + suggestions_layout->set_hit_testable(false); suggestions_layout->set_y_anchoring(TOP); suggestions_layout->set_y_centering(BOTTOM); - suggestions_layout->set_margin(kSuggestionGap); + suggestions_layout->SetTranslate(0, kSuggestionGapDMM, 0); suggestions_layout->AddBinding(base::MakeUnique<SuggestionSetBinding>( &model_->omnibox_suggestions, added_callback, removed_callback)); + scene_->AddUiElement(kOmniboxContainer, std::move(suggestions_layout)); }
diff --git a/chrome/browser/vr/ui_scene_creator.h b/chrome/browser/vr/ui_scene_creator.h index 157fd517..3d7ce7d 100644 --- a/chrome/browser/vr/ui_scene_creator.h +++ b/chrome/browser/vr/ui_scene_creator.h
@@ -39,7 +39,6 @@ void CreateViewportAwareRoot(); void CreateUrlBar(); void CreateOmnibox(); - void CreateSuggestionList(); void CreateWebVrUrlToast(); void CreateCloseButton(); void CreateExitPrompt();
diff --git a/chrome/browser/vr/ui_unittest.cc b/chrome/browser/vr/ui_unittest.cc index 880ab0e..5f294aba 100644 --- a/chrome/browser/vr/ui_unittest.cc +++ b/chrome/browser/vr/ui_unittest.cc
@@ -67,7 +67,6 @@ kUrlBar, kOmniboxContainer, kOmniboxTextField, - kOmniboxSuggestions, kLoadingIndicator, kWebVrTimeoutSpinner, kWebVrTimeoutMessage,
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index ad5a5e1..68b17f7 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -733,6 +733,7 @@ "../browser/ui/collected_cookies_browsertest.cc", "../browser/ui/content_settings/content_setting_bubble_model_browsertest.cc", "../browser/ui/content_settings/content_setting_image_model_browsertest.cc", + "../browser/ui/content_settings/framebust_block_browsertest.cc", "../browser/ui/exclusive_access/fullscreen_controller_browsertest.cc", "../browser/ui/extensions/extension_enable_flow_browsertest.cc", "../browser/ui/extensions/extension_installed_bubble_browsertest.cc",
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java index 6ad7a1e..abf06ab2 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/OmniboxTestUtils.java
@@ -165,7 +165,7 @@ } @Override - public void startZeroSuggest(Profile profile, String omniboxText, String url, + public void startZeroSuggest(Profile profile, String omniboxText, String url, String title, boolean focusedFromFakebox) { mZeroSuggestCalledCount++; } @@ -212,9 +212,8 @@ boolean preventInlineAutocomplete, boolean focusedFromFakebox) {} @Override - public void startZeroSuggest(Profile profile, String omniboxText, String url, - boolean focusedFromFakebox) { - } + public void startZeroSuggest(Profile profile, String omniboxText, String url, String title, + boolean focusedFromFakebox) {} @Override public void stop(boolean clear) {}
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index de348e3..32c7334 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -35,7 +35,6 @@ #include "chrome/browser/history/chrome_history_client.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/history/web_history_service_factory.h" -#include "chrome/browser/net/proxy_service_factory.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/policy/profile_policy_connector_factory.h" #include "chrome/browser/policy/schema_registry_service.h" @@ -78,7 +77,6 @@ #include "components/policy/core/common/policy_service_impl.h" #include "components/policy/core/common/schema.h" #include "components/prefs/testing_pref_store.h" -#include "components/proxy_config/pref_proxy_config_tracker.h" #include "components/sync/model/fake_sync_change_processor.h" #include "components/sync/model/sync_error_factory_mock.h" #include "components/sync_preferences/pref_service_mock_factory.h" @@ -537,9 +535,6 @@ if (host_content_settings_map_.get()) host_content_settings_map_->ShutdownOnUIThread(); - if (pref_proxy_config_tracker_.get()) - pref_proxy_config_tracker_->DetachFromPrefService(); - // Shutdown storage partitions before we post a task to delete // the resource context. ShutdownStoragePartitions(); @@ -888,16 +883,6 @@ last_selected_directory_ = path; } -PrefProxyConfigTracker* TestingProfile::GetProxyConfigTracker() { - if (!pref_proxy_config_tracker_.get()) { - // TestingProfile is used in unit tests, where local state is not available. - pref_proxy_config_tracker_.reset( - ProxyServiceFactory::CreatePrefProxyConfigTrackerOfProfile(GetPrefs(), - NULL)); - } - return pref_proxy_config_tracker_.get(); -} - void TestingProfile::BlockUntilHistoryProcessesPendingRequests() { history::HistoryService* history_service = HistoryServiceFactory::GetForProfile(this,
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h index c7b1e207..f86e5d9 100644 --- a/chrome/test/base/testing_profile.h +++ b/chrome/test/base/testing_profile.h
@@ -328,8 +328,6 @@ void InitChromeOSPreferences() override {} #endif // defined(OS_CHROMEOS) - PrefProxyConfigTracker* GetProxyConfigTracker() override; - // Schedules a task on the history backend and runs a nested loop until the // task is processed. This has the effect of blocking the caller until the // history service processes all pending requests. @@ -407,9 +405,6 @@ extension_special_storage_policy_; #endif - // The proxy prefs tracker. - std::unique_ptr<PrefProxyConfigTracker> pref_proxy_config_tracker_; - // The path to this profile. This will be valid in either of the two above // cases. base::FilePath profile_path_;
diff --git a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js index 88c2d02..2d814bb6 100644 --- a/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js +++ b/chrome/test/data/webui/print_preview/new_print_preview_ui_browsertest.js
@@ -87,3 +87,7 @@ TEST_F('PrintPreviewSettingsSectionsTest', 'Scaling', function() { this.runMochaTest(settings_sections_tests.TestNames.Scaling); }); + +TEST_F('PrintPreviewSettingsSectionsTest', 'Other', function() { + this.runMochaTest(settings_sections_tests.TestNames.Other); +});
diff --git a/chrome/test/data/webui/print_preview/settings_section_test.js b/chrome/test/data/webui/print_preview/settings_section_test.js index deddf1a..8d8d082 100644 --- a/chrome/test/data/webui/print_preview/settings_section_test.js +++ b/chrome/test/data/webui/print_preview/settings_section_test.js
@@ -12,6 +12,7 @@ Margins: 'margins', Dpi: 'dpi', Scaling: 'scaling', + Other: 'other', }; const suiteName = 'SettingsSectionsTests'; @@ -261,6 +262,62 @@ setPdfDestination(); expectEquals(true, scalingElement.hidden); }); + + test(assert(TestNames.Other), function() { + const optionsElement = page.$$('print-preview-other-options-settings'); + const headerFooter = optionsElement.$$('#header-footer-container'); + const duplex = optionsElement.$$('#duplex-container'); + const cssBackground = optionsElement.$$('#css-background-container'); + const rasterize = optionsElement.$$('#rasterize-container'); + const selectionOnly = optionsElement.$$('#selection-only-container'); + + // Start with HTML + duplex capability. + setPdfDocument(false); + let capabilities = getCdd(); + page.set('destination.capabilities', capabilities); + expectEquals(false, optionsElement.hidden); + expectEquals(false, headerFooter.hidden); + expectEquals(false, duplex.hidden); + expectEquals(false, cssBackground.hidden); + expectEquals(true, rasterize.hidden); + expectEquals(true, selectionOnly.hidden); + + // Add a selection. + let info = new print_preview.DocumentInfo(); + info.init(true, 'title', true); + page.set('documentInfo', info); + expectEquals(false, optionsElement.hidden); + expectEquals(false, selectionOnly.hidden); + + // Remove duplex capability. + capabilities = getCdd(); + delete capabilities.printer.duplex; + page.set('destination.capabilities', capabilities); + expectEquals(false, optionsElement.hidden); + expectEquals(true, duplex.hidden); + + // PDF + setPdfDocument(true); + expectEquals(cr.isWindows || cr.isMac, optionsElement.hidden); + expectEquals(true, headerFooter.hidden); + expectEquals(true, duplex.hidden); + expectEquals(true, cssBackground.hidden); + expectEquals(cr.isWindows || cr.isMac, rasterize.hidden); + expectEquals(true, selectionOnly.hidden); + + // Add a selection - should do nothing for PDFs. + info = new print_preview.DocumentInfo(); + info.init(false, 'title', true); + page.set('documentInfo', info); + expectEquals(cr.isWindows || cr.isMac, optionsElement.hidden); + expectEquals(true, selectionOnly.hidden); + + // Add duplex. + capabilities = getCdd(); + page.set('destination.capabilities', capabilities); + expectEquals(false, optionsElement.hidden); + expectEquals(false, duplex.hidden); + }); }); return {
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn index 01b164c8..20d8489 100644 --- a/chromecast/BUILD.gn +++ b/chromecast/BUILD.gn
@@ -34,6 +34,9 @@ if (!is_android) { deps += [ ":cast_shell" ] } + if (is_linux) { + deps += [ "//chromecast/tracing" ] + } if (chromecast_branding != "public") { deps += [ "//chromecast/internal:all" ] } @@ -514,7 +517,9 @@ ] if (chromecast_branding != "public") { - sources += [ "$root_gen_dir/chromecast/internal/webui/app_strings_${locale}.pak" ] + sources += [ + "$root_gen_dir/chromecast/internal/webui/app_strings_${locale}.pak", + ] deps += [ "//chromecast/internal/webui:chromecast_app_strings" ] if (enable_chromecast_webui) {
diff --git a/chromecast/base/chromecast_switches.cc b/chromecast/base/chromecast_switches.cc index 5dbf6e4..7d79080 100644 --- a/chromecast/base/chromecast_switches.cc +++ b/chromecast/base/chromecast_switches.cc
@@ -69,6 +69,7 @@ const char kAlsaEnableUpsampling[] = "alsa-enable-upsampling"; // Optional flag to set a fixed sample rate for the alsa device. +// Deprecated: Use --audio-output-sample-rate instead. const char kAlsaFixedOutputSampleRate[] = "alsa-fixed-output-sample-rate"; // Name of the simple mixer control element that the ALSA-based media library @@ -96,6 +97,11 @@ // value is 2. const char kAudioOutputChannels[] = "audio-output-channels"; +// Specify fixed sample rate for audio output stream. If this flag is not +// specified the StreamMixer will choose sample rate based on the sample rate of +// the media stream. +const char kAudioOutputSampleRate[] = "audio-output-sample-rate"; + // Some platforms typically have very little 'free' memory, but plenty is // available in buffers+cached. For such platforms, configure this amount // as the portion of buffers+cached memory that should be treated as
diff --git a/chromecast/base/chromecast_switches.h b/chromecast/base/chromecast_switches.h index 8d3949a2..e887b95f 100644 --- a/chromecast/base/chromecast_switches.h +++ b/chromecast/base/chromecast_switches.h
@@ -38,6 +38,9 @@ extern const char kAcceptResourceProvider[]; // ALSA-based CMA switches. (Only valid for audio products.) +// TODO(sergeyu): kAlsaEnableUpsampling and kAlsaCheckCloseTimeout are +// implemented in StreamMixer, which is not ALSA-specific - it's also used on +// Fuchsia. Rename these flags. extern const char kAlsaOutputBufferSize[]; extern const char kAlsaOutputPeriodSize[]; extern const char kAlsaOutputStartThreshold[]; @@ -51,6 +54,7 @@ extern const char kAlsaMuteElementName[]; extern const char kMaxOutputVolumeDba1m[]; extern const char kAudioOutputChannels[]; +extern const char kAudioOutputSampleRate[]; // Memory pressure switches extern const char kMemPressureSystemReservedKb[];
diff --git a/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc b/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc index 3656a6bc..2db91d4 100644 --- a/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc +++ b/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.cc
@@ -143,10 +143,6 @@ alsa_ = std::move(alsa); } -bool MixerOutputStreamAlsa::IsFixedSampleRate() { - return fixed_sample_rate_ != kInvalidSampleRate; -} - bool MixerOutputStreamAlsa::Start(int sample_rate, int channels) { if (!alsa_) { alsa_ = std::make_unique<AlsaWrapper>(); @@ -427,22 +423,9 @@ LOG(DFATAL) << "ALSA avail min must be no larger than the buffer size"; alsa_avail_min_ = alsa_period_size_; } - - fixed_sample_rate_ = GetSwitchValueNonNegativeInt( - switches::kAlsaFixedOutputSampleRate, kInvalidSampleRate); - if (fixed_sample_rate_ != kInvalidSampleRate) { - LOG(INFO) << "Setting fixed sample rate to " << fixed_sample_rate_; - } } int MixerOutputStreamAlsa::DetermineOutputRate(int requested_sample_rate) { - if (fixed_sample_rate_ != kInvalidSampleRate) { - LOG(INFO) << "Requested output rate is " << requested_sample_rate; - LOG(INFO) << "Cannot change rate since it is fixed to " - << fixed_sample_rate_; - return fixed_sample_rate_; - } - unsigned int unsigned_output_sample_rate = requested_sample_rate; // Try the requested sample rate. If the ALSA driver doesn't know how to deal
diff --git a/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.h b/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.h index eda0cc1..03f6fd2a 100644 --- a/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.h +++ b/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.h
@@ -27,7 +27,6 @@ void SetAlsaWrapperForTest(std::unique_ptr<AlsaWrapper> alsa); // MixerOutputStream interface. - bool IsFixedSampleRate() override; bool Start(int requested_sample_rate, int channels) override; bool GetTimeUntilUnderrun(base::TimeDelta* result) override; int GetSampleRate() override; @@ -57,9 +56,6 @@ void UpdateRenderingDelay(int newly_pushed_frames); - // Value of --alsa-fixed-output-sample-rate flag if any. - int fixed_sample_rate_ = kInvalidSampleRate; - std::unique_ptr<AlsaWrapper> alsa_; snd_pcm_t* pcm_ = nullptr;
diff --git a/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.cc b/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.cc index b01d810..262a71f 100644 --- a/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.cc +++ b/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.cc
@@ -39,10 +39,6 @@ fuchsia_audio_manager_free(manager_); } -bool MixerOutputStreamFuchsia::IsFixedSampleRate() { - return false; -} - bool MixerOutputStreamFuchsia::Start(int requested_sample_rate, int channels) { DCHECK(!stream_);
diff --git a/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.h b/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.h index dfcc2a2..7d3bb07 100644 --- a/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.h +++ b/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.h
@@ -21,7 +21,6 @@ ~MixerOutputStreamFuchsia() override; // MixerOutputStream interface. - bool IsFixedSampleRate() override; bool Start(int requested_sample_rate, int channels) override; bool GetTimeUntilUnderrun(base::TimeDelta* result) override; int GetSampleRate() override;
diff --git a/chromecast/media/cma/backend/mixer_output_stream.h b/chromecast/media/cma/backend/mixer_output_stream.h index 4331076b..334cba1 100644 --- a/chromecast/media/cma/backend/mixer_output_stream.h +++ b/chromecast/media/cma/backend/mixer_output_stream.h
@@ -26,9 +26,6 @@ virtual ~MixerOutputStream() {} - // Returns true if the sample rate is fixed. - virtual bool IsFixedSampleRate() = 0; - // Start the stream. Caller must call GetSampleRate() to get the actual sample // rate selected for the stream. It may be different from // |requested_sample_rate|, e.g. if IsFixedSampleRate() is true, or the device
diff --git a/chromecast/media/cma/backend/stream_mixer.cc b/chromecast/media/cma/backend/stream_mixer.cc index f39ba03e..057a699 100644 --- a/chromecast/media/cma/backend/stream_mixer.cc +++ b/chromecast/media/cma/backend/stream_mixer.cc
@@ -11,7 +11,6 @@ #include <utility> #include "base/bind_helpers.h" -#include "base/command_line.h" #include "base/lazy_instance.h" #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" @@ -152,13 +151,27 @@ num_output_channels_ == 1); low_sample_rate_cutoff_ = - chromecast::GetSwitchValueBoolean(switches::kAlsaEnableUpsampling, false) + GetSwitchValueBoolean(switches::kAlsaEnableUpsampling, false) ? kLowSampleRateCutoff : MixerOutputStream::kInvalidSampleRate; - // Read post-processing configuration file - PostProcessingPipelineParser pipeline_parser; + fixed_sample_rate_ = GetSwitchValueNonNegativeInt( + switches::kAudioOutputSampleRate, MixerOutputStream::kInvalidSampleRate); +#if defined(USE_ALSA) + if (fixed_sample_rate_ == MixerOutputStream::kInvalidSampleRate) { + fixed_sample_rate_ = + GetSwitchValueNonNegativeInt(switches::kAlsaFixedOutputSampleRate, + MixerOutputStream::kInvalidSampleRate); + } +#endif // defined(USE_ALSA) + + if (fixed_sample_rate_ != MixerOutputStream::kInvalidSampleRate) { + LOG(INFO) << "Setting fixed sample rate to " << fixed_sample_rate_; + } + + // Read post-processing configuration file. + PostProcessingPipelineParser pipeline_parser; CreatePostProcessors(&pipeline_parser); // TODO(jyw): command line flag for filter frame alignment. @@ -166,10 +179,10 @@ << "Alignment must be a power of 2."; // --accept-resource-provider should imply a check close timeout of 0. - int default_close_timeout = chromecast::GetSwitchValueBoolean( - switches::kAcceptResourceProvider, false) - ? 0 - : kDefaultCheckCloseTimeoutMs; + int default_close_timeout = + GetSwitchValueBoolean(switches::kAcceptResourceProvider, false) + ? 0 + : kDefaultCheckCloseTimeoutMs; check_close_timeout_ = GetSwitchValueInt(switches::kAlsaCheckCloseTimeout, default_close_timeout); } @@ -275,17 +288,20 @@ bool StreamMixer::Start() { DCHECK(mixer_task_runner_->BelongsToCurrentThread()); - int requested_sample_rate = requested_output_samples_per_second_; - if (!output_) output_ = MixerOutputStream::Create(); - if (low_sample_rate_cutoff_ != MixerOutputStream::kInvalidSampleRate && - requested_sample_rate < low_sample_rate_cutoff_) { + int requested_sample_rate; + if (fixed_sample_rate_ != MixerOutputStream::kInvalidSampleRate) { + requested_sample_rate = fixed_sample_rate_; + } else if (low_sample_rate_cutoff_ != MixerOutputStream::kInvalidSampleRate && + requested_output_samples_per_second_ < low_sample_rate_cutoff_) { requested_sample_rate = output_samples_per_second_ != MixerOutputStream::kInvalidSampleRate ? output_samples_per_second_ : kLowSampleRateFallback; + } else { + requested_sample_rate = requested_output_samples_per_second_; } if (!output_->Start(requested_sample_rate, num_output_channels_)) { @@ -357,7 +373,8 @@ // If the new input is a primary one, we may need to change the output // sample rate to match its input sample rate. // We only change the output rate if it is not set to a fixed value. - if (input->primary() && output_ && !output_->IsFixedSampleRate()) { + if (input->primary() && output_ && + fixed_sample_rate_ != MixerOutputStream::kInvalidSampleRate) { CheckChangeOutputRate(input->input_samples_per_second()); }
diff --git a/chromecast/media/cma/backend/stream_mixer.h b/chromecast/media/cma/backend/stream_mixer.h index 9282525..517ddaf 100644 --- a/chromecast/media/cma/backend/stream_mixer.h +++ b/chromecast/media/cma/backend/stream_mixer.h
@@ -281,6 +281,7 @@ int requested_output_samples_per_second_ = 0; int output_samples_per_second_ = 0; int low_sample_rate_cutoff_ = 0; + int fixed_sample_rate_ = 0; State state_;
diff --git a/chromecast/tracing/BUILD.gn b/chromecast/tracing/BUILD.gn new file mode 100644 index 0000000..4893411 --- /dev/null +++ b/chromecast/tracing/BUILD.gn
@@ -0,0 +1,51 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//chromecast/chromecast.gni") +import("//testing/test.gni") + +assert(!is_fuchsia) + +cast_source_set("system_tracing_common") { + sources = [ + "system_tracing_common.cc", + "system_tracing_common.h", + ] + + deps = [ + "//base", + ] +} + +cast_executable("traced") { + sources = [ + "ftrace.cc", + "ftrace.h", + "tracing_service_main.cc", + ] + + deps = [ + ":system_tracing_common", + "//base", + ] +} + +cast_source_set("system_tracer") { + sources = [ + "system_tracer.cc", + "system_tracer.h", + ] + + public_deps = [ + ":system_tracing_common", + "//base", + ] +} + +group("tracing") { + deps = [ + ":system_tracing_common", + ":traced", + ] +}
diff --git a/chromecast/tracing/OWNERS b/chromecast/tracing/OWNERS new file mode 100644 index 0000000..35a2760 --- /dev/null +++ b/chromecast/tracing/OWNERS
@@ -0,0 +1 @@ +spang@chromium.org
diff --git a/chromecast/tracing/ftrace.cc b/chromecast/tracing/ftrace.cc new file mode 100644 index 0000000..6f38bfc --- /dev/null +++ b/chromecast/tracing/ftrace.cc
@@ -0,0 +1,205 @@ +// 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 "chromecast/tracing/ftrace.h" + +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include "base/files/file_util.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_util.h" +#include "base/trace_event/common/trace_event_common.h" +#include "chromecast/tracing/system_tracing_common.h" + +namespace chromecast { +namespace tracing { +namespace { + +const char kPathTracefs[] = "/sys/kernel/tracing"; +const char kTraceFileTracingOn[] = "tracing_on"; +const char kTraceFileTraceMarker[] = "trace_marker"; +const char kTraceFileSetEvent[] = "set_event"; +const char kTraceFileTraceClock[] = "trace_clock"; +const char kTraceFileTrace[] = "trace"; +const char kTraceFileBufferSizeKb[] = "buffer_size_kb"; + +const char kBufferSizeKbRunning[] = "7040"; +const char kBufferSizeKbIdle[] = "1408"; + +// TODO(spang): Load these lists from a configuration file. +const char* const kGfxEvents[] = { + "i915:i915_flip_request", "i915:i915_flip_complete", + "i915:i915_gem_object_pwrite", "i915:intel_gpu_freq_change", + "exynos:exynos_flip_request", "exynos:exynos_flip_complete", + "exynos:exynos_page_flip_state", "drm:drm_vblank_event", +}; + +const char* const kInputEvents[] = { + "irq:irq_threaded_handler_entry", "irq:irq_threaded_handler_exit", +}; + +const char* const kIrqEvents[] = { + "irq:irq_handler_exit", "irq:irq_handler_entry", +}; + +const char* const kPowerEvents[] = { + "power:cpu_idle", + "power:cpu_frequency", + "mali:mali_dvfs_set_clock", + "mali:mali_dvfs_set_voltage", + "cpufreq_interactive:cpufreq_interactive_boost", + "cpufreq_interactive:cpufreq_interactive_unboost", + "exynos_busfreq:exynos_busfreq_target_int", + "exynos_busfreq:exynos_busfreq_target_mif", +}; + +const char* const kSchedEvents[] = { + "sched:sched_switch", "sched:sched_wakeup", +}; + +const char* const kWorkqEvents[] = { + "workqueue:workqueue_execute_start", "workqueue:workqueue_execute_end", +}; + +void AddCategoryEvents(const std::string& category, + std::vector<std::string>* events) { + if (category == "gfx") { + std::copy(kGfxEvents, kGfxEvents + arraysize(kGfxEvents), + std::back_inserter(*events)); + return; + } + if (category == "input") { + std::copy(kInputEvents, kInputEvents + arraysize(kInputEvents), + std::back_inserter(*events)); + return; + } + if (category == TRACE_DISABLED_BY_DEFAULT("irq")) { + std::copy(kIrqEvents, kIrqEvents + arraysize(kIrqEvents), + std::back_inserter(*events)); + return; + } + if (category == "power") { + std::copy(kPowerEvents, kPowerEvents + arraysize(kPowerEvents), + std::back_inserter(*events)); + return; + } + if (category == "sched") { + std::copy(kSchedEvents, kSchedEvents + arraysize(kSchedEvents), + std::back_inserter(*events)); + return; + } + if (category == "workq") { + std::copy(kWorkqEvents, kWorkqEvents + arraysize(kWorkqEvents), + std::back_inserter(*events)); + return; + } + + LOG(WARNING) << "Unrecognized category: " << category; +} + +bool WriteTracingFile(const char* trace_file, base::StringPiece contents) { + base::FilePath path = base::FilePath(kPathTracefs).Append(trace_file); + + if (!base::WriteFile(path, contents.data(), contents.size())) { + PLOG(ERROR) << "write: " << path; + return false; + } + + return true; +} + +bool EnableTraceEvent(base::StringPiece event) { + base::FilePath path = base::FilePath(kPathTracefs).Append(kTraceFileSetEvent); + + // Enabling events returns EINVAL if the event does not exist. It is normal + // for driver specific events to be missing when the driver is not built in. + if (!base::AppendToFile(path, event.data(), event.size()) && + errno != EINVAL) { + PLOG(ERROR) << "write: " << path; + return false; + } + + return true; +} + +} // namespace + +bool IsValidCategory(base::StringPiece str) { + for (size_t i = 0; i < kCategoryCount; ++i) { + base::StringPiece category(kCategories[i]); + if (category == str) + return true; + } + + return false; +} + +bool StartFtrace(const std::vector<std::string>& categories) { + if (categories.size() == 0) { + LOG(ERROR) << "No categories to enable"; + return false; + } + + std::vector<std::string> events; + for (const auto& category : categories) + AddCategoryEvents(category, &events); + + if (events.size() == 0) { + LOG(ERROR) << "No events to enable"; + return false; + } + + // Disable tracing and clear events. + if (!WriteTracingFile(kTraceFileTracingOn, "0")) + return false; + if (!WriteTracingFile(kTraceFileSetEvent, "\n")) + return false; + + // Use CLOCK_MONOTONIC so that kernel timestamps align with std::steady_clock + // and base::TimeTicks. + if (!WriteTracingFile(kTraceFileTraceClock, "mono")) + return false; + + for (const auto& event : events) + EnableTraceEvent(event); + + if (!WriteTracingFile(kTraceFileBufferSizeKb, kBufferSizeKbRunning)) + return false; + if (!WriteTracingFile(kTraceFileTracingOn, "1")) + return false; + + return true; +} + +bool WriteFtraceTimeSyncMarker() { + return WriteTracingFile(kTraceFileTraceMarker, + "trace_event_clock_sync: parent_ts=0"); +} + +bool StopFtrace() { + if (!WriteTracingFile(kTraceFileTracingOn, "0")) + return false; + return true; +} + +base::ScopedFD GetFtraceData() { + base::FilePath path = base::FilePath(kPathTracefs).Append(kTraceFileTrace); + base::ScopedFD trace_data(HANDLE_EINTR( + open(path.value().c_str(), O_RDONLY | O_CLOEXEC | O_NONBLOCK))); + if (!trace_data.is_valid()) + PLOG(ERROR) << "open: " << path.value(); + return trace_data; +} + +bool ClearFtrace() { + if (!WriteTracingFile(kTraceFileBufferSizeKb, kBufferSizeKbIdle)) + return false; + if (!WriteTracingFile(kTraceFileTrace, "0")) + return false; + return true; +} + +} // namespace tracing +} // namespace chromecast
diff --git a/chromecast/tracing/ftrace.h b/chromecast/tracing/ftrace.h new file mode 100644 index 0000000..92adc68 --- /dev/null +++ b/chromecast/tracing/ftrace.h
@@ -0,0 +1,50 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMECAST_TRACING_FTRACE_H_ +#define CHROMECAST_TRACING_FTRACE_H_ + +#include <string> +#include <vector> + +#include "base/files/scoped_file.h" +#include "base/strings/string_piece.h" + +namespace chromecast { +namespace tracing { + +// Returns true if |category| is valid for system tracing. +bool IsValidCategory(base::StringPiece category); + +// Starts ftrace for the specified categories. +// +// This must be paired with StopFtrace() or the kernel will continue tracing +// indefinitely. Returns false if an error occurs writing to tracefs - this +// usually indicates a configuration issue (e.g. tracefs not mounted). +bool StartFtrace(const std::vector<std::string>& categories); + +// Writes time synchronization marker. +// +// This is used by trace-viewer to align ftrace clock with userspace +// tracing. Since CLOCK_MONOTONIC is used in both cases, this merely +// writes a zero offset. Call it at the end of tracing right before +// StopFtrace(). Returns false if an error occurs writing to tracefs. +bool WriteFtraceTimeSyncMarker(); + +// Stops ftrace. +// +// This is safe to call even if tracing isn't started. Returns false if an error +// occurs writing to tracefs. +bool StopFtrace(); + +// Opens ftrace buffer for reading. +base::ScopedFD GetFtraceData(); + +// Clears ftrace buffer. Returns false if an error occurs writing to tracefs. +bool ClearFtrace(); + +} // namespace tracing +} // namespace chromecast + +#endif // CHROMECAST_TRACING_FTRACE_H_
diff --git a/chromecast/tracing/system_tracer.cc b/chromecast/tracing/system_tracer.cc new file mode 100644 index 0000000..bb487bb7 --- /dev/null +++ b/chromecast/tracing/system_tracer.cc
@@ -0,0 +1,200 @@ +// 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 "chromecast/tracing/system_tracer.h" + +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/un.h> +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/logging.h" +#include "base/message_loop/message_loop.h" +#include "base/message_loop/message_pump_libevent.h" +#include "base/posix/eintr_wrapper.h" +#include "base/posix/unix_domain_socket.h" +#include "base/trace_event/trace_config.h" +#include "chromecast/tracing/system_tracing_common.h" + +namespace chromecast { +namespace { + +constexpr size_t kBufferSize = 1UL << 16; + +base::ScopedFD CreateClientSocket() { + base::ScopedFD socket_fd( + socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); + if (!socket_fd.is_valid()) { + PLOG(ERROR) << "socket"; + return base::ScopedFD(); + } + + struct sockaddr_un addr = + chromecast::tracing::GetSystemTracingSocketAddress(); + + if (connect(socket_fd.get(), reinterpret_cast<struct sockaddr*>(&addr), + sizeof(addr))) { + PLOG(ERROR) << "connect: " << addr.sun_path; + return base::ScopedFD(); + } + + return socket_fd; +} + +} // namespace + +SystemTracer::SystemTracer() : buffer_(new char[kBufferSize]) {} + +SystemTracer::~SystemTracer() { + Cleanup(); +} + +void SystemTracer::StartTracing(base::StringPiece categories, + StartTracingCallback callback) { + start_tracing_callback_ = std::move(callback); + if (state_ != State::INITIAL) { + FailStartTracing(); + return; + } + + if (categories.size() == 0) { + // No relevant categories are enabled. + FailStartTracing(); + return; + } + + connection_fd_ = CreateClientSocket(); + if (!connection_fd_.is_valid()) { + FailStartTracing(); + return; + } + + if (!base::UnixDomainSocket::SendMsg(connection_fd_.get(), categories.data(), + categories.size(), std::vector<int>())) { + PLOG(ERROR) << "sendmsg"; + FailStartTracing(); + return; + } + + connection_watcher_ = base::FileDescriptorWatcher::WatchReadable( + connection_fd_.get(), + base::BindRepeating(&SystemTracer::ReceiveStartAckAndTracePipe, + base::Unretained(this))); + state_ = State::STARTING; +} + +void SystemTracer::StopTracing(const StopTracingCallback& callback) { + stop_tracing_callback_ = callback; + if (state_ != State::TRACING) { + FailStopTracing(); + return; + } + + char stop_tracing_message[] = {0}; + if (!base::UnixDomainSocket::SendMsg( + connection_fd_.get(), stop_tracing_message, + sizeof(stop_tracing_message), std::vector<int>())) { + PLOG(ERROR) << "sendmsg"; + FailStopTracing(); + return; + } + + trace_pipe_watcher_ = base::FileDescriptorWatcher::WatchReadable( + trace_pipe_fd_.get(), base::BindRepeating(&SystemTracer::ReceiveTraceData, + base::Unretained(this))); + state_ = State::READING; +} + +void SystemTracer::ReceiveStartAckAndTracePipe() { + DCHECK_EQ(state_, State::STARTING); + + std::vector<base::ScopedFD> fds; + ssize_t received = base::UnixDomainSocket::RecvMsg( + connection_fd_.get(), buffer_.get(), kBufferSize, &fds); + if (received == 0) { + LOG(ERROR) << "EOF from server"; + FailStartTracing(); + return; + } + if (received < 0) { + PLOG(ERROR) << "recvmsg"; + FailStartTracing(); + return; + } + if (fds.size() != 1) { + LOG(ERROR) << "Start ack missing trace pipe"; + FailStartTracing(); + return; + } + + trace_pipe_fd_ = std::move(fds[0]); + connection_watcher_.reset(); + state_ = State::TRACING; + std::move(start_tracing_callback_).Run(Status::OK); +} + +void SystemTracer::ReceiveTraceData() { + DCHECK_EQ(state_, State::READING); + + for (;;) { + ssize_t bytes = + HANDLE_EINTR(read(trace_pipe_fd_.get(), buffer_.get(), kBufferSize)); + if (bytes < 0) { + if (errno == EAGAIN) + return; // Wait for more data. + PLOG(ERROR) << "read: trace"; + FailStopTracing(); + return; + } + + if (bytes == 0) { + FinishTracing(); + return; + } + + trace_data_.append(buffer_.get(), bytes); + + static constexpr size_t kPartialTraceDataSize = 1UL << 20; // 1 MiB + if (trace_data_.size() > kPartialTraceDataSize) { + SendPartialTraceData(); + return; + } + } +} + +void SystemTracer::FailStartTracing() { + std::move(start_tracing_callback_).Run(Status::FAIL); + Cleanup(); +} + +void SystemTracer::FailStopTracing() { + stop_tracing_callback_.Run(Status::FAIL, ""); + Cleanup(); +} + +void SystemTracer::SendPartialTraceData() { + DCHECK_EQ(state_, State::READING); + stop_tracing_callback_.Run(Status::KEEP_GOING, std::move(trace_data_)); + trace_data_ = ""; +} + +void SystemTracer::FinishTracing() { + DCHECK_EQ(state_, State::READING); + stop_tracing_callback_.Run(Status::OK, std::move(trace_data_)); + Cleanup(); +} + +void SystemTracer::Cleanup() { + connection_watcher_.reset(); + connection_fd_.reset(); + trace_pipe_watcher_.reset(); + trace_pipe_fd_.reset(); + start_tracing_callback_.Reset(); + stop_tracing_callback_.Reset(); + state_ = State::FINISHED; +} + +} // namespace chromecast
diff --git a/chromecast/tracing/system_tracer.h b/chromecast/tracing/system_tracer.h new file mode 100644 index 0000000..89d4f09 --- /dev/null +++ b/chromecast/tracing/system_tracer.h
@@ -0,0 +1,88 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMECAST_TRACING_SYSTEM_TRACER_H_ +#define CHROMECAST_TRACING_SYSTEM_TRACER_H_ + +#include <memory> +#include <string> + +#include "base/callback.h" +#include "base/files/file_descriptor_watcher_posix.h" +#include "base/files/scoped_file.h" +#include "base/macros.h" +#include "base/message_loop/message_pump_libevent.h" + +namespace chromecast { + +class SystemTracer { + public: + SystemTracer(); + ~SystemTracer(); + + enum class Status { + OK, + KEEP_GOING, + FAIL, + }; + + using StartTracingCallback = base::OnceCallback<void(Status)>; + using StopTracingCallback = + base::RepeatingCallback<void(Status status, std::string trace_data)>; + + // Start system tracing for categories in |categories| (comma separated). + void StartTracing(base::StringPiece categories, + StartTracingCallback callback); + + // Stop system tracing. + // + // This will call |callback| on the current thread with the trace data. If + // |status| is Status::KEEP_GOING, another call will be made with additional + // data. + void StopTracing(const StopTracingCallback& callback); + + private: + enum class State { + INITIAL, // Not yet started. + STARTING, // Sent start message, waiting for ack. + TRACING, // Tracing, not yet requested stop. + READING, // Trace stopped, reading output. + FINISHED, // All done. + }; + + void ReceiveStartAckAndTracePipe(); + void ReceiveTraceData(); + void FailStartTracing(); + void FailStopTracing(); + void SendPartialTraceData(); + void FinishTracing(); + void Cleanup(); + + // Current state of tracing attempt. + State state_ = State::INITIAL; + + // Unix socket connection to tracing daemon. + base::ScopedFD connection_fd_; + std::unique_ptr<base::FileDescriptorWatcher::Controller> connection_watcher_; + + // Pipe for trace data. + base::ScopedFD trace_pipe_fd_; + std::unique_ptr<base::FileDescriptorWatcher::Controller> trace_pipe_watcher_; + + // Read buffer (of size kBufferSize). + std::unique_ptr<char[]> buffer_; + + // Callbacks for StartTracing() and StopTracing(). + StartTracingCallback start_tracing_callback_; + StopTracingCallback stop_tracing_callback_; + + // Trace data. + std::string trace_data_; + + DISALLOW_COPY_AND_ASSIGN(SystemTracer); +}; + +} // namespace chromecast + +#endif // CHROMECAST_TRACING_SYSTEM_TRACER_H_
diff --git a/chromecast/tracing/system_tracing_common.cc b/chromecast/tracing/system_tracing_common.cc new file mode 100644 index 0000000..c88f721 --- /dev/null +++ b/chromecast/tracing/system_tracing_common.cc
@@ -0,0 +1,36 @@ +// 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 "chromecast/tracing/system_tracing_common.h" + +#include <string.h> +#include "base/macros.h" +#include "base/trace_event/common/trace_event_common.h" + +namespace chromecast { +namespace tracing { +namespace { + +const char kSocketPath[] = "/dev/socket/tracing/tracing"; + +} // namespace + +const char* const kCategories[] = { + "gfx", "input", TRACE_DISABLED_BY_DEFAULT("irq"), + "power", "sched", "workq"}; + +const size_t kCategoryCount = arraysize(kCategories); + +sockaddr_un GetSystemTracingSocketAddress() { + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + static_assert(sizeof(kSocketPath) <= sizeof(addr.sun_path), + "Address too long"); + strncpy(addr.sun_path, kSocketPath, sizeof(addr.sun_path) - 1); + addr.sun_family = AF_UNIX; + return addr; +} + +} // namespace tracing +} // namespace chromecast
diff --git a/chromecast/tracing/system_tracing_common.h b/chromecast/tracing/system_tracing_common.h new file mode 100644 index 0000000..d7e3a8f --- /dev/null +++ b/chromecast/tracing/system_tracing_common.h
@@ -0,0 +1,23 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROMECAST_TRACING_SYSTEM_TRACING_COMMON_H_ +#define CHROMECAST_TRACING_SYSTEM_TRACING_COMMON_H_ + +#include <sys/socket.h> +#include <sys/un.h> + +namespace chromecast { +namespace tracing { + +extern const char* const kCategories[]; + +extern const size_t kCategoryCount; + +sockaddr_un GetSystemTracingSocketAddress(); + +} // namespace tracing +} // namespace chromecast + +#endif // CHROMECAST_TRACING_SYSTEM_TRACING_COMMON_H_
diff --git a/chromecast/tracing/tracing_service_main.cc b/chromecast/tracing/tracing_service_main.cc new file mode 100644 index 0000000..7a754b0 --- /dev/null +++ b/chromecast/tracing/tracing_service_main.cc
@@ -0,0 +1,412 @@ +// 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 <fcntl.h> +#include <signal.h> +#include <sys/socket.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/un.h> +#include <memory> + +#include "base/at_exit.h" +#include "base/bind.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "base/memory/weak_ptr.h" +#include "base/message_loop/message_loop.h" +#include "base/posix/eintr_wrapper.h" +#include "base/posix/unix_domain_socket.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" +#include "base/threading/thread_task_runner_handle.h" +#include "base/time/time.h" +#include "chromecast/tracing/ftrace.h" +#include "chromecast/tracing/system_tracing_common.h" + +namespace chromecast { +namespace tracing { +namespace { + +constexpr size_t kMessageSize = 4096; + +base::ScopedFD CreateServerSocket() { + struct sockaddr_un addr = GetSystemTracingSocketAddress(); + + if (unlink(addr.sun_path) != 0 && errno != ENOENT) + PLOG(ERROR) << "unlink: " << addr.sun_path; + + base::ScopedFD socket_fd( + socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, 0)); + if (!socket_fd.is_valid()) { + PLOG(ERROR) << "socket"; + return base::ScopedFD(); + } + + if (bind(socket_fd.get(), reinterpret_cast<struct sockaddr*>(&addr), + sizeof(addr))) { + PLOG(ERROR) << "bind: " << addr.sun_path; + return base::ScopedFD(); + } + + if (chmod(addr.sun_path, 0666)) + PLOG(WARNING) << "chmod: " << addr.sun_path; + + static constexpr int kBacklog = 10; + if (listen(socket_fd.get(), kBacklog)) { + PLOG(ERROR) << "listen: " << addr.sun_path; + return base::ScopedFD(); + } + + return socket_fd; +} + +std::vector<std::string> ParseCategories(base::StringPiece message) { + std::vector<std::string> requested_categories = base::SplitString( + message, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL); + std::vector<std::string> categories; + for (const auto& category : requested_categories) { + if (IsValidCategory(category)) + categories.push_back(category); + else + LOG(WARNING) << "Unrecognized category: " << category; + } + return categories; +} + +class TraceCopyTask : public base::MessagePumpLibevent::Watcher { + public: + // Read 64 kB at a time (standard pipe capacity). + static constexpr size_t kCopyBufferSize = 1UL << 16; + + enum class Status { + SUCCESS, + FAILURE, + }; + + TraceCopyTask(base::ScopedFD in_fd, + base::ScopedFD out_fd, + base::OnceCallback<void(Status, size_t)> callback) + : buffer_(new char[kCopyBufferSize]), + in_fd_(std::move(in_fd)), + out_fd_(std::move(out_fd)), + out_watcher_(FROM_HERE), + callback_(std::move(callback)) {} + virtual ~TraceCopyTask() {} + + void Start() { + base::MessageLoopForIO::current()->WatchFileDescriptor( + out_fd_.get(), true /* persistent */, + base::MessageLoopForIO::WATCH_WRITE, &out_watcher_, this); + } + + // base::MessagePumpLibevent::Watcher: + void OnFileCanReadWithoutBlocking(int fd) override { NOTREACHED(); } + void OnFileCanWriteWithoutBlocking(int fd) override { + DCHECK_EQ(out_fd_.get(), fd); + CopyTraceData(); + } + + private: + void CopyTraceData() { + for (;;) { + if (read_ == written_) { + total_copied_ += read_; + read_ = written_ = 0; + + // Read trace data from debugfs. + ssize_t read_bytes = + HANDLE_EINTR(read(in_fd_.get(), buffer_.get(), kCopyBufferSize)); + if (read_bytes == 0) { + // EOF, we're done; + Finish(Status::SUCCESS); + return; + } else if (read_bytes < 0) { + PLOG(ERROR) << "read: trace"; + Finish(Status::FAILURE); + return; + } + + read_ = read_bytes; + } + + // Write trace data to output pipe. + ssize_t written_bytes = HANDLE_EINTR( + write(out_fd_.get(), buffer_.get() + written_, read_ - written_)); + if (written_bytes < 0) { + if (errno == EAGAIN) + return; // Wait for more space. + PLOG(ERROR) << "write: pipe"; + Finish(Status::FAILURE); + return; + } + written_ += written_bytes; + } + } + + void Finish(Status status) { + out_watcher_.StopWatchingFileDescriptor(); + in_fd_.reset(); + out_fd_.reset(); + buffer_.reset(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback_), status, total_copied_)); + } + + std::unique_ptr<char[]> buffer_; + size_t read_ = 0; + size_t written_ = 0; + size_t total_copied_ = 0; + + // Trace data file. + base::ScopedFD in_fd_; + + // Pipe for trace data. + base::ScopedFD out_fd_; + base::MessagePumpLibevent::FileDescriptorWatcher out_watcher_; + + // Callback for when copy finishes. + base::OnceCallback<void(Status, size_t)> callback_; +}; + +class TraceConnection : public base::MessagePumpLibevent::Watcher { + public: + TraceConnection(base::ScopedFD connection_fd, base::OnceClosure callback) + : recv_buffer_(new char[kMessageSize]), + connection_fd_(std::move(connection_fd)), + connection_watcher_(FROM_HERE), + callback_(std::move(callback)), + weak_ptr_factory_(this) {} + virtual ~TraceConnection() {} + + void Init() { + base::MessageLoopForIO::current()->WatchFileDescriptor( + connection_fd_.get(), true /* persistent */, + base::MessageLoopForIO::WATCH_READ, &connection_watcher_, this); + } + + // base::MessagePumpLibevent::Watcher: + void OnFileCanReadWithoutBlocking(int fd) override { + DCHECK_EQ(connection_fd_.get(), fd); + ReceiveClientMessage(); + } + void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); } + + private: + enum class State { + INITIAL, // Waiting for init message + TRACING, // Ftrace started. + COPYING, // Ftrace stopped, copying trace data. + COPY_COMPLETE, // Ftrace stopped, all data written to pipe. + FINISHED, // All done. + }; + + void ReceiveClientMessage() { + std::vector<base::ScopedFD> fds; + ssize_t bytes = base::UnixDomainSocket::RecvMsg( + connection_fd_.get(), recv_buffer_.get(), kMessageSize, &fds); + if (bytes < 0) { + PLOG(ERROR) << "recvmsg"; + Finish(); + return; + } else if (bytes == 0) { + LOG(INFO) << "connection closed"; + Finish(); + } else { + base::StringPiece message(recv_buffer_.get(), bytes); + HandleClientMessage(message); + } + } + + void HandleClientMessage(base::StringPiece message) { + if (state_ == State::INITIAL) { + std::vector<std::string> categories = ParseCategories(message); + + if (!StartFtrace(categories)) { + LOG(ERROR) << "Failed to start ftrace"; + Finish(); + return; + } + + if (!SendTracePipeToClient()) { + LOG(ERROR) << "Failed to send trace pipe"; + Finish(); + return; + } + + LOG(INFO) << "Started tracing for categories: " + << base::JoinString(categories, ","); + + state_ = State::TRACING; + } else if (state_ == State::TRACING) { + WriteFtraceTimeSyncMarker(); + StopFtrace(); + base::ScopedFD trace_data = GetFtraceData(); + if (!trace_data.is_valid()) { + LOG(ERROR) << "Failed to get trace data"; + Finish(); + return; + } + + LOG(INFO) << "Tracing stopped"; + trace_copy_task_ = std::make_unique<TraceCopyTask>( + std::move(trace_data), std::move(trace_pipe_), + base::BindOnce(&TraceConnection::OnFinishedCopying, + weak_ptr_factory_.GetWeakPtr())); + trace_copy_task_->Start(); + state_ = State::COPYING; + } else { + LOG(WARNING) << "Unexpected message"; + Finish(); + return; + } + } + + void OnFinishedCopying(TraceCopyTask::Status status, size_t trace_data_size) { + if (status == TraceCopyTask::Status::SUCCESS) { + LOG(INFO) << "Finished tracing (" << trace_data_size << " bytes copied)"; + state_ = State::COPY_COMPLETE; + } else { + LOG(INFO) << "I/O error copying trace data"; + } + + Finish(); + } + + bool SendTracePipeToClient() { + int pipefd[2] = {-1, -1}; + if (pipe2(pipefd, O_CLOEXEC | O_NONBLOCK)) { + PLOG(ERROR) << "pipe2"; + return false; + } + base::ScopedFD read_end(pipefd[0]); + base::ScopedFD write_end(pipefd[1]); + + const char response[] = {0}; + std::vector<int> send_fds; + send_fds.push_back(read_end.get()); + if (!base::UnixDomainSocket::SendMsg(connection_fd_.get(), response, + sizeof(response), send_fds)) { + PLOG(ERROR) << "sendmsg"; + return false; + } + + trace_pipe_ = std::move(write_end); + return true; + } + + void Finish() { + if (state_ != State::COPY_COMPLETE) + LOG(WARNING) << "Ending tracing without sending data"; + trace_copy_task_.reset(); + state_ = State::FINISHED; + recv_buffer_.reset(); + connection_watcher_.StopWatchingFileDescriptor(); + connection_fd_.reset(); + StopFtrace(); + ClearFtrace(); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback_))); + } + + // Tracing state. + State state_ = State::INITIAL; + + // Buffer for incoming messages. + std::unique_ptr<char[]> recv_buffer_; + + // Client connection. + base::ScopedFD connection_fd_; + base::MessagePumpLibevent::FileDescriptorWatcher connection_watcher_; + + // Pipe for trace output. + base::ScopedFD trace_pipe_; + + // Task to send all trace output to client via a pipe. + std::unique_ptr<TraceCopyTask> trace_copy_task_; + + // Callback for when connection closes. + base::OnceClosure callback_; + + base::WeakPtrFactory<TraceConnection> weak_ptr_factory_; +}; + +class TracingService : public base::MessagePumpLibevent::Watcher { + public: + TracingService() + : server_socket_watcher_(FROM_HERE), weak_ptr_factory_(this) {} + virtual ~TracingService() {} + + bool Init() { + server_socket_ = CreateServerSocket(); + if (!server_socket_.is_valid()) + return false; + + base::MessageLoopForIO::current()->WatchFileDescriptor( + server_socket_.get(), true /* persistent */, + base::MessageLoopForIO::WATCH_READ, &server_socket_watcher_, this); + + return true; + } + + // base::MessagePumpLibevent::Watcher: + void OnFileCanReadWithoutBlocking(int fd) override { + DCHECK_EQ(server_socket_.get(), fd); + AcceptConnection(); + } + void OnFileCanWriteWithoutBlocking(int fd) override { NOTREACHED(); } + + private: + void AcceptConnection() { + base::ScopedFD connection_fd(accept4(server_socket_.get(), nullptr, nullptr, + SOCK_NONBLOCK | SOCK_CLOEXEC)); + if (!connection_fd.is_valid()) { + PLOG(ERROR) << "accept: "; + return; + } + + trace_connection_ = std::make_unique<TraceConnection>( + std::move(connection_fd), + base::BindOnce(&TracingService::OnConnectionClosed, + weak_ptr_factory_.GetWeakPtr())); + trace_connection_->Init(); + } + + void OnConnectionClosed() { trace_connection_.reset(); } + + // Socket and watcher for listening socket. + base::ScopedFD server_socket_; + base::MessagePumpLibevent::FileDescriptorWatcher server_socket_watcher_; + + // Currently active tracing connection. + // There can only be one; ftrace affects the whole system. + std::unique_ptr<TraceConnection> trace_connection_; + + base::WeakPtrFactory<TracingService> weak_ptr_factory_; +}; + +} // namespace +} // namespace tracing +} // namespace chromecast + +int main(int argc, char** argv) { + base::AtExitManager exit_manager; + base::CommandLine::Init(argc, argv); + logging::InitLogging(logging::LoggingSettings()); + + signal(SIGPIPE, SIG_IGN); + + LOG(INFO) << "Starting system tracing service..."; + + base::MessageLoopForIO message_loop; + chromecast::tracing::TracingService service; + + if (!service.Init()) + return EXIT_FAILURE; + + base::RunLoop run_loop; + run_loop.Run(); + + return EXIT_SUCCESS; +}
diff --git a/chromeos/dbus/cros_disks_client.cc b/chromeos/dbus/cros_disks_client.cc index 3b0c08d8..44b40c7 100644 --- a/chromeos/dbus/cros_disks_client.cc +++ b/chromeos/dbus/cros_disks_client.cc
@@ -141,15 +141,24 @@ // CrosDisksClient override. void EnumerateAutoMountableDevices( - const EnumerateAutoMountableDevicesCallback& callback, + const EnumerateDevicesCallback& callback, const base::Closure& error_callback) override { dbus::MethodCall method_call(cros_disks::kCrosDisksInterface, cros_disks::kEnumerateAutoMountableDevices); - proxy_->CallMethod( - &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, - base::BindOnce(&CrosDisksClientImpl::OnEnumerateAutoMountableDevices, - weak_ptr_factory_.GetWeakPtr(), callback, - error_callback)); + proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::BindOnce(&CrosDisksClientImpl::OnEnumerateDevices, + weak_ptr_factory_.GetWeakPtr(), callback, + error_callback)); + } + + void EnumerateDevices(const EnumerateDevicesCallback& callback, + const base::Closure& error_callback) override { + dbus::MethodCall method_call(cros_disks::kCrosDisksInterface, + cros_disks::kEnumerateDevices); + proxy_->CallMethod(&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, + base::BindOnce(&CrosDisksClientImpl::OnEnumerateDevices, + weak_ptr_factory_.GetWeakPtr(), callback, + error_callback)); } // CrosDisksClient override. @@ -331,12 +340,11 @@ callback.Run(); } - // Handles the result of EnumerateAutoMountableDevices and calls |callback| or - // |error_callback|. - void OnEnumerateAutoMountableDevices( - const EnumerateAutoMountableDevicesCallback& callback, - const base::Closure& error_callback, - dbus::Response* response) { + // Handles the result of EnumerateDevices and EnumarateAutoMountableDevices. + // Calls |callback| or |error_callback|. + void OnEnumerateDevices(const EnumerateDevicesCallback& callback, + const base::Closure& error_callback, + dbus::Response* response) { if (!response) { error_callback.Run(); return; @@ -497,10 +505,11 @@ has_media_(false), on_boot_device_(false), on_removable_device_(false), - device_type_(DEVICE_TYPE_UNKNOWN), - total_size_in_bytes_(0), is_read_only_(false), - is_hidden_(true) { + is_hidden_(true), + is_virtual_(false), + device_type_(DEVICE_TYPE_UNKNOWN), + total_size_in_bytes_(0) { InitializeFromResponse(response); } @@ -627,6 +636,8 @@ cros_disks::kDeviceIsOnBootDevice, &on_boot_device_); properties->GetBooleanWithoutPathExpansion( cros_disks::kDeviceIsOnRemovableDevice, &on_removable_device_); + properties->GetBooleanWithoutPathExpansion(cros_disks::kDeviceIsVirtual, + &is_virtual_); properties->GetStringWithoutPathExpansion( cros_disks::kNativePath, &system_path_); properties->GetStringWithoutPathExpansion(
diff --git a/chromeos/dbus/cros_disks_client.h b/chromeos/dbus/cros_disks_client.h index 8b80ec6..d571986 100644 --- a/chromeos/dbus/cros_disks_client.h +++ b/chromeos/dbus/cros_disks_client.h
@@ -162,6 +162,15 @@ // Is the disk on a removable device. bool on_removable_device() const { return on_removable_device_; } + // Is the device read-only. + bool is_read_only() const { return is_read_only_; } + + // Returns true if the device should be hidden from the file browser. + bool is_hidden() const { return is_hidden_; } + + // Is the disk virtual. + bool is_virtual() const { return is_virtual_; } + // Disk file path (e.g. /dev/sdb). const std::string& file_path() const { return file_path_; } @@ -189,12 +198,6 @@ // Total size of the disk in bytes. uint64_t total_size_in_bytes() const { return total_size_in_bytes_; } - // Is the device read-only. - bool is_read_only() const { return is_read_only_; } - - // Returns true if the device should be hidden from the file browser. - bool is_hidden() const { return is_hidden_; } - // Returns file system uuid. const std::string& uuid() const { return uuid_; } @@ -211,6 +214,9 @@ bool has_media_; bool on_boot_device_; bool on_removable_device_; + bool is_read_only_; + bool is_hidden_; + bool is_virtual_; std::string file_path_; std::string label_; @@ -221,8 +227,6 @@ std::string drive_model_; DeviceType device_type_; uint64_t total_size_in_bytes_; - bool is_read_only_; - bool is_hidden_; std::string uuid_; std::string file_system_type_; }; @@ -261,10 +265,10 @@ // by callbacks. class CHROMEOS_EXPORT CrosDisksClient : public DBusClient { public: - // A callback to handle the result of EnumerateAutoMountableDevices. - // The argument is the enumerated device paths. + // A callback to handle the result of EnumerateAutoMountableDevices and + // EnumerateDevices. The argument is the enumerated device paths. typedef base::Callback<void(const std::vector<std::string>& device_paths)> - EnumerateAutoMountableDevicesCallback; + EnumerateDevicesCallback; // A callback to handle the result of EnumerateMountEntries. // The argument is the enumerated mount entries. @@ -329,9 +333,14 @@ // Calls EnumerateAutoMountableDevices method. |callback| is called after the // method call succeeds, otherwise, |error_callback| is called. virtual void EnumerateAutoMountableDevices( - const EnumerateAutoMountableDevicesCallback& callback, + const EnumerateDevicesCallback& callback, const base::Closure& error_callback) = 0; + // Calls EnumerateDevices method. |callback| is called after the + // method call succeeds, otherwise, |error_callback| is called. + virtual void EnumerateDevices(const EnumerateDevicesCallback& callback, + const base::Closure& error_callback) = 0; + // Calls EnumerateMountEntries. |callback| is called after the // method call succeeds, otherwise, |error_callback| is called. virtual void EnumerateMountEntries(
diff --git a/chromeos/dbus/fake_cros_disks_client.cc b/chromeos/dbus/fake_cros_disks_client.cc index aa1490f..9de0892 100644 --- a/chromeos/dbus/fake_cros_disks_client.cc +++ b/chromeos/dbus/fake_cros_disks_client.cc
@@ -141,9 +141,12 @@ } void FakeCrosDisksClient::EnumerateAutoMountableDevices( - const EnumerateAutoMountableDevicesCallback& callback, - const base::Closure& error_callback) { -} + const EnumerateDevicesCallback& callback, + const base::Closure& error_callback) {} + +void FakeCrosDisksClient::EnumerateDevices( + const EnumerateDevicesCallback& callback, + const base::Closure& error_callback) {} void FakeCrosDisksClient::EnumerateMountEntries( const EnumerateMountEntriesCallback& callback,
diff --git a/chromeos/dbus/fake_cros_disks_client.h b/chromeos/dbus/fake_cros_disks_client.h index 10e3fed1..495d97f 100644 --- a/chromeos/dbus/fake_cros_disks_client.h +++ b/chromeos/dbus/fake_cros_disks_client.h
@@ -41,8 +41,10 @@ const base::Closure& callback, const base::Closure& error_callback) override; void EnumerateAutoMountableDevices( - const EnumerateAutoMountableDevicesCallback& callback, + const EnumerateDevicesCallback& callback, const base::Closure& error_callback) override; + void EnumerateDevices(const EnumerateDevicesCallback& callback, + const base::Closure& error_callback) override; void EnumerateMountEntries(const EnumerateMountEntriesCallback& callback, const base::Closure& error_callback) override; void Format(const std::string& device_path,
diff --git a/chromeos/disks/disk_mount_manager.cc b/chromeos/disks/disk_mount_manager.cc index 5b9853c..0f4856f 100644 --- a/chromeos/disks/disk_mount_manager.cc +++ b/chromeos/disks/disk_mount_manager.cc
@@ -268,7 +268,7 @@ refresh_callbacks_.push_back(callback); if (refresh_callbacks_.size() == 1) { // If there's no in-flight refreshing task, start it. - cros_disks_client_->EnumerateAutoMountableDevices( + cros_disks_client_->EnumerateDevices( base::Bind(&DiskMountManagerImpl::RefreshAfterEnumerateDevices, weak_ptr_factory_.GetWeakPtr()), base::Bind(&DiskMountManagerImpl::RefreshCompleted, @@ -626,10 +626,7 @@ // Callback for GetDeviceProperties. void OnGetDeviceProperties(const DiskInfo& disk_info) { - // TODO(zelidrag): Find a better way to filter these out before we - // fetch the properties: - // Ignore disks coming from the device we booted the system from. - if (disk_info.on_boot_device()) + if (disk_info.is_virtual()) return; LOG(WARNING) << "Found disk " << disk_info.device_path(); @@ -650,6 +647,8 @@ auto access_mode = access_modes_.find(disk_info.device_path()); bool write_disabled_by_policy = access_mode != access_modes_.end() && access_mode->second == chromeos::MOUNT_ACCESS_MODE_READ_ONLY; + // TODO(agawronska): Add constructor for Disk from DiskInfo. Introduce Disk + // builder class for tests. Disk* disk = new Disk( disk_info.device_path(), disk_info.mount_path(), write_disabled_by_policy, disk_info.system_path(), @@ -663,7 +662,7 @@ disk_info.is_hidden(), disk_info.file_system_type(), base_mount_path); disks_.insert( std::make_pair(disk_info.device_path(), base::WrapUnique(disk))); - NotifyDiskStatusUpdate(is_new ? DISK_ADDED : DISK_CHANGED, disk); + NotifyDiskStatusUpdate(is_new ? DISK_ADDED : DISK_CHANGED, *disk); } // Part of EnsureMountInfoRefreshed(). Called after the list of devices are @@ -743,7 +742,7 @@ DiskMountManager::DiskMap::iterator iter = disks_.find(device_path); if (iter != disks_.end()) { Disk* disk = iter->second.get(); - NotifyDiskStatusUpdate(DISK_REMOVED, disk); + NotifyDiskStatusUpdate(DISK_REMOVED, *disk); disks_.erase(iter); } break; @@ -769,10 +768,11 @@ } // Notifies all observers about disk status update. - void NotifyDiskStatusUpdate(DiskEvent event, - const Disk* disk) { - for (auto& observer : observers_) - observer.OnDiskEvent(event, disk); + void NotifyDiskStatusUpdate(DiskEvent event, const Disk& disk) { + for (auto& observer : observers_) { + disk.IsAutoMountable() ? observer.OnAutoMountableDiskEvent(event, disk) + : observer.OnBootDeviceDiskEvent(event, disk); + } } // Notifies all observers about device status update. @@ -906,6 +906,15 @@ base_mount_path_ = mount_path; } +bool DiskMountManager::Disk::IsAutoMountable() const { + // Disks are considered auto-mountable if they are: + // 1. Non-virtual + // 2. Not on boot device + // Only the second condition is checked here, because Disks are created from + // non-virtual mount devices only. + return !on_boot_device_; +}; + bool DiskMountManager::AddDiskForTest(std::unique_ptr<Disk> disk) { return false; }
diff --git a/chromeos/disks/disk_mount_manager.h b/chromeos/disks/disk_mount_manager.h index cb8a927..fa8ff4b 100644 --- a/chromeos/disks/disk_mount_manager.h +++ b/chromeos/disks/disk_mount_manager.h
@@ -54,7 +54,8 @@ enum RenameEvent { RENAME_STARTED, RENAME_COMPLETED }; - // Used to house an instance of each found mount device. + // Used to house an instance of each found mount device. Created from + // non-virtual mount devices only - see IsAutoMountable(). class Disk { public: Disk(const std::string& device_path, @@ -182,6 +183,8 @@ void SetMountPath(const std::string& mount_path); + bool IsAutoMountable() const; + private: std::string device_path_; std::string mount_path_; @@ -245,12 +248,17 @@ typedef base::Callback<void(bool success)> EnsureMountInfoRefreshedCallback; // Implement this interface to be notified about disk/mount related events. + // TODO(agawronska): Make observer methods non-pure virtual, because + // subclasses only use small subset of them. class Observer { public: virtual ~Observer() {} - // Called when disk mount status is changed. - virtual void OnDiskEvent(DiskEvent event, const Disk* disk) = 0; + // Called when auto-mountable disk mount status is changed. + virtual void OnAutoMountableDiskEvent(DiskEvent event, + const Disk& disk) = 0; + // Called when fixed storage disk status is changed. + virtual void OnBootDeviceDiskEvent(DiskEvent event, const Disk& disk) = 0; // Called when device status is changed. virtual void OnDeviceEvent(DeviceEvent event, const std::string& device_path) = 0;
diff --git a/chromeos/disks/disk_mount_manager_unittest.cc b/chromeos/disks/disk_mount_manager_unittest.cc index 8c94e15..7d4fad3 100644 --- a/chromeos/disks/disk_mount_manager_unittest.cc +++ b/chromeos/disks/disk_mount_manager_unittest.cc
@@ -172,11 +172,12 @@ // Represents which function in |DiskMountManager::Observer| was invoked. enum ObserverEventType { - DEVICE_EVENT, // OnDeviceEvent() - DISK_EVENT, // OnDiskEvent() - FORMAT_EVENT, // OnFormatEvent() - MOUNT_EVENT, // OnMountEvent() - RENAME_EVENT // OnRenameEvent() + DEVICE_EVENT, // OnDeviceEvent() + AUTO_MOUNTABLE_DISK_EVENT, // OnAutoMountableDiskEvent() + BOOT_DEVICE_DISK_EVENT, // OnBootDeviceDiskEvent() + FORMAT_EVENT, // OnFormatEvent() + MOUNT_EVENT, // OnMountEvent() + RENAME_EVENT // OnRenameEvent() }; // Represents every event notified to |DiskMountManager::Observer|. @@ -208,30 +209,56 @@ } }; -// Represents an invocation of |DiskMountManager::Observer::OnDiskEvent()|. -struct DiskEvent : public ObserverEvent { +// Represents an invocation of +// DiskMountManager::Observer::OnAutoMountableDiskEvent(). +struct AutoMountableDiskEvent : public ObserverEvent { DiskMountManager::DiskEvent event; std::unique_ptr<DiskMountManager::Disk> disk; - DiskEvent(DiskMountManager::DiskEvent event, - const DiskMountManager::Disk& disk) - : event(event), - disk(std::unique_ptr<DiskMountManager::Disk>( - new DiskMountManager::Disk(disk))) {} + AutoMountableDiskEvent(DiskMountManager::DiskEvent event, + const DiskMountManager::Disk& disk) + : event(event), disk(std::make_unique<DiskMountManager::Disk>(disk)) {} - DiskEvent(DiskEvent&& other) + AutoMountableDiskEvent(AutoMountableDiskEvent&& other) : event(other.event), disk(std::move(other.disk)) {} - ObserverEventType type() const override { return DISK_EVENT; } + ObserverEventType type() const override { return AUTO_MOUNTABLE_DISK_EVENT; } - bool operator==(const DiskEvent& other) const { + bool operator==(const AutoMountableDiskEvent& other) const { return event == other.event && disk == other.disk; } std::string DebugString() const { - return StringPrintf("OnDiskEvent(event=%d, device_path=%s, mount_path=%s", - event, disk->device_path().c_str(), - disk->mount_path().c_str()); + return StringPrintf( + "OnAutoMountableDiskEvent(event=%d, device_path=%s, mount_path=%s", + event, disk->device_path().c_str(), disk->mount_path().c_str()); + } +}; + +// Represents an invocation of +// DiskMountManager::Observer::OnBootDeviceDiskEvent(). +// TODO(agawronska): Add tests for disks events. +struct BootDeviceDiskEvent : public ObserverEvent { + DiskMountManager::DiskEvent event; + std::unique_ptr<DiskMountManager::Disk> disk; + + BootDeviceDiskEvent(DiskMountManager::DiskEvent event, + const DiskMountManager::Disk& disk) + : event(event), disk(std::make_unique<DiskMountManager::Disk>(disk)) {} + + BootDeviceDiskEvent(BootDeviceDiskEvent&& other) + : event(other.event), disk(std::move(other.disk)) {} + + ObserverEventType type() const override { return BOOT_DEVICE_DISK_EVENT; } + + bool operator==(const BootDeviceDiskEvent& other) const { + return event == other.event && disk == other.disk; + } + + std::string DebugString() const { + return StringPrintf( + "OnBootDeviceDiskEvent(event=%d, device_path=%s, mount_path=%s", event, + disk->device_path().c_str(), disk->mount_path().c_str()); } }; @@ -334,11 +361,18 @@ events_.push_back(std::make_unique<DeviceEvent>(event, device_path)); } - void OnDiskEvent(DiskMountManager::DiskEvent event, - const DiskMountManager::Disk* disk) override { + void OnBootDeviceDiskEvent(DiskMountManager::DiskEvent event, + const DiskMountManager::Disk& disk) override { // Take a snapshot (copy) of the Disk object at the time of invocation for // later verification. - events_.push_back(std::make_unique<DiskEvent>(event, *disk)); + events_.push_back(std::make_unique<BootDeviceDiskEvent>(event, disk)); + } + + void OnAutoMountableDiskEvent(DiskMountManager::DiskEvent event, + const DiskMountManager::Disk& disk) override { + // Take a snapshot (copy) of the Disk object at the time of invocation for + // later verification. + events_.push_back(std::make_unique<AutoMountableDiskEvent>(event, disk)); } void OnFormatEvent(DiskMountManager::FormatEvent event, @@ -375,11 +409,20 @@ return static_cast<const DeviceEvent&>(*events_[index]); } - // Verifies if the |index|th invocation is OnDiskEvent() and returns details. - const DiskEvent& GetDiskEvent(size_t index) { + // Verifies if the |index|th invocation is OnAutoMountableDiskEvent() and + // returns details. + const AutoMountableDiskEvent& GetAutoMountableDiskEvent(size_t index) { DCHECK_GT(events_.size(), index); - DCHECK_EQ(DISK_EVENT, events_[index]->type()); - return static_cast<const DiskEvent&>(*events_[index]); + DCHECK_EQ(AUTO_MOUNTABLE_DISK_EVENT, events_[index]->type()); + return static_cast<const AutoMountableDiskEvent&>(*events_[index]); + } + + // Verifies if the |index|th invocation is OnBootDeviceDiskEvent() and returns + // details. + const BootDeviceDiskEvent& GetBootDeviceDiskEvent(size_t index) { + DCHECK_GT(events_.size(), index); + DCHECK_EQ(BOOT_DEVICE_DISK_EVENT, events_[index]->type()); + return static_cast<const BootDeviceDiskEvent&>(*events_[index]); } // Verifies if the |index|th invocation is OnFormatEvent() and returns
diff --git a/chromeos/disks/mock_disk_mount_manager.cc b/chromeos/disks/mock_disk_mount_manager.cc index d2d4c4866..36939aa3 100644 --- a/chromeos/disks/mock_disk_mount_manager.cc +++ b/chromeos/disks/mock_disk_mount_manager.cc
@@ -227,8 +227,10 @@ void MockDiskMountManager::NotifyDiskChanged( DiskEvent event, const DiskMountManager::Disk* disk) { - for (auto& observer : observers_) - observer.OnDiskEvent(event, disk); + for (auto& observer : observers_) { + disk->IsAutoMountable() ? observer.OnAutoMountableDiskEvent(event, *disk) + : observer.OnBootDeviceDiskEvent(event, *disk); + } } void MockDiskMountManager::NotifyDeviceChanged(DeviceEvent event,
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn index a4550c6f..9d5d168 100644 --- a/components/arc/BUILD.gn +++ b/components/arc/BUILD.gn
@@ -160,6 +160,7 @@ static_library("arc_test_support") { testonly = true sources = [ + "test/connection_holder_util.h", "test/fake_app_instance.cc", "test/fake_app_instance.h", "test/fake_arc_bridge_host.cc",
diff --git a/components/arc/power/arc_power_bridge_unittest.cc b/components/arc/power/arc_power_bridge_unittest.cc index e592c28..e9f02f9 100644 --- a/components/arc/power/arc_power_bridge_unittest.cc +++ b/components/arc/power/arc_power_bridge_unittest.cc
@@ -4,6 +4,8 @@ #include "components/arc/power/arc_power_bridge.h" +#include <utility> + #include "base/run_loop.h" #include "base/test/scoped_task_environment.h" #include "chromeos/dbus/dbus_thread_manager.h" @@ -11,6 +13,7 @@ #include "chromeos/dbus/power_manager/suspend.pb.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/common/power.mojom.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_power_instance.h" #include "content/public/common/service_manager_connection.h" #include "services/device/public/cpp/test/test_wake_lock_provider.h" @@ -59,8 +62,8 @@ // ArcPowerBridge::OnInstanceReady() being called. void CreatePowerInstance() { power_instance_ = std::make_unique<FakePowerInstance>(); - bridge_service_->power()->SetInstance(power_instance_.get(), - mojom::PowerInstance::Version_); + bridge_service_->power()->SetInstance(power_instance_.get()); + WaitForInstanceReady(bridge_service_->power()); } // Destroys the FakePowerInstance. This results in
diff --git a/components/arc/test/connection_holder_util.h b/components/arc/test/connection_holder_util.h new file mode 100644 index 0000000..53fa7a6 --- /dev/null +++ b/components/arc/test/connection_holder_util.h
@@ -0,0 +1,60 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_ARC_TEST_CONNECTION_HOLDER_UTIL_H_ +#define COMPONENTS_ARC_TEST_CONNECTION_HOLDER_UTIL_H_ + +#include <utility> + +#include "base/callback_helpers.h" +#include "base/macros.h" +#include "base/run_loop.h" +#include "components/arc/connection_holder.h" + +namespace arc { + +namespace internal { + +// An observer that runs a closure when the connection is ready. +template <typename InstanceType, typename HostType> +class ReadinessObserver + : public ConnectionHolder<InstanceType, HostType>::Observer { + public: + explicit ReadinessObserver(ConnectionHolder<InstanceType, HostType>* holder, + base::OnceClosure closure) + : holder_(holder), closure_(std::move(closure)) { + holder_->AddObserver(this); + } + ~ReadinessObserver() override { holder_->RemoveObserver(this); } + + private: + void OnConnectionReady() override { + if (!closure_) + return; + std::move(closure_).Run(); + } + + ConnectionHolder<InstanceType, HostType>* const holder_; // Owned by caller + base::OnceClosure closure_; + + DISALLOW_COPY_AND_ASSIGN(ReadinessObserver); +}; + +} // namespace internal + +// Waits for the instance to be ready. +template <typename InstanceType, typename HostType> +void WaitForInstanceReady(ConnectionHolder<InstanceType, HostType>* holder) { + if (holder->IsConnected()) + return; + + base::RunLoop run_loop; + internal::ReadinessObserver<InstanceType, HostType> readiness_observer( + holder, run_loop.QuitClosure()); + run_loop.Run(); +} + +} // namespace arc + +#endif // COMPONENTS_ARC_TEST_CONNECTION_HOLDER_UTIL_H_
diff --git a/components/arc/test/fake_app_instance.cc b/components/arc/test/fake_app_instance.cc index 7fbf1e3..25ca126 100644 --- a/components/arc/test/fake_app_instance.cc +++ b/components/arc/test/fake_app_instance.cc
@@ -52,6 +52,7 @@ // ARC app instance calls RefreshAppList after Init() successfully. Call // RefreshAppList() here to keep the same behavior. RefreshAppList(); + host_ = std::move(host_ptr); std::move(callback).Run(); }
diff --git a/components/arc/test/fake_app_instance.h b/components/arc/test/fake_app_instance.h index 316ef82..4f9f9790 100644 --- a/components/arc/test/fake_app_instance.h +++ b/components/arc/test/fake_app_instance.h
@@ -200,6 +200,10 @@ // Keeps information for running tasks. TaskIdToInfo task_id_to_info_; + // Keeps the binding alive so that calls to this class can be correctly + // routed. + mojom::AppHostPtr host_; + bool GetFakeIcon(mojom::ScaleFactor scale_factor, std::string* png_data_as_string);
diff --git a/components/arc/test/fake_bluetooth_instance.cc b/components/arc/test/fake_bluetooth_instance.cc index 2641807..660cc48 100644 --- a/components/arc/test/fake_bluetooth_instance.cc +++ b/components/arc/test/fake_bluetooth_instance.cc
@@ -34,6 +34,7 @@ void FakeBluetoothInstance::Init(mojom::BluetoothHostPtr host_ptr, InitCallback callback) { + host_ = std::move(host_ptr); std::move(callback).Run(); }
diff --git a/components/arc/test/fake_bluetooth_instance.h b/components/arc/test/fake_bluetooth_instance.h index 893db67..abe5cac 100644 --- a/components/arc/test/fake_bluetooth_instance.h +++ b/components/arc/test/fake_bluetooth_instance.h
@@ -149,6 +149,10 @@ std::vector<std::unique_ptr<LEDeviceFoundData>> le_device_found_data_; std::vector<std::unique_ptr<GattDBResult>> gatt_db_result_; + // Keeps the binding alive so that calls to this class can be correctly + // routed. + mojom::BluetoothHostPtr host_; + DISALLOW_COPY_AND_ASSIGN(FakeBluetoothInstance); };
diff --git a/components/arc/test/fake_intent_helper_instance.cc b/components/arc/test/fake_intent_helper_instance.cc index 9a25bd98..aacb8d1 100644 --- a/components/arc/test/fake_intent_helper_instance.cc +++ b/components/arc/test/fake_intent_helper_instance.cc
@@ -77,6 +77,7 @@ void FakeIntentHelperInstance::Init(mojom::IntentHelperHostPtr host_ptr, InitCallback callback) { + host_ = std::move(host_ptr); std::move(callback).Run(); }
diff --git a/components/arc/test/fake_intent_helper_instance.h b/components/arc/test/fake_intent_helper_instance.h index 8451ba3e..e70cca65 100644 --- a/components/arc/test/fake_intent_helper_instance.h +++ b/components/arc/test/fake_intent_helper_instance.h
@@ -119,6 +119,10 @@ std::map<std::string, std::vector<mojom::IntentHandlerInfoPtr>> intent_handlers_; + // Keeps the binding alive so that calls to this class can be correctly + // routed. + mojom::IntentHelperHostPtr host_; + DISALLOW_COPY_AND_ASSIGN(FakeIntentHelperInstance); };
diff --git a/components/arc/test/fake_wallpaper_instance.cc b/components/arc/test/fake_wallpaper_instance.cc index 0a40514..a5b180e 100644 --- a/components/arc/test/fake_wallpaper_instance.cc +++ b/components/arc/test/fake_wallpaper_instance.cc
@@ -21,6 +21,7 @@ void FakeWallpaperInstance::Init(mojom::WallpaperHostPtr host_ptr, InitCallback callback) { + host_ = std::move(host_ptr); std::move(callback).Run(); }
diff --git a/components/arc/test/fake_wallpaper_instance.h b/components/arc/test/fake_wallpaper_instance.h index 6af83bd..d0f18f9 100644 --- a/components/arc/test/fake_wallpaper_instance.h +++ b/components/arc/test/fake_wallpaper_instance.h
@@ -28,6 +28,10 @@ private: std::vector<int32_t> changed_ids_; + // Keeps the binding alive so that calls to this class can be correctly + // routed. + mojom::WallpaperHostPtr host_; + DISALLOW_COPY_AND_ASSIGN(FakeWallpaperInstance); };
diff --git a/components/arc/volume_mounter/arc_volume_mounter_bridge.cc b/components/arc/volume_mounter/arc_volume_mounter_bridge.cc index 9412567..7cf9eb0 100644 --- a/components/arc/volume_mounter/arc_volume_mounter_bridge.cc +++ b/components/arc/volume_mounter/arc_volume_mounter_bridge.cc
@@ -74,12 +74,18 @@ base::BindOnce(&SendAllMountEvents, this)); } -void ArcVolumeMounterBridge::OnDiskEvent( +void ArcVolumeMounterBridge::OnAutoMountableDiskEvent( chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk* disk) { + const chromeos::disks::DiskMountManager::Disk& disk) { // Ignored. DiskEvents will be maintained in Vold during MountEvents. } +void ArcVolumeMounterBridge::OnBootDeviceDiskEvent( + chromeos::disks::DiskMountManager::DiskEvent event, + const chromeos::disks::DiskMountManager::Disk& disk) { + // Ignored. ARC doesn't care about boot device disk events. +} + void ArcVolumeMounterBridge::OnDeviceEvent( chromeos::disks::DiskMountManager::DeviceEvent event, const std::string& device_path) {
diff --git a/components/arc/volume_mounter/arc_volume_mounter_bridge.h b/components/arc/volume_mounter/arc_volume_mounter_bridge.h index af51cf38..5c47f2cf 100644 --- a/components/arc/volume_mounter/arc_volume_mounter_bridge.h +++ b/components/arc/volume_mounter/arc_volume_mounter_bridge.h
@@ -42,9 +42,12 @@ void OnConnectionReady() override; // chromeos::disks::DiskMountManager::Observer overrides: - void OnDiskEvent( + void OnAutoMountableDiskEvent( chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk* disk) override; + const chromeos::disks::DiskMountManager::Disk& disk) override; + void OnBootDeviceDiskEvent( + chromeos::disks::DiskMountManager::DiskEvent event, + const chromeos::disks::DiskMountManager::Disk& disk) override; void OnDeviceEvent(chromeos::disks::DiskMountManager::DeviceEvent event, const std::string& device_path) override; void OnMountEvent(chromeos::disks::DiskMountManager::MountEvent event,
diff --git a/components/autofill/content/renderer/BUILD.gn b/components/autofill/content/renderer/BUILD.gn index be934a5..b7acdc30 100644 --- a/components/autofill/content/renderer/BUILD.gn +++ b/components/autofill/content/renderer/BUILD.gn
@@ -14,6 +14,8 @@ "form_classifier.h", "html_based_username_detector.cc", "html_based_username_detector.h", + "html_based_username_detector_vocabulary.cc", + "html_based_username_detector_vocabulary.h", "page_form_analyser_logger.cc", "page_form_analyser_logger.h", "page_passwords_analyser.cc",
diff --git a/components/autofill/content/renderer/html_based_username_detector.cc b/components/autofill/content/renderer/html_based_username_detector.cc index ea7a502..046932cc 100644 --- a/components/autofill/content/renderer/html_based_username_detector.cc +++ b/components/autofill/content/renderer/html_based_username_detector.cc
@@ -5,12 +5,15 @@ #include "components/autofill/content/renderer/html_based_username_detector.h" #include <algorithm> -#include <map> +#include <tuple> +#include "base/containers/flat_set.h" #include "base/i18n/case_conversion.h" +#include "base/macros.h" #include "base/strings/string_split.h" #include "base/strings/utf_string_conversions.h" #include "components/autofill/content/renderer/form_autofill_util.h" +#include "components/autofill/content/renderer/html_based_username_detector_vocabulary.h" #include "third_party/WebKit/public/web/WebFormElement.h" using blink::WebFormControlElement; @@ -21,248 +24,38 @@ namespace { -// For each input element that can be username, we compute and save developer -// and user group, along with associated short tokens lists (to handle finding -// less than |kMinimumWordLength| letters long words). +// List of separators that can appear in HTML attribute values. +constexpr char kDelimiters[] = "$\"\'?%*@!\\/&^#:+~`;,>|<.[](){}-_ 0123456789"; + +// Minimum length of a word, in order not to be considered short word. Short +// words will not be searched in attribute values (especially after delimiters +// removing), because a short word may be a part of another word. A short word +// should be enclosed between delimiters, otherwise an occurrence doesn't count. +constexpr int kMinimumWordLength = 4; + +// For each input element that can be a username, developer and user group +// values are computed. The user group value includes what a user sees: label, +// placeholder, aria-label (all are stored in FormFieldData.label). The +// developer group value consists of name and id attribute values. +// For each group the set of short tokens (tokens shorter than +// |kMinimumWordLength|) is computed as well. struct UsernameFieldData { WebInputElement input_element; base::string16 developer_value; - std::vector<base::string16> developer_short_tokens; + base::flat_set<base::string16> developer_short_tokens; base::string16 user_value; - std::vector<base::string16> user_short_tokens; + base::flat_set<base::string16> user_short_tokens; }; +// Words that the algorithm looks for are split into multiple categories based +// on feature reliability. +// A category may contain a latin dictionary and a non-latin dictionary. It is +// mandatory that it has a latin one, but a non-latin might be missing. // "Latin" translations are the translations of the words for which the // original translation is similar to the romanized translation (translation of // the word only using ISO basic Latin alphabet). // "Non-latin" translations are the translations of the words that have custom, // country specific characters. -const char* const kNegativeLatin[] = { - "pin", "parola", "wagwoord", "wachtwoord", - "fake", "parole", "givenname", "achinsinsi", - "token", "parool", "firstname", "facalfaire", - "fname", "lozinka", "pasahitza", "focalfaire", - "lname", "passord", "pasiwedhi", "iphasiwedi", - "geslo", "huahuna", "passwuert", "katalaluan", - "heslo", "fullname", "phasewete", "adgangskode", - "parol", "optional", "wachtwurd", "contrasenya", - "sandi", "lastname", "cyfrinair", "contrasinal", - "senha", "kupuhipa", "katasandi", "kalmarsirri", - "hidden", "password", "loluszais", "tenimiafina", - "second", "passwort", "middlename", "paroladordine", - "codice", "pasvorto", "familyname", "inomboloyokuvula", - "modpas", "salasana", "motdepasse", "numeraeleiloaesesi"}; -constexpr int kNegativeLatinSize = arraysize(kNegativeLatin); - -const char* const kNegativeNonLatin[] = {"fjalëkalim", - "የይለፍቃል", - "كلمهالسر", - "գաղտնաբառ", - "пароль", - "পাসওয়ার্ড", - "парола", - "密码", - "密碼", - "დაგავიწყდათ", - "κωδικόςπρόσβασης", - "પાસવર્ડ", - "סיסמה", - "पासवर्ड", - "jelszó", - "lykilorð", - "paswọọdụ", - "パスワード", - "ಪಾಸ್ವರ್ಡ್", - "пароль", - "ការពាក្យសម្ងាត់", - "암호", - "şîfre", - "купуясөз", - "ລະຫັດຜ່ານ", - "slaptažodis", - "лозинка", - "पासवर्ड", - "нууцүг", - "စကားဝှက်ကို", - "पासवर्ड", - "رمز", - "کلمهعبور", - "hasło", - "пароль", - "лозинка", - "پاسورڊ", - "මුරපදය", - "contraseña", - "lösenord", - "гузарвожа", - "கடவுச்சொல்", - "పాస్వర్డ్", - "รหัสผ่าน", - "пароль", - "پاسورڈ", - "mậtkhẩu", - "פּאַראָל", - "ọrọigbaniwọle"}; -constexpr int kNegativeNonLatinSize = arraysize(kNegativeNonLatin); - -const char* const kUsernameLatin[] = { - "gatti", "uzantonomo", "solonanarana", "nombredeusuario", - "olumulo", "nomenusoris", "enwdefnyddiwr", "nomdutilisateur", - "lolowera", "notandanafn", "nomedeusuario", "vartotojovardas", - "username", "ahanjirimara", "gebruikersnaam", "numedeutilizator", - "brugernavn", "benotzernumm", "jinalamtumiaji", "erabiltzaileizena", - "brukernavn", "benutzername", "sunanmaiamfani", "foydalanuvchinomi", - "mosebedisi", "kasutajanimi", "ainmcleachdaidh", "igamalomsebenzisi", - "nomdusuari", "lomsebenzisi", "jenengpanganggo", "ingoakaiwhakamahi", - "nomeutente", "namapengguna"}; -constexpr int kUsernameLatinSize = arraysize(kUsernameLatin); - -const char* const kUsernameNonLatin[] = {"用户名", - "کاتيجونالو", - "用戶名", - "የተጠቃሚስም", - "логин", - "اسمالمستخدم", - "נאמען", - "کاصارفکانام", - "ユーザ名", - "όνομα χρήστη", - "brûkersnamme", - "корисничкоиме", - "nonitilizatè", - "корисничкоиме", - "ngaranpamaké", - "ຊື່ຜູ້ໃຊ້", - "användarnamn", - "యూజర్పేరు", - "korisničkoime", - "пайдаланушыаты", - "שםמשתמש", - "ім'якористувача", - "کارننوم", - "хэрэглэгчийннэр", - "nomedeusuário", - "имяпользователя", - "têntruynhập", - "பயனர்பெயர்", - "ainmúsáideora", - "ชื่อผู้ใช้", - "사용자이름", - "імякарыстальніка", - "lietotājvārds", - "потребителскоиме", - "uporabniškoime", - "колдонуучунунаты", - "kullanıcıadı", - "පරිශීලකනාමය", - "istifadəçiadı", - "օգտագործողիանունը", - "navêbikarhêner", - "ಬಳಕೆದಾರಹೆಸರು", - "emriipërdoruesit", - "वापरकर्तानाव", - "käyttäjätunnus", - "વપરાશકર્તાનામ", - "felhasználónév", - "उपयोगकर्तानाम", - "nazwaużytkownika", - "ഉപയോക്തൃനാമം", - "სახელი", - "အသုံးပြုသူအမည်", - "نامکاربری", - "प्रयोगकर्तानाम", - "uživatelskéjméno", - "ব্যবহারকারীরনাম", - "užívateľskémeno", - "ឈ្មោះអ្នកប្រើប្រាស់"}; -constexpr int kUsernameNonLatinSize = arraysize(kUsernameNonLatin); - -const char* const kUserLatin[] = { - "user", "wosuta", "gebruiker", "utilizator", - "usor", "notandi", "gumagamit", "vartotojas", - "fammi", "olumulo", "maiamfani", "cleachdaidh", - "utent", "pemakai", "mpampiasa", "umsebenzisi", - "bruger", "usuario", "panganggo", "utilisateur", - "bruker", "benotzer", "uporabnik", "doutilizador", - "numake", "benutzer", "covneegsiv", "erabiltzaile", - "usuari", "kasutaja", "defnyddiwr", "kaiwhakamahi", - "utente", "korisnik", "mosebedisi", "foydalanuvchi", - "uzanto", "pengguna", "mushandisi"}; -constexpr int kUserLatinSize = arraysize(kUserLatin); - -const char* const kUserNonLatin[] = {"用户", - "użytkownik", - "tagatafaʻaaogā", - "دکارونکيعکس", - "用戶", - "užívateľ", - "корисник", - "карыстальнік", - "brûker", - "kullanıcı", - "истифода", - "អ្នកប្រើ", - "ọrụ", - "ተጠቃሚ", - "באַניצער", - "хэрэглэгчийн", - "يوزر", - "istifadəçi", - "ຜູ້ໃຊ້", - "пользователь", - "صارف", - "meahoʻohana", - "потребител", - "वापरकर्ता", - "uživatel", - "ユーザー", - "מִשׁתַמֵשׁ", - "ผู้ใช้งาน", - "사용자", - "bikaranîvan", - "колдонуучу", - "વપરાશકર્તા", - "përdorues", - "ngườidùng", - "корисникот", - "उपयोगकर्ता", - "itilizatè", - "χρήστης", - "користувач", - "օգտվողիանձնագիրը", - "használó", - "faoiúsáideoir", - "შესახებ", - "ব্যবহারকারী", - "lietotājs", - "பயனர்", - "ಬಳಕೆದಾರ", - "ഉപയോക്താവ്", - "کاربر", - "యూజర్", - "පරිශීලක", - "प्रयोगकर्ता", - "användare", - "المستعمل", - "пайдаланушы", - "အသုံးပြုသူကို", - "käyttäjä"}; -constexpr int kUserNonLatinSize = arraysize(kUserNonLatin); - -const char* const kTechnicalWords[] = { - "uid", "newtel", "uaccount", "regaccount", "ureg", - "loginid", "laddress", "accountreg", "regid", "regname", - "loginname", "membername", "uname", "ucreate", "loginmail", - "accountname", "umail", "loginreg", "accountid", "loginaccount", - "ulogin", "regemail", "newmobile", "accountlogin"}; -constexpr int kTechnicalWordsSize = arraysize(kTechnicalWords); - -const char* const kWeakWords[] = {"id", "login", "mail"}; -constexpr int kWeakWordsSize = arraysize(kWeakWords); - -// Words that the algorithm looks for are split into multiple categories. -// A category may contain latin dictionary and non-latin dictionary. It is -// mandatory that it has latin one, but non-latin might be missing. struct CategoryOfWords { const char* const* const latin_dictionary; const size_t latin_dictionary_size; @@ -270,53 +63,65 @@ const size_t non_latin_dictionary_size; }; -// Minimum length of a word, in order not to be considered short word. -// Short words will have different treatment than the others. -constexpr int kMinimumWordLength = 4; - -void BuildValueAndShortTokens( +// 1. Removes delimiters from |raw_value| and appends it to |*field_data_value|. +// A sentinel symbol is added first if |*field_data_value| is not empty. +// 2. Tokenizes and appends short tokens (shorter than |kMinimumWordLength|) +// from |raw_value| to |*field_data_short_tokens|, if any. +void AppendValueAndShortTokens( const base::string16& raw_value, base::string16* field_data_value, - std::vector<base::string16>* field_data_short_tokens) { - // List of separators that can appear in HTML attribute values. - static const std::string kDelimiters = - "\"\'?%*@!\\/&^#:+~`;,>|<.[](){}-_ 0123456789"; + base::flat_set<base::string16>* field_data_short_tokens) { base::string16 lowercase_value = base::i18n::ToLower(raw_value); + const base::string16 delimiters = base::ASCIIToUTF16(kDelimiters); std::vector<base::StringPiece16> tokens = - base::SplitStringPiece(lowercase_value, base::ASCIIToUTF16(kDelimiters), - base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - *field_data_value = base::JoinString(tokens, base::string16()); + base::SplitStringPiece(lowercase_value, delimiters, base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + // Modify |lowercase_value| only when |tokens| has been processed. - std::vector<base::StringPiece16> short_tokens; - std::copy_if(tokens.begin(), tokens.end(), std::back_inserter(short_tokens), - [](const base::StringPiece16& token) { - return token.size() < kMinimumWordLength; - }); + std::vector<base::string16> short_tokens; + std::transform( + std::find_if(tokens.begin(), tokens.end(), + [](const base::StringPiece16& token) { + return token.size() < kMinimumWordLength; + }), + tokens.end(), std::back_inserter(short_tokens), + [](const base::StringPiece16& token) { return token.as_string(); }); + // It is better to insert elements to a |flat_map| in one operation. + field_data_short_tokens->insert(short_tokens.begin(), short_tokens.end()); - for (const base::StringPiece16& token : short_tokens) { - field_data_short_tokens->push_back(token.as_string()); - } -} + // Now that tokens are processed, squeeze delimiters out of |lowercase_value|. + lowercase_value.erase(std::remove_if( + lowercase_value.begin(), lowercase_value.end(), + [delimiters](char c) { return delimiters.find(c) != delimiters.npos; })); -// For a given input element, compute developer and user value, along with -// developer and user short tokens. -UsernameFieldData ComputeFieldData(const blink::WebInputElement& input_element, - const FormFieldData& field) { - UsernameFieldData field_data; - field_data.input_element = input_element; // When computing the developer value, '$' safety guard is being added // between field name and id, so that forming of accidental words is // prevented. - BuildValueAndShortTokens(field.name + base::ASCIIToUTF16("$") + field.id, - &field_data.developer_value, - &field_data.developer_short_tokens); - BuildValueAndShortTokens(field.label, &field_data.user_value, - &field_data.user_short_tokens); + if (!field_data_value->empty()) + field_data_value->push_back('$'); + *field_data_value += lowercase_value; +} + +// For the given |input_element|, compute developer and user value, along with +// sets of short tokens, and returns it. +UsernameFieldData ComputeUsernameFieldData( + const blink::WebInputElement& input_element, + const FormFieldData& field) { + UsernameFieldData field_data; + field_data.input_element = input_element; + + AppendValueAndShortTokens(field.name, &field_data.developer_value, + &field_data.developer_short_tokens); + AppendValueAndShortTokens(field.id, &field_data.developer_value, + &field_data.developer_short_tokens); + AppendValueAndShortTokens(field.label, &field_data.user_value, + &field_data.user_short_tokens); return field_data; } -// For the fields of the given form that can be username fields, compute data -// needed by the detector. +// For the fields of the given form that can be username fields +// (all_possible_usernames), computes |UsernameFieldData| needed by the +// detector. void InferUsernameFieldData( const std::vector<blink::WebInputElement>& all_possible_usernames, const FormData& form_data, @@ -324,41 +129,43 @@ // |all_possible_usernames| and |form_data.fields| may have different set of // fields. Match them based on |WebInputElement.NameForAutofill| and // |FormFieldData.name|. - size_t current_index = 0; + size_t next_element_range_begin = 0; for (const blink::WebInputElement& input_element : all_possible_usernames) { - for (size_t i = current_index; i < form_data.fields.size(); ++i) { - const FormFieldData& field = form_data.fields[i]; + const base::string16 element_name = input_element.NameForAutofill().Utf16(); + for (size_t i = next_element_range_begin; i < form_data.fields.size(); + ++i) { + const FormFieldData& field_data = form_data.fields[i]; if (input_element.NameForAutofill().IsEmpty()) continue; - // Find matching form data and web input element. - if (field.name == input_element.NameForAutofill().Utf16()) { - current_index = i + 1; + // Find matching field data and web input element. + if (field_data.name == element_name) { + next_element_range_begin = i + 1; possible_usernames_data->push_back( - ComputeFieldData(input_element, field)); + ComputeUsernameFieldData(input_element, field_data)); break; } } } } -// Check if any word from the dictionary is encountered in computed field -// information. -bool SearchFieldInDictionary(const base::string16& value, - const std::vector<base::string16>& tokens, - const char* const* dictionary, - const size_t& dictionary_size) { +// Check if any word from |dictionary| is encountered in computed field +// information (i.e. |value|, |tokens|). +bool CheckFieldWithDictionary( + const base::string16& value, + const base::flat_set<base::string16>& short_tokens, + const char* const* dictionary, + const size_t& dictionary_size) { for (size_t i = 0; i < dictionary_size; ++i) { - if (strlen(dictionary[i]) < kMinimumWordLength) { - // Treat short words by looking up for them in the tokens list. - for (const base::string16& token : tokens) { - if (token == base::UTF8ToUTF16(dictionary[i])) - return true; - } + const base::string16 word = base::UTF8ToUTF16(dictionary[i]); + if (word.length() < kMinimumWordLength) { + // Treat short words by looking them up in the tokens set. + if (short_tokens.find(word) != short_tokens.end()) + return true; } else { - // Treat long words by looking for them as a substring in |value|. - if (value.find(base::UTF8ToUTF16(dictionary[i])) != std::string::npos) + // Treat long words by looking them up as a substring in |value|. + if (value.find(word) != std::string::npos) return true; } } @@ -366,33 +173,30 @@ } // Check if any word from |category| is encountered in computed field -// information. +// information (|possible_username|). bool ContainsWordFromCategory(const UsernameFieldData& possible_username, const CategoryOfWords& category) { // For user value, search in latin and non-latin dictionaries, because this - // value is user visible. - return SearchFieldInDictionary( + // value is user visible. For developer value, only look up in latin + /// dictionaries. + return CheckFieldWithDictionary( possible_username.user_value, possible_username.user_short_tokens, category.latin_dictionary, category.latin_dictionary_size) || - SearchFieldInDictionary(possible_username.user_value, - possible_username.user_short_tokens, - category.non_latin_dictionary, - category.non_latin_dictionary_size) || - // For developer value, only look up in latin dictionaries. - SearchFieldInDictionary(possible_username.developer_value, - possible_username.developer_short_tokens, - category.latin_dictionary, - category.latin_dictionary_size); + CheckFieldWithDictionary(possible_username.user_value, + possible_username.user_short_tokens, + category.non_latin_dictionary, + category.non_latin_dictionary_size) || + CheckFieldWithDictionary(possible_username.developer_value, + possible_username.developer_short_tokens, + category.latin_dictionary, + category.latin_dictionary_size); } // Remove from |possible_usernames_data| the elements that definitely cannot be // usernames, because their computed values contain at least one negative word. void RemoveFieldsWithNegativeWords( std::vector<UsernameFieldData>* possible_usernames_data) { - // Words that certainly point to a non-username field. - // If field values contain at least one negative word, then the field is - // excluded from the list of possible usernames. - static const CategoryOfWords kNegativeCategory{ + static const CategoryOfWords kNegativeCategory = { kNegativeLatin, kNegativeLatinSize, kNegativeNonLatin, kNegativeNonLatinSize}; @@ -406,11 +210,11 @@ possible_usernames_data->end()); } -// Check if any word from the given category appears in fields from the form. -// If a word appears in more than 2 fields, we do not make a decision, because -// it may just be a prefix. -// If a word appears in 1 or 2 fields, we return the first field in which we -// found the substring as |username_element|. +// Check if any word from the given category (|category|) appears in fields from +// the form (|possible_usernames_data|). If the category words appear in more +// than 2 fields, do not make a decision, because it may just be a prefix. If +// the words appears in 1 or 2 fields, the first field is saved to +// |*username_element|. bool FormContainsWordFromCategory( const std::vector<UsernameFieldData>& possible_usernames_data, const CategoryOfWords& category, @@ -419,20 +223,21 @@ // the form) in which a substring is encountered. WebInputElement chosen_field; - size_t count = 0; + size_t fields_found = 0; for (const UsernameFieldData& field_data : possible_usernames_data) { if (ContainsWordFromCategory(field_data, category)) { - if (count == 0) + if (fields_found == 0) chosen_field = field_data.input_element; - count++; + fields_found++; } } - if (count && count <= 2) { + if (fields_found > 0 && fields_found <= 2) { *username_element = chosen_field; return true; + } else { + return false; } - return false; } // Find username element if there is no cached result for the given form. @@ -442,28 +247,18 @@ WebInputElement* username_element) { DCHECK(username_element); - // Translations of "username". - static const CategoryOfWords kUsernameCategory{ + static const CategoryOfWords kUsernameCategory = { kUsernameLatin, kUsernameLatinSize, kUsernameNonLatin, kUsernameNonLatinSize}; - - // Translations of "user". - static const CategoryOfWords kUserCategory{kUserLatin, kUserLatinSize, - kUserNonLatin, kUserNonLatinSize}; - - // Words that certainly point to a username field, if they appear in developer - // value. They are technical words, because they can only be used as variable - // names, and not as stand-alone words. - static const CategoryOfWords kTechnicalCategory{ + static const CategoryOfWords kUserCategory = { + kUserLatin, kUserLatinSize, kUserNonLatin, kUserNonLatinSize}; + static const CategoryOfWords kTechnicalCategory = { kTechnicalWords, kTechnicalWordsSize, nullptr, 0}; - - // Words that might point to a username field.They have the smallest priority - // in the heuristic, because there are also field attribute values that - // contain them, but are not username fields. - static const CategoryOfWords kWeakCategory{kWeakWords, kWeakWordsSize, - nullptr, 0}; - + static const CategoryOfWords kWeakCategory = {kWeakWords, kWeakWordsSize, + nullptr, 0}; // These categories contain words that point to username field. + // Order of categories is vital: the detector searches for words in descending + // order of probability to point to a username field. static const CategoryOfWords kPositiveCategories[] = { kUsernameCategory, kUserCategory, kTechnicalCategory, kWeakCategory}; @@ -473,8 +268,6 @@ RemoveFieldsWithNegativeWords(&possible_usernames_data); // These are the searches performed by the username detector. - // Order of categories is vital: the detector searches for words in descending - // order of probability to point to a username field. for (const CategoryOfWords& category : kPositiveCategories) { if (FormContainsWordFromCategory(possible_usernames_data, category, username_element)) { @@ -496,20 +289,34 @@ if (all_possible_usernames.empty()) return false; + // All elements in |all_possible_usernames| should have the same |Form()|. + DCHECK( + std::adjacent_find( + all_possible_usernames.begin(), all_possible_usernames.end(), + [](const blink::WebInputElement& a, const blink::WebInputElement& b) { + return a.Form() != b.Form(); + }) == all_possible_usernames.end()); const blink::WebFormElement form = all_possible_usernames[0].Form(); - if (!username_detector_cache || - username_detector_cache->find(form) == username_detector_cache->end()) { + + // True if the cache has no entry for |form|. + bool cache_miss = true; + // Iterator pointing to the entry for |form| if the entry for |form| is found. + UsernameDetectorCache::iterator form_position; + if (username_detector_cache) { + std::tie(form_position, cache_miss) = username_detector_cache->insert( + std::make_pair(form, blink::WebInputElement())); + } + + if (!username_detector_cache || cache_miss) { bool username_found = FindUsernameFieldInternal( all_possible_usernames, form_data, username_element); - if (username_detector_cache) { - (*username_detector_cache)[form] = - username_found ? *username_element : blink::WebInputElement(); - } + if (username_detector_cache && username_found) + form_position->second = *username_element; return username_found; + } else { + *username_element = form_position->second; + return !username_element->IsNull(); } - // Use the cached value for |form|. - *username_element = (*username_detector_cache)[form]; - return !username_element->IsNull(); } } // namespace autofill
diff --git a/components/autofill/content/renderer/html_based_username_detector.h b/components/autofill/content/renderer/html_based_username_detector.h index 11cf121..a7089fd 100644 --- a/components/autofill/content/renderer/html_based_username_detector.h +++ b/components/autofill/content/renderer/html_based_username_detector.h
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <map> + #include "components/autofill/core/common/password_form.h" #include "third_party/WebKit/public/web/WebFormControlElement.h" #include "third_party/WebKit/public/web/WebInputElement.h"
diff --git a/components/autofill/content/renderer/html_based_username_detector_vocabulary.cc b/components/autofill/content/renderer/html_based_username_detector_vocabulary.cc new file mode 100644 index 0000000..abf4e4bf --- /dev/null +++ b/components/autofill/content/renderer/html_based_username_detector_vocabulary.cc
@@ -0,0 +1,234 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/autofill/content/renderer/html_based_username_detector_vocabulary.h" + +#include "base/macros.h" + +namespace autofill { + +const char* const kNegativeLatin[] = { + "pin", "parola", "wagwoord", "wachtwoord", + "fake", "parole", "givenname", "achinsinsi", + "token", "parool", "firstname", "facalfaire", + "fname", "lozinka", "pasahitza", "focalfaire", + "lname", "passord", "pasiwedhi", "iphasiwedi", + "geslo", "huahuna", "passwuert", "katalaluan", + "heslo", "fullname", "phasewete", "adgangskode", + "parol", "optional", "wachtwurd", "contrasenya", + "sandi", "lastname", "cyfrinair", "contrasinal", + "senha", "kupuhipa", "katasandi", "kalmarsirri", + "hidden", "password", "loluszais", "tenimiafina", + "second", "passwort", "middlename", "paroladordine", + "codice", "pasvorto", "familyname", "inomboloyokuvula", + "modpas", "salasana", "motdepasse", "numeraeleiloaesesi"}; +const int kNegativeLatinSize = arraysize(kNegativeLatin); + +const char* const kNegativeNonLatin[] = {"fjalëkalim", + "የይለፍቃል", + "كلمهالسر", + "գաղտնաբառ", + "пароль", + "পাসওয়ার্ড", + "парола", + "密码", + "密碼", + "დაგავიწყდათ", + "κωδικόςπρόσβασης", + "પાસવર્ડ", + "סיסמה", + "पासवर्ड", + "jelszó", + "lykilorð", + "paswọọdụ", + "パスワード", + "ಪಾಸ್ವರ್ಡ್", + "пароль", + "ការពាក្យសម្ងាត់", + "암호", + "şîfre", + "купуясөз", + "ລະຫັດຜ່ານ", + "slaptažodis", + "лозинка", + "पासवर्ड", + "нууцүг", + "စကားဝှက်ကို", + "पासवर्ड", + "رمز", + "کلمهعبور", + "hasło", + "пароль", + "лозинка", + "پاسورڊ", + "මුරපදය", + "contraseña", + "lösenord", + "гузарвожа", + "கடவுச்சொல்", + "పాస్వర్డ్", + "รหัสผ่าน", + "пароль", + "پاسورڈ", + "mậtkhẩu", + "פּאַראָל", + "ọrọigbaniwọle"}; +const int kNegativeNonLatinSize = arraysize(kNegativeNonLatin); + +const char* const kUsernameLatin[] = { + "gatti", "uzantonomo", "solonanarana", "nombredeusuario", + "olumulo", "nomenusoris", "enwdefnyddiwr", "nomdutilisateur", + "lolowera", "notandanafn", "nomedeusuario", "vartotojovardas", + "username", "ahanjirimara", "gebruikersnaam", "numedeutilizator", + "brugernavn", "benotzernumm", "jinalamtumiaji", "erabiltzaileizena", + "brukernavn", "benutzername", "sunanmaiamfani", "foydalanuvchinomi", + "mosebedisi", "kasutajanimi", "ainmcleachdaidh", "igamalomsebenzisi", + "nomdusuari", "lomsebenzisi", "jenengpanganggo", "ingoakaiwhakamahi", + "nomeutente", "namapengguna"}; +const int kUsernameLatinSize = arraysize(kUsernameLatin); + +const char* const kUsernameNonLatin[] = {"用户名", + "کاتيجونالو", + "用戶名", + "የተጠቃሚስም", + "логин", + "اسمالمستخدم", + "נאמען", + "کاصارفکانام", + "ユーザ名", + "όνομα χρήστη", + "brûkersnamme", + "корисничкоиме", + "nonitilizatè", + "корисничкоиме", + "ngaranpamaké", + "ຊື່ຜູ້ໃຊ້", + "användarnamn", + "యూజర్పేరు", + "korisničkoime", + "пайдаланушыаты", + "שםמשתמש", + "ім'якористувача", + "کارننوم", + "хэрэглэгчийннэр", + "nomedeusuário", + "имяпользователя", + "têntruynhập", + "பயனர்பெயர்", + "ainmúsáideora", + "ชื่อผู้ใช้", + "사용자이름", + "імякарыстальніка", + "lietotājvārds", + "потребителскоиме", + "uporabniškoime", + "колдонуучунунаты", + "kullanıcıadı", + "පරිශීලකනාමය", + "istifadəçiadı", + "օգտագործողիանունը", + "navêbikarhêner", + "ಬಳಕೆದಾರಹೆಸರು", + "emriipërdoruesit", + "वापरकर्तानाव", + "käyttäjätunnus", + "વપરાશકર્તાનામ", + "felhasználónév", + "उपयोगकर्तानाम", + "nazwaużytkownika", + "ഉപയോക്തൃനാമം", + "სახელი", + "အသုံးပြုသူအမည်", + "نامکاربری", + "प्रयोगकर्तानाम", + "uživatelskéjméno", + "ব্যবহারকারীরনাম", + "užívateľskémeno", + "ឈ្មោះអ្នកប្រើប្រាស់"}; +const int kUsernameNonLatinSize = arraysize(kUsernameNonLatin); + +const char* const kUserLatin[] = { + "user", "wosuta", "gebruiker", "utilizator", + "usor", "notandi", "gumagamit", "vartotojas", + "fammi", "olumulo", "maiamfani", "cleachdaidh", + "utent", "pemakai", "mpampiasa", "umsebenzisi", + "bruger", "usuario", "panganggo", "utilisateur", + "bruker", "benotzer", "uporabnik", "doutilizador", + "numake", "benutzer", "covneegsiv", "erabiltzaile", + "usuari", "kasutaja", "defnyddiwr", "kaiwhakamahi", + "utente", "korisnik", "mosebedisi", "foydalanuvchi", + "uzanto", "pengguna", "mushandisi"}; +const int kUserLatinSize = arraysize(kUserLatin); + +const char* const kUserNonLatin[] = {"用户", + "użytkownik", + "tagatafaʻaaogā", + "دکارونکيعکس", + "用戶", + "užívateľ", + "корисник", + "карыстальнік", + "brûker", + "kullanıcı", + "истифода", + "អ្នកប្រើ", + "ọrụ", + "ተጠቃሚ", + "באַניצער", + "хэрэглэгчийн", + "يوزر", + "istifadəçi", + "ຜູ້ໃຊ້", + "пользователь", + "صارف", + "meahoʻohana", + "потребител", + "वापरकर्ता", + "uživatel", + "ユーザー", + "מִשׁתַמֵשׁ", + "ผู้ใช้งาน", + "사용자", + "bikaranîvan", + "колдонуучу", + "વપરાશકર્તા", + "përdorues", + "ngườidùng", + "корисникот", + "उपयोगकर्ता", + "itilizatè", + "χρήστης", + "користувач", + "օգտվողիանձնագիրը", + "használó", + "faoiúsáideoir", + "შესახებ", + "ব্যবহারকারী", + "lietotājs", + "பயனர்", + "ಬಳಕೆದಾರ", + "ഉപയോക്താവ്", + "کاربر", + "యూజర్", + "පරිශීලක", + "प्रयोगकर्ता", + "användare", + "المستعمل", + "пайдаланушы", + "အသုံးပြုသူကို", + "käyttäjä"}; +const int kUserNonLatinSize = arraysize(kUserNonLatin); + +const char* const kTechnicalWords[] = { + "uid", "newtel", "uaccount", "regaccount", "ureg", + "loginid", "laddress", "accountreg", "regid", "regname", + "loginname", "membername", "uname", "ucreate", "loginmail", + "accountname", "umail", "loginreg", "accountid", "loginaccount", + "ulogin", "regemail", "newmobile", "accountlogin"}; +const int kTechnicalWordsSize = arraysize(kTechnicalWords); + +const char* const kWeakWords[] = {"id", "login", "mail"}; +const int kWeakWordsSize = arraysize(kWeakWords); + +} // namespace autofill
diff --git a/components/autofill/content/renderer/html_based_username_detector_vocabulary.h b/components/autofill/content/renderer/html_based_username_detector_vocabulary.h new file mode 100644 index 0000000..8164fa2 --- /dev/null +++ b/components/autofill/content/renderer/html_based_username_detector_vocabulary.h
@@ -0,0 +1,39 @@ +// 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. + +namespace autofill { + +// Words that certainly point to a non-username field. +// If field values contain at least one negative word, then the field is +// excluded from the list of possible usernames. +extern const char* const kNegativeLatin[]; +extern const int kNegativeLatinSize; +extern const char* const kNegativeNonLatin[]; +extern const int kNegativeNonLatinSize; + +// Translations of "username". +extern const char* const kUsernameLatin[]; +extern const int kUsernameLatinSize; +extern const char* const kUsernameNonLatin[]; +extern const int kUsernameNonLatinSize; + +// Translations of "user". +extern const char* const kUserLatin[]; +extern const int kUserLatinSize; +extern const char* const kUserNonLatin[]; +extern const int kUserNonLatinSize; + +// Words that certainly point to a username field, if they appear in developer +// value. They are technical words, because they can only be used as variable +// names, and not as stand-alone words. +extern const char* const kTechnicalWords[]; +extern const int kTechnicalWordsSize; + +// Words that might point to a username field.They have the smallest priority +// in the heuristic, because there are also field attribute values that +// contain them, but are not username fields. +extern const char* const kWeakWords[]; +extern const int kWeakWordsSize; + +} // namespace autofill
diff --git a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc index 915a853..b74ba55 100644 --- a/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc +++ b/components/autofill/content/renderer/password_form_conversion_utils_browsertest.cc
@@ -221,7 +221,8 @@ } return CreatePasswordFormFromWebForm( - form, with_user_input ? &user_input : nullptr, predictions, nullptr); + form, with_user_input ? &user_input : nullptr, predictions, + &username_detector_cache_); } // Iterates on the form generated by the |html| and adds the fields and type @@ -270,6 +271,8 @@ *form = forms[0]; } + UsernameDetectorCache username_detector_cache_; + private: DISALLOW_COPY_AND_ASSIGN(MAYBE_PasswordFormConversionUtilsTest); }; @@ -334,7 +337,7 @@ } TEST_F(MAYBE_PasswordFormConversionUtilsTest, - IdentifyingUsernameFieldsFromDeveloperGroupWithHTMLDetector) { + HTMLDetector_DeveloperGroupAttributes) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature( password_manager::features::kEnableHtmlBasedUsernameDetector); @@ -408,17 +411,18 @@ {"email", "", "js@google.com"}, "email", "js@google.com"}, - // If word matches in maximum 2 fields, it is accepted. + // If a word matches in maximum 2 fields, it is accepted. // First encounter is selected as username. - {{"loginusername", "", "johnsmith"}, - {"loginemail", "", "js@google.com"}, - "loginusername", + {{"username", "", "johnsmith"}, + {"repeat_username", "", "johnsmith"}, + "username", "johnsmith"}, - // Check treatment for short dictionary words. - {{"identity_name", "", "johnsmith"}, - {"email", "", "js@google.com"}, - "email", - "js@google.com"}}; + // A short word should be enclosed between delimiters. Otherwise, an + // Occurrence doesn't count. + {{"identity_name", "idn", "johnsmith"}, + {"id", "id", "123"}, + "id", + "123"}}; for (size_t i = 0; i < arraysize(cases); ++i) { SCOPED_TRACE(testing::Message() << "Iteration " << i); @@ -436,6 +440,7 @@ builder.AddSubmitButton("submit"); std::string html = builder.ProduceHTML(); + username_detector_cache_.clear(); std::unique_ptr<PasswordForm> password_form = LoadHTMLAndConvertForm(html, nullptr, false); @@ -445,7 +450,19 @@ password_form->username_element); EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value), password_form->username_value); + // Check that the username field was found by HTML detector. + ASSERT_EQ(1u, username_detector_cache_.size()); + ASSERT_FALSE(username_detector_cache_.begin()->second.IsNull()); + EXPECT_EQ( + cases[i].expected_username_element, + username_detector_cache_.begin()->second.NameForAutofill().Utf8()); } +} + +TEST_F(MAYBE_PasswordFormConversionUtilsTest, HTMLDetector_SeveralDetections) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + password_manager::features::kEnableHtmlBasedUsernameDetector); // If word matches in more than 2 fields, we don't match on it. // We search for match with another word. @@ -459,6 +476,7 @@ builder.AddSubmitButton("submit"); std::string html = builder.ProduceHTML(); + DCHECK(username_detector_cache_.empty()); std::unique_ptr<PasswordForm> password_form = LoadHTMLAndConvertForm(html, nullptr, false); @@ -466,10 +484,15 @@ EXPECT_EQ(base::UTF8ToUTF16("loginid"), password_form->username_element); EXPECT_EQ(base::UTF8ToUTF16("johnsmith"), password_form->username_value); + // Check that the username field was found by HTML detector. + ASSERT_EQ(1u, username_detector_cache_.size()); + ASSERT_FALSE(username_detector_cache_.begin()->second.IsNull()); + EXPECT_EQ("loginid", + username_detector_cache_.begin()->second.NameForAutofill().Utf8()); } TEST_F(MAYBE_PasswordFormConversionUtilsTest, - IdentifyingUsernameFieldsFromUserGroupWithHTMLDetector) { + HTMLDetector_UserGroupAttributes) { base::test::ScopedFeatureList feature_list; feature_list.InitAndEnableFeature( password_manager::features::kEnableHtmlBasedUsernameDetector); @@ -483,12 +506,12 @@ struct TestCase { // Field parameters represent, in order of appearance, field name, field // id, field value and field label or placeholder. + // Field name and field id don't contain any significant information. const char* first_text_field_parameters[4]; const char* second_text_field_parameters[4]; const char* expected_username_element; const char* expected_username_value; } cases[] = { - // Developer group does not contain any significant information. // Label information will decide username. {{"name1", "id1", "johnsmith", "Username:"}, {"name2", "id2", "js@google.com", "Email:"}, @@ -545,9 +568,10 @@ {"username", "", "johnsmith", "Email:"}, "email", "js@google.com"}, - // Check treatment for short dictionary words. + // Check treatment for short dictionary words. "uid" has higher priority, + // but its occurrence is ignored because it is a part of another word. {{"name1", "", "johnsmith", "Insert your id:"}, - {"name2", "", "js@google.com", "Insert something:"}, + {"name2", "uidentical", "js@google.com", "Insert something:"}, "name1", "johnsmith"}}; @@ -569,6 +593,7 @@ builder.AddSubmitButton("submit"); std::string html = builder.ProduceHTML(); + username_detector_cache_.clear(); std::unique_ptr<PasswordForm> password_form = LoadHTMLAndConvertForm(html, nullptr, false); @@ -578,6 +603,12 @@ password_form->username_element); EXPECT_EQ(base::UTF8ToUTF16(cases[i].expected_username_value), password_form->username_value); + // Check that the username field was found by HTML detector. + ASSERT_EQ(1u, username_detector_cache_.size()); + ASSERT_FALSE(username_detector_cache_.begin()->second.IsNull()); + EXPECT_EQ( + cases[i].expected_username_element, + username_detector_cache_.begin()->second.NameForAutofill().Utf8()); } } @@ -613,7 +644,7 @@ // will be the same because it was cached in |username_detector_cache|. WebVector<WebFormControlElement> control_elements; form.GetFormControlElements(control_elements); - control_elements[0].SetAttribute("name", "login"); + control_elements[0].SetAttribute("name", "id"); password_form = CreatePasswordFormFromWebForm(form, nullptr, nullptr, &username_detector_cache); EXPECT_TRUE(password_form); @@ -633,7 +664,7 @@ ASSERT_EQ(1u, username_detector_cache.size()); EXPECT_EQ(form, username_detector_cache.begin()->first); ASSERT_FALSE(username_detector_cache.begin()->second.IsNull()); - EXPECT_EQ("login", + EXPECT_EQ("id", username_detector_cache.begin()->second.NameForAutofill().Utf8()); EXPECT_THAT( histogram_tester.GetAllSamples("PasswordManager.UsernameDetectionMethod"), @@ -650,7 +681,7 @@ ASSERT_EQ(1u, username_detector_cache.size()); EXPECT_EQ(form, username_detector_cache.begin()->first); ASSERT_FALSE(username_detector_cache.begin()->second.IsNull()); - EXPECT_EQ("login", + EXPECT_EQ("id", username_detector_cache.begin()->second.NameForAutofill().Utf8()); EXPECT_THAT( histogram_tester.GetAllSamples("PasswordManager.UsernameDetectionMethod"),
diff --git a/components/autofill/core/browser/credit_card_unittest.cc b/components/autofill/core/browser/credit_card_unittest.cc index e45c40a..b110302 100644 --- a/components/autofill/core/browser/credit_card_unittest.cc +++ b/components/autofill/core/browser/credit_card_unittest.cc
@@ -1271,7 +1271,12 @@ // Test that credit card last used date suggestion can be generated correctly // in different variations. -TEST(CreditCardTest, GetLastUsedDateForDisplay) { + + +// TODO(scottmg): Disabling as sheriff. On Android, LastUsedDateForDisplay is +// returning "Last used over a year ago", rather than "last used Nov 30" as of +// today, Dec 1. https://crbug.com/791067. +TEST(CreditCardTest, DISABLED_GetLastUsedDateForDisplay) { const base::Time::Exploded kTestDateTimeExploded = { 2016, 12, 6, 10, // Sat, Dec 10, 2016 15, 42, 7, 0 // 15:42:07.000
diff --git a/components/os_crypt/key_storage_keyring.cc b/components/os_crypt/key_storage_keyring.cc index 2061e194..af2f64b 100644 --- a/components/os_crypt/key_storage_keyring.cc +++ b/components/os_crypt/key_storage_keyring.cc
@@ -9,8 +9,6 @@ #include "base/rand_util.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" -#include "base/synchronization/waitable_event.h" -#include "base/threading/thread.h" #include "components/os_crypt/keyring_util_linux.h" namespace { @@ -33,50 +31,34 @@ KeyStorageKeyring::~KeyStorageKeyring() {} +base::SequencedTaskRunner* KeyStorageKeyring::GetTaskRunner() { + return main_thread_runner_.get(); +} + bool KeyStorageKeyring::Init() { + DCHECK(main_thread_runner_->RunsTasksInCurrentSequence()); return GnomeKeyringLoader::LoadGnomeKeyring(); } std::string KeyStorageKeyring::GetKeyImpl() { + DCHECK(main_thread_runner_->RunsTasksInCurrentSequence()); + std::string password; - - // Ensure GetKeyDelegate() is executed on the main thread. - if (main_thread_runner_->BelongsToCurrentThread()) { - GetKeyDelegate(&password, nullptr); - } else { - base::WaitableEvent password_loaded( - base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::NOT_SIGNALED); - main_thread_runner_->PostTask( - FROM_HERE, - base::Bind(&KeyStorageKeyring::GetKeyDelegate, base::Unretained(this), - &password, &password_loaded)); - password_loaded.Wait(); - } - - return password; -} - -void KeyStorageKeyring::GetKeyDelegate( - std::string* password_ptr, - base::WaitableEvent* password_loaded_ptr) { - gchar* password = nullptr; + gchar* password_c = nullptr; GnomeKeyringResult result = GnomeKeyringLoader::gnome_keyring_find_password_sync_ptr( - &kSchema, &password, "application", kApplicationName, nullptr); + &kSchema, &password_c, "application", kApplicationName, nullptr); if (result == GNOME_KEYRING_RESULT_OK) { - *password_ptr = password; - GnomeKeyringLoader::gnome_keyring_free_password_ptr(password); + password = password_c; + GnomeKeyringLoader::gnome_keyring_free_password_ptr(password_c); } else if (result == GNOME_KEYRING_RESULT_NO_MATCH) { - *password_ptr = KeyStorageKeyring::AddRandomPasswordInKeyring(); + password = KeyStorageKeyring::AddRandomPasswordInKeyring(); VLOG(1) << "OSCrypt generated a new password"; } else { - password_ptr->clear(); VLOG(1) << "OSCrypt failed to use gnome-keyring"; } - if (password_loaded_ptr) - password_loaded_ptr->Signal(); + return password; } std::string KeyStorageKeyring::AddRandomPasswordInKeyring() {
diff --git a/components/os_crypt/key_storage_keyring.h b/components/os_crypt/key_storage_keyring.h index e186ef1..fb41a708 100644 --- a/components/os_crypt/key_storage_keyring.h +++ b/components/os_crypt/key_storage_keyring.h
@@ -13,7 +13,6 @@ namespace base { class SingleThreadTaskRunner; -class WaitableEvent; } // namespace base // Specialisation of KeyStorageLinux that uses Libsecret. @@ -25,17 +24,11 @@ protected: // KeyStorageLinux + base::SequencedTaskRunner* GetTaskRunner() override; bool Init() override; std::string GetKeyImpl() override; private: - // Gnome keyring requires calls to originate from the main thread. - // This is the part of GetKey() that gets dispatched to the main thread. - // The password is stored in |password_ptr|. If |password_loaded_ptr| is not - // null, it will be signaled when |password_ptr| is safe to read. - void GetKeyDelegate(std::string* password_ptr, - base::WaitableEvent* password_loaded_ptr); - // Generate a random string and store it as OScrypt's new password. std::string AddRandomPasswordInKeyring();
diff --git a/components/password_manager/core/browser/export/destination.h b/components/password_manager/core/browser/export/destination.h index 342601e..a0987a1 100644 --- a/components/password_manager/core/browser/export/destination.h +++ b/components/password_manager/core/browser/export/destination.h
@@ -16,8 +16,9 @@ Destination() = default; virtual ~Destination() = default; - // Send the data to the destination, synchronously. - virtual bool Write(const std::string& data) = 0; + // Send the data to the destination, synchronously. On failure, a + // human-readable error message will be returned. + virtual base::string16 Write(const std::string& data) = 0; }; } // namespace password_manager
diff --git a/components/password_manager/core/browser/export/password_manager_exporter_unittest.cc b/components/password_manager/core/browser/export/password_manager_exporter_unittest.cc index 48dec4b..2ab2407 100644 --- a/components/password_manager/core/browser/export/password_manager_exporter_unittest.cc +++ b/components/password_manager/core/browser/export/password_manager_exporter_unittest.cc
@@ -59,7 +59,7 @@ MockDestination() = default; ~MockDestination() override = default; - MOCK_METHOD1(Write, bool(const std::string& data)); + MOCK_METHOD1(Write, base::string16(const std::string& data)); private: DISALLOW_COPY_AND_ASSIGN(MockDestination);
diff --git a/components/password_manager/core/browser/password_store_factory_util.cc b/components/password_manager/core/browser/password_store_factory_util.cc index f7a9824..4e8cdb8 100644 --- a/components/password_manager/core/browser/password_store_factory_util.cc +++ b/components/password_manager/core/browser/password_store_factory_util.cc
@@ -30,16 +30,21 @@ PasswordStore* password_store, net::URLRequestContextGetter* request_context_getter, const base::FilePath& db_path) { - // The PasswordStore is so far the only consumer of the AffiliationService, - // therefore the service is owned by the AffiliatedMatchHelper, which in - // turn is owned by the PasswordStore. + // Subsequent instances of the AffiliationService must use the same sequenced + // task runner for their backends. This guarantees that the backend of the + // first instance will have closed the affiliation database before the second + // instance attempts to open it again. See: https://crbug.com/786157. + // // Task priority is USER_VISIBLE, because AffiliationService-related tasks - // block obtaining credentials from PasswordStore, which matches the - // USER_VISIBLE example: "Loading data that might be shown in the UI after a - // future user interaction." + // block obtaining credentials from PasswordStore, hence password autofill. + static auto backend_task_runner = base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); + + // The PasswordStore is so far the only consumer of the AffiliationService, + // therefore the service is owned by the AffiliatedMatchHelper, which in turn + // is owned by the PasswordStore. std::unique_ptr<AffiliationService> affiliation_service( - new AffiliationService(base::CreateSequencedTaskRunnerWithTraits( - {base::MayBlock(), base::TaskPriority::USER_VISIBLE}))); + new AffiliationService(backend_task_runner)); affiliation_service->Initialize(request_context_getter, db_path); std::unique_ptr<AffiliatedMatchHelper> affiliated_match_helper( new AffiliatedMatchHelper(password_store,
diff --git a/components/password_manager_strings.grdp b/components/password_manager_strings.grdp index cfc7a00..d0647b2 100644 --- a/components/password_manager_strings.grdp +++ b/components/password_manager_strings.grdp
@@ -19,5 +19,8 @@ <message name="IDS_PASSWORD_MANAGER_DEFAULT_EXPORT_FILENAME" desc="Chrome suggests this file name when user chooses to export their passwords saved with Chrome."> Chrome Passwords </message> + <message name="IDS_PASSWORD_MANAGER_EXPORT_TO_FILE_FAILED" desc="Chrome tried to export the passwords to a file and failed. This message will be the title of the error message that will be shown to the user."> + Can't export passwords to "<ph name="folder">$1<ex>Desktop</ex></ph>" + </message> </grit-part>
diff --git a/components/proxy_config/pref_proxy_config_tracker_impl.cc b/components/proxy_config/pref_proxy_config_tracker_impl.cc index 33ddfac..c39d5e4 100644 --- a/components/proxy_config/pref_proxy_config_tracker_impl.cc +++ b/components/proxy_config/pref_proxy_config_tracker_impl.cc
@@ -127,10 +127,11 @@ PrefProxyConfigTrackerImpl::PrefProxyConfigTrackerImpl( PrefService* pref_service, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) + scoped_refptr<base::SingleThreadTaskRunner> + proxy_config_service_task_runner) : pref_service_(pref_service), proxy_config_service_impl_(nullptr), - io_task_runner_(io_task_runner) { + proxy_config_service_task_runner_(proxy_config_service_task_runner) { pref_config_state_ = ReadPrefConfig(pref_service_, &pref_config_); active_config_state_ = pref_config_state_; active_config_ = pref_config_; @@ -279,7 +280,19 @@ if (!proxy_config_service_impl_) return; - io_task_runner_->PostTask( + + // If the ProxyConfigService lives on the current thread, just synchronously + // tell it about the new configuration. + // TODO(mmenke): When/if iOS is migrated to using the NetworkService, get rid + // of |proxy_config_service_task_runner_|. Can also merge + // ProxyConfigServiceImpl into the tracker, and make the class talk over the + // Mojo pipe directly, at that point. + if (!proxy_config_service_task_runner_) { + proxy_config_service_impl_->UpdateProxyConfig(config_state, config); + return; + } + + proxy_config_service_task_runner_->PostTask( FROM_HERE, base::Bind(&ProxyConfigServiceImpl::UpdateProxyConfig, base::Unretained(proxy_config_service_impl_), config_state, config));
diff --git a/components/proxy_config/pref_proxy_config_tracker_impl.h b/components/proxy_config/pref_proxy_config_tracker_impl.h index b86fb327..4a5b7f5e 100644 --- a/components/proxy_config/pref_proxy_config_tracker_impl.h +++ b/components/proxy_config/pref_proxy_config_tracker_impl.h
@@ -75,14 +75,16 @@ }; // A class that tracks proxy preferences. It translates the configuration -// to net::ProxyConfig and pushes the result over to the IO thread for -// ProxyConfigServiceImpl::UpdateProxyConfig to use. +// to net::ProxyConfig and pushes the result over to +// ProxyConfigServiceImpl::UpdateProxyConfig. class PROXY_CONFIG_EXPORT PrefProxyConfigTrackerImpl : public PrefProxyConfigTracker { public: - PrefProxyConfigTrackerImpl( - PrefService* pref_service, - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner); + // |proxy_config_service_task_runner| is the thread the ProxyConfigService + // will live on. Use nullptr if it lives on the current thread. + PrefProxyConfigTrackerImpl(PrefService* pref_service, + scoped_refptr<base::SingleThreadTaskRunner> + proxy_config_service_task_runner); ~PrefProxyConfigTrackerImpl() override; // PrefProxyConfigTracker implementation: @@ -167,7 +169,7 @@ // Active proxy configuration, last received from OnProxyConfigChanged. net::ProxyConfig active_config_; - scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; + scoped_refptr<base::SingleThreadTaskRunner> proxy_config_service_task_runner_; base::ThreadChecker thread_checker_;
diff --git a/components/storage_monitor/storage_monitor_chromeos.cc b/components/storage_monitor/storage_monitor_chromeos.cc index a31490e..82e0af2 100644 --- a/components/storage_monitor/storage_monitor_chromeos.cc +++ b/components/storage_monitor/storage_monitor_chromeos.cc
@@ -80,9 +80,7 @@ } // namespace -StorageMonitorCros::StorageMonitorCros() - : weak_ptr_factory_(this) { -} +StorageMonitorCros::StorageMonitorCros() : weak_ptr_factory_(this) {} StorageMonitorCros::~StorageMonitorCros() { DiskMountManager* manager = DiskMountManager::GetInstance(); @@ -134,8 +132,13 @@ weak_ptr_factory_.GetWeakPtr())); } -void StorageMonitorCros::OnDiskEvent(DiskMountManager::DiskEvent event, - const DiskMountManager::Disk* disk) {} +void StorageMonitorCros::OnAutoMountableDiskEvent( + DiskMountManager::DiskEvent event, + const DiskMountManager::Disk& disk) {} + +void StorageMonitorCros::OnBootDeviceDiskEvent( + DiskMountManager::DiskEvent event, + const DiskMountManager::Disk& disk) {} void StorageMonitorCros::OnDeviceEvent(DiskMountManager::DeviceEvent event, const std::string& device_path) {} @@ -195,7 +198,6 @@ media_transfer_protocol_manager_.reset(test_manager); } - bool StorageMonitorCros::GetStorageInfoForPath( const base::FilePath& path, StorageInfo* device_info) const {
diff --git a/components/storage_monitor/storage_monitor_chromeos.h b/components/storage_monitor/storage_monitor_chromeos.h index 30034971..4ad37c880 100644 --- a/components/storage_monitor/storage_monitor_chromeos.h +++ b/components/storage_monitor/storage_monitor_chromeos.h
@@ -45,9 +45,12 @@ device::MediaTransferProtocolManager* test_manager); // chromeos::disks::DiskMountManager::Observer implementation. - void OnDiskEvent( + void OnAutoMountableDiskEvent( chromeos::disks::DiskMountManager::DiskEvent event, - const chromeos::disks::DiskMountManager::Disk* disk) override; + const chromeos::disks::DiskMountManager::Disk& disk) override; + void OnBootDeviceDiskEvent( + chromeos::disks::DiskMountManager::DiskEvent event, + const chromeos::disks::DiskMountManager::Disk& disk) override; void OnDeviceEvent(chromeos::disks::DiskMountManager::DeviceEvent event, const std::string& device_path) override; void OnMountEvent(chromeos::disks::DiskMountManager::MountEvent event,
diff --git a/components/viz/service/display_embedder/software_output_device_mac_unittest.mm b/components/viz/service/display_embedder/software_output_device_mac_unittest.mm index 4485632e..ed0b8ad 100644 --- a/components/viz/service/display_embedder/software_output_device_mac_unittest.mm +++ b/components/viz/service/display_embedder/software_output_device_mac_unittest.mm
@@ -13,7 +13,7 @@ TEST(SoftwareOutputDeviceMacTest, Basics) { std::unique_ptr<SoftwareOutputDeviceMac> device( - new SoftwareOutputDeviceMac(nullptr)); + new SoftwareOutputDeviceMac(gfx::kNullAcceleratedWidget)); gfx::Size pixel_size(512, 512); float scale_factor = 1;
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 4acf153..5029537c 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -1709,6 +1709,17 @@ ] } + if (is_chromecast && is_linux) { + sources += [ + "tracing/cast_tracing_agent.cc", + "tracing/cast_tracing_agent.h", + ] + + deps += [ "//chromecast/tracing:system_tracer" ] + + defines += [ "CAST_TRACING_AGENT=1" ] + } + if (is_fuchsia) { sources += [ "child_process_launcher_helper_fuchsia.cc",
diff --git a/content/browser/accessibility/browser_accessibility_manager_mac.mm b/content/browser/accessibility/browser_accessibility_manager_mac.mm index 33c5ec0..423902c 100644 --- a/content/browser/accessibility/browser_accessibility_manager_mac.mm +++ b/content/browser/accessibility/browser_accessibility_manager_mac.mm
@@ -17,6 +17,7 @@ #import "content/browser/accessibility/browser_accessibility_mac.h" #include "content/common/accessibility_messages.h" #include "content/public/browser/browser_thread.h" +#include "ui/accelerated_widget_mac/accelerated_widget_mac.h" #include "ui/accessibility/ax_role_properties.h" namespace { @@ -486,7 +487,10 @@ } NSView* BrowserAccessibilityManagerMac::GetParentView() { - return delegate() ? delegate()->AccessibilityGetAcceleratedWidget() : nullptr; + gfx::AcceleratedWidget accelerated_widget = + delegate() ? delegate()->AccessibilityGetAcceleratedWidget() + : gfx::kNullAcceleratedWidget; + return ui::AcceleratedWidgetMac::GetNSView(accelerated_widget); } } // namespace content
diff --git a/content/browser/background_sync/background_sync_manager_unittest.cc b/content/browser/background_sync/background_sync_manager_unittest.cc index 56ae3820..7b20c5b 100644 --- a/content/browser/background_sync/background_sync_manager_unittest.cc +++ b/content/browser/background_sync/background_sync_manager_unittest.cc
@@ -460,9 +460,8 @@ sw_registration_1_->active_version()->provider_host(); ASSERT_TRUE(provider_host); - // Remove the registration object host (it removes itself from |provider_host| - // upon destruction). - delete provider_host->registration_object_hosts_[sw_registration_1_->id()]; + // Remove the registration object host. + provider_host->registration_object_hosts_.clear(); // Ensure |sw_registration_1_| is the last reference to the registration. ASSERT_TRUE(sw_registration_1_->HasOneRef());
diff --git a/content/browser/devtools/devtools_url_interceptor_request_job.cc b/content/browser/devtools/devtools_url_interceptor_request_job.cc index 5ddde72..c0eaf3c 100644 --- a/content/browser/devtools/devtools_url_interceptor_request_job.cc +++ b/content/browser/devtools/devtools_url_interceptor_request_job.cc
@@ -754,16 +754,15 @@ bool* defer_redirect) { DCHECK_CURRENTLY_ON(BrowserThread::IO); DCHECK(sub_request_); - // If we're not intercepting results then just exit. - if (stage_to_intercept_ == InterceptionStage::DONT_INTERCEPT) { + + // If we're not intercepting results or are a response then cancel this + // redirect and tell the parent request it was redirected through |redirect_|. + if (stage_to_intercept_ == InterceptionStage::DONT_INTERCEPT || + stage_to_intercept_ == InterceptionStage::RESPONSE) { *defer_redirect = false; - return; - } - // If we're a response interception only, we will pick it up on the followup - // request in DevToolsURLInterceptorRequestJob::Start(). - if (stage_to_intercept_ == InterceptionStage::RESPONSE) { - interceptor_->ExpectRequestAfterRedirect(this->request(), interception_id_); - *defer_redirect = false; + ProcessRedirect(redirectinfo.status_code, redirectinfo.new_url.spec()); + redirect_.reset(); + sub_request_.reset(); return; } @@ -781,8 +780,6 @@ } redirect_.reset(new net::RedirectInfo(redirectinfo)); - sub_request_->Cancel(); - sub_request_.reset(); waiting_for_user_response_ = WaitingForUserResponse::WAITING_FOR_REQUEST_ACK; @@ -793,6 +790,7 @@ request_info->redirect_url = redirectinfo.new_url.spec(); BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::BindOnce(callback_, std::move(request_info))); + sub_request_.reset(); } void DevToolsURLInterceptorRequestJob::OnInterceptedRequestResponseStarted( @@ -966,6 +964,24 @@ } } +void DevToolsURLInterceptorRequestJob::ProcessRedirect( + int status_code, + const std::string& new_url) { + // NOTE we don't append the text form of the status code because + // net::HttpResponseHeaders doesn't need that. + std::string raw_headers = base::StringPrintf("HTTP/1.1 %d", status_code); + raw_headers.append(1, '\0'); + raw_headers.append("Location: "); + raw_headers.append(new_url); + raw_headers.append(2, '\0'); + mock_response_details_.reset(new MockResponseDetails( + base::MakeRefCounted<net::HttpResponseHeaders>(raw_headers), "", 0, + base::TimeTicks::Now())); + + interceptor_->ExpectRequestAfterRedirect(request(), interception_id_); + NotifyHeadersComplete(); +} + void DevToolsURLInterceptorRequestJob::GetResponseBody( std::unique_ptr<GetResponseBodyForInterceptionCallback> callback) { DCHECK_CURRENTLY_ON(BrowserThread::IO); @@ -1050,22 +1066,10 @@ if (redirect_) { DCHECK(!is_response_ack); - // NOTE we don't append the text form of the status code because - // net::HttpResponseHeaders doesn't need that. - std::string raw_headers = - base::StringPrintf("HTTP/1.1 %d", redirect_->status_code); - raw_headers.append(1, '\0'); - raw_headers.append("Location: "); - raw_headers.append( + ProcessRedirect( + redirect_->status_code, modifications->modified_url.fromMaybe(redirect_->new_url.spec())); - raw_headers.append(2, '\0'); - mock_response_details_.reset(new MockResponseDetails( - base::MakeRefCounted<net::HttpResponseHeaders>(raw_headers), "", 0, - base::TimeTicks::Now())); redirect_.reset(); - - interceptor_->ExpectRequestAfterRedirect(request(), interception_id_); - NotifyHeadersComplete(); } else if (is_response_ack) { DCHECK(sub_request_); // If we are continuing the request without change we fetch the body.
diff --git a/content/browser/devtools/devtools_url_interceptor_request_job.h b/content/browser/devtools/devtools_url_interceptor_request_job.h index e438fb7..b8792cf 100644 --- a/content/browser/devtools/devtools_url_interceptor_request_job.h +++ b/content/browser/devtools/devtools_url_interceptor_request_job.h
@@ -119,6 +119,7 @@ // |mock_response_|. In some cases (e.g. file access) this may be null. const net::HttpResponseHeaders* GetHttpResponseHeaders() const; + void ProcessRedirect(int status_code, const std::string& new_url); void ProcessInterceptionRespose( std::unique_ptr<DevToolsURLRequestInterceptor::Modifications> modification);
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc index 8cb9a50..3dd4390 100644 --- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc +++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -2528,9 +2528,8 @@ // Cancel the download and wait for download system quiesce. download->Cancel(true); - scoped_refptr<DownloadTestFlushObserver> flush_observer( - new DownloadTestFlushObserver(DownloadManagerForShell(shell()))); - flush_observer->WaitForFlush(); + DownloadTestFlushObserver flush_observer(DownloadManagerForShell(shell())); + flush_observer.WaitForFlush(); // Get the important info from other threads and check it. EXPECT_TRUE(EnsureNoPendingDownloads()); @@ -2568,9 +2567,8 @@ // Cancel the download and wait for download system quiesce. download->Cancel(true); - scoped_refptr<DownloadTestFlushObserver> flush_observer( - new DownloadTestFlushObserver(DownloadManagerForShell(shell()))); - flush_observer->WaitForFlush(); + DownloadTestFlushObserver flush_observer(DownloadManagerForShell(shell())); + flush_observer.WaitForFlush(); // Get the important info from other threads and check it. EXPECT_TRUE(EnsureNoPendingDownloads());
diff --git a/content/browser/download/download_browsertest.cc b/content/browser/download/download_browsertest.cc index 53a8fa1..2a2fad9 100644 --- a/content/browser/download/download_browsertest.cc +++ b/content/browser/download/download_browsertest.cc
@@ -40,10 +40,8 @@ #include "content/browser/download/download_resource_handler.h" #include "content/browser/download/download_task_runner.h" #include "content/browser/download/parallel_download_utils.h" -#include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/download_danger_type.h" -#include "content/public/browser/resource_dispatcher_host_delegate.h" #include "content/public/browser/resource_throttle.h" #include "content/public/common/content_features.h" #include "content/public/common/content_paths.h" @@ -99,17 +97,17 @@ const std::string kOriginTwo = "two.example"; const std::string kOriginThree = "example.com"; -class TestResourceDispatcherHostDelegate - : public ResourceDispatcherHostDelegate { +// Implementation of TestContentBrowserClient that overrides +// AllowRenderingMhtmlOverHttp() and allows consumers to set a value. +class DownloadTestContentBrowserClient : public ContentBrowserClient { public: - TestResourceDispatcherHostDelegate() = default; + DownloadTestContentBrowserClient() = default; - bool AllowRenderingMhtmlOverHttp(net::URLRequest* request) const override { + bool AllowRenderingMhtmlOverHttp( + NavigationUIData* navigation_data) const override { return allowed_rendering_mhtml_over_http_; } - void SetDelegate() { ResourceDispatcherHost::Get()->SetDelegate(this); } - void set_allowed_rendering_mhtml_over_http(bool allowed) { allowed_rendering_mhtml_over_http_ = allowed; } @@ -117,7 +115,7 @@ private: bool allowed_rendering_mhtml_over_http_ = false; - DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcherHostDelegate); + DISALLOW_COPY_AND_ASSIGN(DownloadTestContentBrowserClient); }; class MockDownloadItemObserver : public DownloadItem::Observer { @@ -702,14 +700,6 @@ real_host); host_resolver()->AddRule(TestDownloadHttpResponse::kTestDownloadHostName, real_host); - - test_resource_dispatcher_host_delegate_ = - std::make_unique<TestResourceDispatcherHostDelegate>(); - content::BrowserThread::PostTask( - content::BrowserThread::IO, FROM_HERE, - base::BindOnce( - &TestResourceDispatcherHostDelegate::SetDelegate, - base::Unretained(test_resource_dispatcher_host_delegate_.get()))); } void SetUpCommandLine(base::CommandLine* command_line) override { @@ -873,18 +863,12 @@ return inject_error_callback_; } - TestResourceDispatcherHostDelegate* test_resource_dispatcher_host_delegate() { - return test_resource_dispatcher_host_delegate_.get(); - } - private: // Location of the downloads directory for these tests base::ScopedTempDir downloads_directory_; std::unique_ptr<TestShellDownloadManagerDelegate> test_delegate_; TestDownloadResponseHandler test_response_handler_; TestDownloadHttpResponse::InjectErrorCallback inject_error_callback_; - std::unique_ptr<TestResourceDispatcherHostDelegate> - test_resource_dispatcher_host_delegate_; }; // Test fixture for parallel downloading. @@ -912,7 +896,7 @@ } // namespace // Flaky. See https://crbug.com/754679. -IN_PROC_BROWSER_TEST_F(DownloadContentTest, DISABLED_DownloadCancelled) { +IN_PROC_BROWSER_TEST_F(DownloadContentTest, DownloadCancelled) { SetupEnsureNoPendingDownloads(); // Create a download, wait until it's started, and confirm @@ -925,9 +909,8 @@ // Cancel the download and wait for download system quiesce. download->Cancel(true); - scoped_refptr<DownloadTestFlushObserver> flush_observer( - new DownloadTestFlushObserver(DownloadManagerForShell(shell()))); - flush_observer->WaitForFlush(); + DownloadTestFlushObserver flush_observer(DownloadManagerForShell(shell())); + flush_observer.WaitForFlush(); // Get the important info from other threads and check it. EXPECT_TRUE(EnsureNoPendingDownloads()); @@ -2891,8 +2874,14 @@ download->GetTargetFilePath().BaseName().value().c_str()); } +#if defined(OS_ANDROID) +// Flaky on android: https://crbug.com/786626 +#define MAYBE_ParallelDownloadComplete DISABLED_ParallelDownloadComplete +#else +#define MAYBE_ParallelDownloadComplete ParallelDownloadComplete +#endif // Verify parallel download in normal case. -IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, ParallelDownloadComplete) { +IN_PROC_BROWSER_TEST_F(ParallelDownloadTest, MAYBE_ParallelDownloadComplete) { EXPECT_TRUE(base::FeatureList::IsEnabled(features::kParallelDownloading)); GURL url = TestDownloadHttpResponse::GetNextURLForDownload(); @@ -3115,18 +3104,21 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ForceDownloadMhtml) { // Force downloading the MHTML. - test_resource_dispatcher_host_delegate() - ->set_allowed_rendering_mhtml_over_http(false); + DownloadTestContentBrowserClient new_client; + new_client.set_allowed_rendering_mhtml_over_http(false); + ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); NavigateToURLAndWaitForDownload( shell(), embedded_test_server()->GetURL("/download/hello.mhtml"), DownloadItem::COMPLETE); + SetBrowserClientForTesting(old_client); } IN_PROC_BROWSER_TEST_F(DownloadContentTest, AllowRenderMhtml) { // Allows loading the MHTML, instead of downloading it. - test_resource_dispatcher_host_delegate() - ->set_allowed_rendering_mhtml_over_http(true); + DownloadTestContentBrowserClient new_client; + new_client.set_allowed_rendering_mhtml_over_http(true); + ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); GURL url = embedded_test_server()->GetURL("/download/hello.mhtml"); auto observer = std::make_unique<content::TestNavigationObserver>(url); @@ -3136,6 +3128,7 @@ NavigateToURL(shell(), url); observer->WaitForNavigationFinished(); + SetBrowserClientForTesting(old_client); } } // namespace content
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index d563c284..b3bfdd5 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -135,13 +135,15 @@ // TODO(clamy): This should match what's happening in // blink::FrameFetchContext::addAdditionalRequestHeaders. -void AddAdditionalRequestHeaders(net::HttpRequestHeaders* headers, - const GURL& url, - FrameMsg_Navigate_Type::Value navigation_type, - BrowserContext* browser_context, - const std::string& method, - const std::string user_agent_override, - FrameTreeNode* frame_tree_node) { +void AddAdditionalRequestHeaders( + net::HttpRequestHeaders* headers, + std::unique_ptr<net::HttpRequestHeaders> embedder_additional_headers, + const GURL& url, + FrameMsg_Navigate_Type::Value navigation_type, + BrowserContext* browser_context, + const std::string& method, + const std::string user_agent_override, + FrameTreeNode* frame_tree_node) { if (!url.SchemeIsHTTPOrHTTPS()) return; @@ -158,9 +160,6 @@ } // Attach additional request headers specified by embedder. - std::unique_ptr<net::HttpRequestHeaders> embedder_additional_headers = - GetContentClient()->browser()->GetAdditionalNavigationRequestHeaders( - browser_context, url); if (embedder_additional_headers) headers->MergeFrom(*(embedder_additional_headers.get())); @@ -394,10 +393,18 @@ frame_tree_node_->navigator()->GetDelegate()->GetUserAgentOverride(); } + std::unique_ptr<net::HttpRequestHeaders> embedder_additional_headers; + int additional_load_flags = 0; + GetContentClient()->browser()->NavigationRequestStarted( + frame_tree_node->frame_tree_node_id(), common_params_.url, + &embedder_additional_headers, &additional_load_flags); + begin_params_->load_flags |= additional_load_flags; + net::HttpRequestHeaders headers; headers.AddHeadersFromString(begin_params_->headers); AddAdditionalRequestHeaders( - &headers, common_params_.url, common_params_.navigation_type, + &headers, std::move(embedder_additional_headers), common_params_.url, + common_params_.navigation_type, frame_tree_node_->navigator()->GetController()->GetBrowserContext(), common_params.method, user_agent_override, frame_tree_node);
diff --git a/content/browser/generic_sensor_browsertest.cc b/content/browser/generic_sensor_browsertest.cc index cf0c4dc..af69ad6 100644 --- a/content/browser/generic_sensor_browsertest.cc +++ b/content/browser/generic_sensor_browsertest.cc
@@ -233,7 +233,13 @@ DISALLOW_COPY_AND_ASSIGN(GenericSensorBrowserTest); }; -IN_PROC_BROWSER_TEST_F(GenericSensorBrowserTest, AmbientLightSensorTest) { +// Flakily crashes on Linux ASAN/TSAN bots. https://crbug.com/789515 +#if defined(OS_LINUX) +#define MAYBE_AmbientLightSensorTest DISABLED_AmbientLightSensorTest +#else +#define MAYBE_AmbientLightSensorTest AmbientLightSensorTest +#endif +IN_PROC_BROWSER_TEST_F(GenericSensorBrowserTest, MAYBE_AmbientLightSensorTest) { // The test page will create an AmbientLightSensor object in Javascript, // expects to get events with fake values then navigates to #pass. GURL test_url =
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index e9d16b4..f3963ef0 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -509,7 +509,7 @@ if (g_gpu_process_hosts[kind_] == this) g_gpu_process_hosts[kind_] = nullptr; -#if defined(OS_MACOSX) || defined(OS_ANDROID) +#if defined(OS_ANDROID) UMA_HISTOGRAM_COUNTS_100("GPU.AtExitSurfaceCount", gpu::GpuSurfaceTracker::Get()->GetSurfaceCount()); #endif
diff --git a/content/browser/loader/mime_sniffing_resource_handler.cc b/content/browser/loader/mime_sniffing_resource_handler.cc index 130041fe..e04648f 100644 --- a/content/browser/loader/mime_sniffing_resource_handler.cc +++ b/content/browser/loader/mime_sniffing_resource_handler.cc
@@ -527,11 +527,13 @@ } else if (request()->url().SchemeIsHTTPOrHTTPS() && // The MHTML mime type should be same as the one we check in // Blink's DocumentLoader. - response_->head.mime_type == "multipart/related" && - !host_->delegate()->AllowRenderingMhtmlOverHttp(request())) { - // Force to download the MHTML page from the remote server, instead of - // loading it. - must_download_ = true; + response_->head.mime_type == "multipart/related") { + // It is OK to load the saved offline copy, in MHTML format. + const ResourceRequestInfo* info = + ResourceRequestInfo::ForRequest(request()); + must_download_ = + !GetContentClient()->browser()->AllowRenderingMhtmlOverHttp( + info->GetNavigationUIData()); } else { must_download_ = false; }
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc index ad08aa9..d7ace9b4 100644 --- a/content/browser/loader/navigation_url_loader_network_service.cc +++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -538,6 +538,8 @@ DISALLOW_COPY_AND_ASSIGN(URLLoaderRequestController); }; +// TODO(https://crbug.com/790734): pass |navigation_ui_data| along with the +// request so that it could be modified. NavigationURLLoaderNetworkService::NavigationURLLoaderNetworkService( ResourceContext* resource_context, StoragePartition* storage_partition, @@ -743,6 +745,11 @@ net::HttpContentDisposition(disposition, std::string()) .is_attachment()) { return true; + } else if (response_->head.mime_type == "multipart/related") { + // TODO(https://crbug.com/790734): retrieve the new NavigationUIData from + // the request and and pass it to AllowRenderingMhtmlOverHttp(). + return !GetContentClient()->browser()->AllowRenderingMhtmlOverHttp( + nullptr); } // TODO(qinmin): Check whether this is special-case user script that needs // to be downloaded.
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm index bf07eba..deb279e4 100644 --- a/content/browser/renderer_host/render_widget_host_view_mac.mm +++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -1733,8 +1733,15 @@ return gfx::Point(originInScreen.x, originInScreen.y); } -NSView* RenderWidgetHostViewMac::AccessibilityGetAcceleratedWidget() { - return cocoa_view_; +gfx::AcceleratedWidget +RenderWidgetHostViewMac::AccessibilityGetAcceleratedWidget() { + if (browser_compositor_) { + ui::AcceleratedWidgetMac* accelerated_widget_mac = + browser_compositor_->GetAcceleratedWidgetMac(); + if (accelerated_widget_mac) + return accelerated_widget_mac->accelerated_widget(); + } + return gfx::kNullAcceleratedWidget; } void RenderWidgetHostViewMac::SetTextInputActive(bool active) {
diff --git a/content/browser/service_worker/service_worker_job_unittest.cc b/content/browser/service_worker/service_worker_job_unittest.cc index 70a8ce4..d264b6ce 100644 --- a/content/browser/service_worker/service_worker_job_unittest.cc +++ b/content/browser/service_worker/service_worker_job_unittest.cc
@@ -362,9 +362,9 @@ // Clear all service worker handles. dispatcher_host->Clear(); EXPECT_EQ(0UL, dispatcher_host->handles().size()); - // The service worker registration object host has been destroyed by the above - // unregistration. Then the only reference to the registration should be - // |registration|. + // The service worker registration object host has been destroyed together + // with |provider_host| by the above unregistration. Then the only reference + // to the registration should be |registration|. EXPECT_TRUE(registration->HasOneRef()); registration = FindRegistrationForPattern(pattern, @@ -435,7 +435,7 @@ dispatcher_host->Clear(); // Ensure that the registration's object host doesn't have the reference. EXPECT_EQ(1UL, provider_host->registration_object_hosts_.size()); - delete provider_host->registration_object_hosts_[old_registration->id()]; + provider_host->registration_object_hosts_.clear(); EXPECT_EQ(0UL, provider_host->registration_object_hosts_.size()); ASSERT_TRUE(old_registration->HasOneRef());
diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc index db1d532..ca80f936 100644 --- a/content/browser/service_worker/service_worker_provider_host.cc +++ b/content/browser/service_worker/service_worker_provider_host.cc
@@ -1214,11 +1214,9 @@ if (existing_host != registration_object_hosts_.end()) { return existing_host->second->CreateObjectInfo(); } - // The newly created ServiceWorkerRegistrationObjectHost instance will destroy - // itself once it loses all its Mojo bindings. registration_object_hosts_[registration_id] = - new ServiceWorkerRegistrationObjectHost(context_, AsWeakPtr(), - std::move(registration)); + std::make_unique<ServiceWorkerRegistrationObjectHost>( + context_, this, std::move(registration)); return registration_object_hosts_[registration_id]->CreateObjectInfo(); }
diff --git a/content/browser/service_worker/service_worker_provider_host.h b/content/browser/service_worker/service_worker_provider_host.h index 5c3522f..f4c69d0 100644 --- a/content/browser/service_worker/service_worker_provider_host.h +++ b/content/browser/service_worker/service_worker_provider_host.h
@@ -509,7 +509,8 @@ // the service worker registration JavaScript objects for the hosted execution // context (service worker global scope or service worker client) in the // renderer process. - std::map<int64_t /* registration_id */, ServiceWorkerRegistrationObjectHost*> + std::map<int64_t /* registration_id */, + std::unique_ptr<ServiceWorkerRegistrationObjectHost>> registration_object_hosts_; // The ready() promise is only allowed to be created once.
diff --git a/content/browser/service_worker/service_worker_registration_object_host.cc b/content/browser/service_worker/service_worker_registration_object_host.cc index 56d91d3a..5f2606a 100644 --- a/content/browser/service_worker/service_worker_registration_object_host.cc +++ b/content/browser/service_worker/service_worker_registration_object_host.cc
@@ -4,6 +4,7 @@ #include "content/browser/service_worker/service_worker_registration_object_host.h" +#include "base/memory/ptr_util.h" #include "content/browser/service_worker/service_worker_consts.h" #include "content/browser/service_worker/service_worker_context_core.h" #include "content/browser/service_worker/service_worker_handle.h" @@ -17,13 +18,13 @@ ServiceWorkerRegistrationObjectHost::ServiceWorkerRegistrationObjectHost( base::WeakPtr<ServiceWorkerContextCore> context, - base::WeakPtr<ServiceWorkerProviderHost> provider_host, + ServiceWorkerProviderHost* provider_host, scoped_refptr<ServiceWorkerRegistration> registration) : provider_host_(provider_host), context_(context), registration_(registration), weak_ptr_factory_(this) { - DCHECK(registration_); + DCHECK(registration_.get()); DCHECK(provider_host_); registration_->AddListener(this); bindings_.set_connection_error_handler( @@ -32,16 +33,12 @@ } ServiceWorkerRegistrationObjectHost::~ServiceWorkerRegistrationObjectHost() { - if (provider_host_) { - provider_host_->RemoveServiceWorkerRegistrationObjectHost( - registration_->id()); - } + DCHECK(registration_.get()); registration_->RemoveListener(this); } blink::mojom::ServiceWorkerRegistrationObjectInfoPtr ServiceWorkerRegistrationObjectHost::CreateObjectInfo() { - DCHECK(provider_host_); auto info = blink::mojom::ServiceWorkerRegistrationObjectInfo::New(); info->options = blink::mojom::ServiceWorkerRegistrationOptions::New( registration_->pattern()); @@ -103,7 +100,7 @@ context_->UpdateServiceWorker( registration_.get(), false /* force_bypass_cache */, - false /* skip_script_comparison */, provider_host_.get(), + false /* skip_script_comparison */, provider_host_, base::AdaptCallbackForRepeating( base::BindOnce(&ServiceWorkerRegistrationObjectHost::UpdateComplete, weak_ptr_factory_.GetWeakPtr(), std::move(callback)))); @@ -184,13 +181,6 @@ if (!net::HttpUtil::IsValidHeaderValue(value)) { bindings_.ReportBadMessage( ServiceWorkerConsts::kBadNavigationPreloadHeaderValue); - // The above ReportBadMessage() has erased the current dispatch binding from - // |bindings_|, but does not invoke OnConnectionError(), so we have to - // invoke it by ourselves, because it is necessary for us to determine - // whether |this| should destroy (whether |bindings_| is empty). - // TODO(leonhsl): Once crbug.com/789816 makes ReportBadMessage() internally - // invoke the connection error handler, we can remove this invocation. - OnConnectionError(); return; } @@ -280,8 +270,6 @@ ServiceWorkerVersion* installing_version, ServiceWorkerVersion* waiting_version, ServiceWorkerVersion* active_version) { - if (!provider_host_) - return; if (!changed_mask.changed()) return; @@ -306,7 +294,9 @@ // If there are still bindings, |this| is still being used. if (!bindings_.empty()) return; - delete this; + // Will destroy |this|. + provider_host_->RemoveServiceWorkerRegistrationObjectHost( + registration()->id()); } template <typename CallbackType, typename... Args> @@ -314,7 +304,7 @@ CallbackType* callback, const char* error_prefix, Args... args) { - if (!provider_host_ || !context_) { + if (!context_) { std::move(*callback).Run( blink::mojom::ServiceWorkerErrorType::kAbort, std::string(error_prefix) + @@ -338,13 +328,6 @@ registration_->pattern()}; if (!ServiceWorkerUtils::AllOriginsMatchAndCanAccessServiceWorkers(urls)) { bindings_.ReportBadMessage(ServiceWorkerConsts::kBadMessageImproperOrigins); - // The above ReportBadMessage() has erased the current dispatch binding from - // |bindings_|, but does not invoke OnConnectionError(), so we have to - // invoke it by ourselves, because it is necessary for us to determine - // whether |this| should destroy (whether |bindings_| is empty). - // TODO(leonhsl): Once crbug.com/789816 makes ReportBadMessage() internally - // invoke the connection error handler, we can remove this invocation. - OnConnectionError(); return false; }
diff --git a/content/browser/service_worker/service_worker_registration_object_host.h b/content/browser/service_worker/service_worker_registration_object_host.h index 771009a..be87d38c 100644 --- a/content/browser/service_worker/service_worker_registration_object_host.h +++ b/content/browser/service_worker/service_worker_registration_object_host.h
@@ -23,10 +23,9 @@ // ServiceWorkerRegistrationObjectHost has a 1:1 correspondence to // WebServiceWorkerRegistration in the renderer process. -// The host manages its own lifetime. It stays alive while the -// WebServiceWorkerRegistration is alive, and destroys itself when it detects -// that it's no longer needed. It also initiates destruction of the -// WebServiceWorkerRegistration. See the class documentation in +// The host stays alive while the WebServiceWorkerRegistration is alive, and +// also initiates destruction of the WebServiceWorkerRegistration once detected +// that it's no longer needed. See the class documentation in // WebServiceWorkerRegistrationImpl for details. // // Has a reference to the corresponding ServiceWorkerRegistration in order to @@ -37,7 +36,7 @@ public: ServiceWorkerRegistrationObjectHost( base::WeakPtr<ServiceWorkerContextCore> context, - base::WeakPtr<ServiceWorkerProviderHost> provider_host, + ServiceWorkerProviderHost* provider_host, scoped_refptr<ServiceWorkerRegistration> registration); ~ServiceWorkerRegistrationObjectHost() override; @@ -47,10 +46,6 @@ ServiceWorkerRegistration* registration() { return registration_.get(); } private: - FRIEND_TEST_ALL_PREFIXES(ServiceWorkerJobTest, RegisterDuplicateScript); - FRIEND_TEST_ALL_PREFIXES(BackgroundSyncManagerTest, - RegisterWithoutLiveSWRegistration); - // ServiceWorkerRegistration::Listener overrides. void OnVersionAttributesChanged( ServiceWorkerRegistration* registration, @@ -111,7 +106,9 @@ const char* error_prefix, Args... args); - base::WeakPtr<ServiceWorkerProviderHost> provider_host_; + // |provider_host_| is valid throughout lifetime of |this| because it owns + // |this|. + ServiceWorkerProviderHost* provider_host_; base::WeakPtr<ServiceWorkerContextCore> context_; mojo::AssociatedBindingSet<blink::mojom::ServiceWorkerRegistrationObjectHost> bindings_;
diff --git a/content/browser/service_worker/service_worker_registration_unittest.cc b/content/browser/service_worker/service_worker_registration_unittest.cc index 4b5505f..2dc47b9 100644 --- a/content/browser/service_worker/service_worker_registration_unittest.cc +++ b/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -269,9 +269,9 @@ helper_->mock_render_process_id(), 1 /* dummy provider_id */, context()->AsWeakPtr(), 1 /* route_id */, dispatcher_host.get(), &remote_endpoint); - // |registration_object_host| will destroy by itself. - auto* registration_object_host = new ServiceWorkerRegistrationObjectHost( - context()->AsWeakPtr(), provider_host->AsWeakPtr(), registration); + auto registration_object_host = + std::make_unique<ServiceWorkerRegistrationObjectHost>( + context()->AsWeakPtr(), provider_host.get(), registration); // To enable the caller end point // |registration_object_host->remote_registration_| to make calls safely with // no need to pass |object_info_->request| through a message pipe endpoint.
diff --git a/content/browser/service_worker/service_worker_url_request_job_unittest.cc b/content/browser/service_worker/service_worker_url_request_job_unittest.cc index 8996b28..f844794 100644 --- a/content/browser/service_worker/service_worker_url_request_job_unittest.cc +++ b/content/browser/service_worker/service_worker_url_request_job_unittest.cc
@@ -18,7 +18,6 @@ #include "base/test/histogram_tester.h" #include "base/test/simple_test_tick_clock.h" #include "base/threading/thread_task_runner_handle.h" -#include "base/time/default_tick_clock.h" #include "base/time/time.h" #include "content/browser/blob_storage/chrome_blob_storage_context.h" #include "content/browser/loader/resource_request_info_impl.h" @@ -422,6 +421,7 @@ // --------------------------------------------------------------------------- TestBrowserThreadBundle thread_bundle_; + base::SimpleTestTickClock tick_clock_; std::unique_ptr<TestBrowserContext> browser_context_; std::unique_ptr<EmbeddedWorkerTestHelper> helper_; @@ -711,14 +711,12 @@ version_->SetStatus(ServiceWorkerVersion::ACTIVATED); // Set mock clock on version_ to check timeout behavior. - base::SimpleTestTickClock tick_clock; - tick_clock.SetNowTicks(base::TimeTicks::Now()); - version_->SetTickClockForTesting(&tick_clock); + tick_clock_.SetNowTicks(base::TimeTicks::Now()); + version_->SetTickClockForTesting(&tick_clock_); protocol_handler_->set_custom_timeout(base::TimeDelta::FromSeconds(5)); TestRequest(200, "OK", std::string(), true /* expect_valid_ssl */); EXPECT_EQ(base::TimeDelta::FromSeconds(5), version_->remaining_timeout()); - version_->SetTickClockForTesting(base::DefaultTickClock::GetInstance()); } class ProviderDeleteHelper : public EmbeddedWorkerTestHelper {
diff --git a/content/browser/tracing/DEPS b/content/browser/tracing/DEPS index c50f522..fddb5c8 100644 --- a/content/browser/tracing/DEPS +++ b/content/browser/tracing/DEPS
@@ -7,5 +7,8 @@ specific_include_rules = { "tracing_controller_impl\.cc": [ "+v8" + ], + "cast_tracing_agent\.": [ + "+chromecast/tracing" ] }
diff --git a/content/browser/tracing/cast_tracing_agent.cc b/content/browser/tracing/cast_tracing_agent.cc new file mode 100644 index 0000000..5e045ffe --- /dev/null +++ b/content/browser/tracing/cast_tracing_agent.cc
@@ -0,0 +1,169 @@ +// 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 "content/browser/tracing/cast_tracing_agent.h" + +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/logging.h" +#include "base/task_scheduler/task_scheduler.h" +#include "base/trace_event/trace_config.h" +#include "chromecast/tracing/system_tracing_common.h" +#include "content/public/browser/browser_thread.h" +#include "mojo/public/cpp/bindings/interface_request.h" +#include "services/resource_coordinator/public/interfaces/service_constants.mojom.h" +#include "services/service_manager/public/cpp/connector.h" + +namespace content { +namespace { + +std::string GetTracingCategories( + const base::trace_event::TraceConfig& trace_config) { + std::vector<base::StringPiece> categories; + for (size_t i = 0; i < chromecast::tracing::kCategoryCount; ++i) { + base::StringPiece category(chromecast::tracing::kCategories[i]); + if (trace_config.category_filter().IsCategoryGroupEnabled(category)) + categories.push_back(category); + } + return base::JoinString(categories, ","); +} + +} // namespace + +CastTracingAgent::CastTracingAgent(service_manager::Connector* connector) + : binding_(this) { + // Connecto to the agent registry interface. + tracing::mojom::AgentRegistryPtr agent_registry; + connector->BindInterface(resource_coordinator::mojom::kServiceName, + &agent_registry); + + // Register this agent. + tracing::mojom::AgentPtr agent; + binding_.Bind(mojo::MakeRequest(&agent)); + static const char kFtraceLabel[] = "systemTraceEvents"; + agent_registry->RegisterAgent(std::move(agent), kFtraceLabel, + tracing::mojom::TraceDataType::STRING, + false /* supports_explicit_clock_sync */); + + task_runner_ = + base::TaskScheduler::GetInstance()->CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::BACKGROUND, + base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}); +} + +CastTracingAgent::~CastTracingAgent() = default; + +// tracing::mojom::Agent. Called by Mojo internals on the UI thread. +void CastTracingAgent::StartTracing( + const std::string& config, + base::TimeTicks coordinator_time, + const Agent::StartTracingCallback& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + base::trace_event::TraceConfig trace_config(config); + + if (!trace_config.IsSystraceEnabled()) { + callback.Run(false /* success */); + return; + } + + start_tracing_callback_ = callback; + + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&CastTracingAgent::StartTracingOnIO, + base::Unretained(this), + base::ThreadTaskRunnerHandle::Get(), + GetTracingCategories(trace_config))); +} + +void CastTracingAgent::StopAndFlush(tracing::mojom::RecorderPtr recorder) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + recorder_ = std::move(recorder); + + task_runner_->PostTask(FROM_HERE, + base::BindOnce(&CastTracingAgent::StopAndFlushOnIO, + base::Unretained(this), + base::ThreadTaskRunnerHandle::Get())); +} + +void CastTracingAgent::RequestClockSyncMarker( + const std::string& sync_id, + const Agent::RequestClockSyncMarkerCallback& callback) { + NOTREACHED(); +} + +void CastTracingAgent::GetCategories( + const Agent::GetCategoriesCallback& callback) { + callback.Run("" /* categories */); +} + +void CastTracingAgent::RequestBufferStatus( + const Agent::RequestBufferStatusCallback& callback) { + callback.Run(0 /* capacity */, 0 /* count */); +} + +void CastTracingAgent::StartTracingOnIO( + scoped_refptr<base::TaskRunner> reply_task_runner, + const std::string& categories) { + system_tracer_ = std::make_unique<chromecast::SystemTracer>(); + + system_tracer_->StartTracing( + categories, base::BindOnce(&CastTracingAgent::FinishStartOnIO, + base::Unretained(this), reply_task_runner)); +} + +void CastTracingAgent::FinishStartOnIO( + scoped_refptr<base::TaskRunner> reply_task_runner, + chromecast::SystemTracer::Status status) { + reply_task_runner->PostTask(FROM_HERE, + base::BindOnce(&CastTracingAgent::FinishStart, + base::Unretained(this), status)); + if (status != chromecast::SystemTracer::Status::OK) { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&CastTracingAgent::CleanupOnIO, base::Unretained(this))); + } +} + +void CastTracingAgent::FinishStart(chromecast::SystemTracer::Status status) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + start_tracing_callback_.Run(status == chromecast::SystemTracer::Status::OK); +} + +void CastTracingAgent::StopAndFlushOnIO( + scoped_refptr<base::TaskRunner> reply_task_runner) { + system_tracer_->StopTracing( + base::BindRepeating(&CastTracingAgent::HandleTraceDataOnIO, + base::Unretained(this), reply_task_runner)); +} + +void CastTracingAgent::HandleTraceDataOnIO( + scoped_refptr<base::TaskRunner> reply_task_runner, + chromecast::SystemTracer::Status status, + std::string trace_data) { + reply_task_runner->PostTask( + FROM_HERE, + base::BindOnce(&CastTracingAgent::HandleTraceData, base::Unretained(this), + status, std::move(trace_data))); + if (status != chromecast::SystemTracer::Status::KEEP_GOING) { + base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::BindOnce(&CastTracingAgent::CleanupOnIO, base::Unretained(this))); + } +} + +void CastTracingAgent::HandleTraceData(chromecast::SystemTracer::Status status, + std::string trace_data) { + if (recorder_ && status != chromecast::SystemTracer::Status::FAIL) + recorder_->AddChunk(std::move(trace_data)); + if (status != chromecast::SystemTracer::Status::KEEP_GOING) + recorder_.reset(); +} + +void CastTracingAgent::CleanupOnIO() { + system_tracer_.reset(); +} + +} // namespace content
diff --git a/content/browser/tracing/cast_tracing_agent.h b/content/browser/tracing/cast_tracing_agent.h new file mode 100644 index 0000000..7ad9d9a --- /dev/null +++ b/content/browser/tracing/cast_tracing_agent.h
@@ -0,0 +1,70 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_TRACING_CAST_TRACING_AGENT_H_ +#define CONTENT_BROWSER_TRACING_CAST_TRACING_AGENT_H_ + +#include <memory> +#include <string> + +#include "chromecast/tracing/system_tracer.h" +#include "mojo/public/cpp/bindings/binding.h" +#include "services/resource_coordinator/public/interfaces/tracing/tracing.mojom.h" + +namespace service_manager { +class Connector; +} // namespace service_manager + +namespace chromecast { +class SystemTracer; +} + +namespace content { + +class CastTracingAgent : public tracing::mojom::Agent { + public: + explicit CastTracingAgent(service_manager::Connector* connector); + ~CastTracingAgent() override; + + private: + // tracing::mojom::Agent. Called by Mojo internals on the UI thread. + void StartTracing(const std::string& config, + base::TimeTicks coordinator_time, + const Agent::StartTracingCallback& callback) override; + void StopAndFlush(tracing::mojom::RecorderPtr recorder) override; + void RequestClockSyncMarker( + const std::string& sync_id, + const Agent::RequestClockSyncMarkerCallback& callback) override; + void GetCategories(const Agent::GetCategoriesCallback& callback) override; + void RequestBufferStatus( + const Agent::RequestBufferStatusCallback& callback) override; + + void StartTracingOnIO(scoped_refptr<base::TaskRunner> reply_task_runner, + const std::string& categories); + void FinishStartOnIO(scoped_refptr<base::TaskRunner> reply_task_runner, + chromecast::SystemTracer::Status status); + void FinishStart(chromecast::SystemTracer::Status status); + void StopAndFlushOnIO(scoped_refptr<base::TaskRunner> reply_task_runner); + void HandleTraceDataOnIO(scoped_refptr<base::TaskRunner> reply_task_runner, + chromecast::SystemTracer::Status, + std::string trace_data); + void HandleTraceData(chromecast::SystemTracer::Status status, + std::string trace_data); + void CleanupOnIO(); + + mojo::Binding<tracing::mojom::Agent> binding_; + Agent::StartTracingCallback start_tracing_callback_; + tracing::mojom::RecorderPtr recorder_; + + // Task runner for collecting traces in a worker thread. + scoped_refptr<base::SequencedTaskRunner> task_runner_; + + std::unique_ptr<chromecast::SystemTracer> system_tracer_; + + DISALLOW_COPY_AND_ASSIGN(CastTracingAgent); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_TRACING_CAST_TRACING_AGENT_H_
diff --git a/content/browser/tracing/tracing_controller_impl.cc b/content/browser/tracing/tracing_controller_impl.cc index 1008cd71..fc8b15c 100644 --- a/content/browser/tracing/tracing_controller_impl.cc +++ b/content/browser/tracing/tracing_controller_impl.cc
@@ -54,6 +54,10 @@ #include "content/browser/tracing/cros_tracing_agent.h" #endif +#if defined(CAST_TRACING_AGENT) +#include "content/browser/tracing/cast_tracing_agent.h" +#endif + #if defined(OS_WIN) #include "content/browser/tracing/etw_tracing_agent_win.h" #endif @@ -139,6 +143,8 @@ #if defined(OS_CHROMEOS) agents_.push_back(std::make_unique<CrOSTracingAgent>(connector)); agents_.push_back(std::make_unique<ArcTracingAgentImpl>(connector)); +#elif defined(CAST_TRACING_AGENT) + agents_.push_back(std::make_unique<CastTracingAgent>(connector)); #elif defined(OS_WIN) agents_.push_back(std::make_unique<EtwTracingAgent>(connector)); #endif
diff --git a/content/network/network_context.cc b/content/network/network_context.cc index 5746ea0..1d5ab88 100644 --- a/content/network/network_context.cc +++ b/content/network/network_context.cc
@@ -109,12 +109,8 @@ } std::unique_ptr<NetworkContext> NetworkContext::CreateForTesting() { - mojom::NetworkContextParamsPtr params = mojom::NetworkContextParams::New(); - // Disable proxy configuration detection, to avoid dependencies on local - // network configuration. - params->initial_proxy_config = net::ProxyConfig::CreateDirect(); - - return base::WrapUnique(new NetworkContext(std::move(params))); + return base::WrapUnique( + new NetworkContext(mojom::NetworkContextParams::New())); } void NetworkContext::RegisterURLLoader(URLLoader* url_loader) { @@ -223,20 +219,6 @@ builder.set_accept_language("en-us,en"); builder.set_user_agent(GetContentClient()->GetUserAgent()); - // TODO(mmenke): Move this logic into content shell. - if (!network_context_params->initial_proxy_config && - !network_context_params->proxy_config_client_request.is_pending()) { - if (command_line->HasSwitch(switches::kProxyServer)) { - net::ProxyConfig config; - config.proxy_rules().ParseFromString( - command_line->GetSwitchValueASCII(switches::kProxyServer)); - network_context_params->initial_proxy_config = config; - } else { - network_context_params->initial_proxy_config = - net::ProxyConfig::CreateDirect(); - } - } - std::unique_ptr<net::CertVerifier> cert_verifier = net::CertVerifier::CreateDefault(); builder.SetCertVerifier( @@ -276,13 +258,15 @@ builder->EnableHttpCache(cache_params); } - if (network_context_params->initial_proxy_config || - network_context_params->proxy_config_client_request.is_pending()) { - builder->set_proxy_config_service(base::MakeUnique<ProxyConfigServiceMojo>( - std::move(network_context_params->proxy_config_client_request), - std::move(network_context_params->initial_proxy_config), - std::move(network_context_params->proxy_config_poller_client))); + if (!network_context_params->initial_proxy_config && + !network_context_params->proxy_config_client_request.is_pending()) { + network_context_params->initial_proxy_config = + net::ProxyConfig::CreateDirect(); } + builder->set_proxy_config_service(base::MakeUnique<ProxyConfigServiceMojo>( + std::move(network_context_params->proxy_config_client_request), + std::move(network_context_params->initial_proxy_config), + std::move(network_context_params->proxy_config_poller_client))); if (network_context_params->http_server_properties_path) { scoped_refptr<JsonPrefStore> json_pref_store(new JsonPrefStore(
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 797cc254..55d37fb9 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -232,13 +232,6 @@ return false; } -std::unique_ptr<net::HttpRequestHeaders> -ContentBrowserClient::GetAdditionalNavigationRequestHeaders( - BrowserContext* context, - const GURL& url) const { - return nullptr; -} - bool ContentBrowserClient::AllowGetCookie(const GURL& url, const GURL& first_party, const net::CookieList& cookie_list, @@ -596,4 +589,9 @@ } #endif +bool ContentBrowserClient::AllowRenderingMhtmlOverHttp( + NavigationUIData* navigation_ui_data) const { + return false; +} + } // namespace content
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index e56b3201..8ae1b96 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -416,10 +416,12 @@ virtual bool IsDataSaverEnabled(BrowserContext* context); // Allow the embedder to return additional headers that should be sent when - // fetching |url|. May return a nullptr. - virtual std::unique_ptr<net::HttpRequestHeaders> - GetAdditionalNavigationRequestHeaders(BrowserContext* context, - const GURL& url) const; + // fetching |url| as well as add extra load flags. + virtual void NavigationRequestStarted( + int frame_tree_node_id, + const GURL& url, + std::unique_ptr<net::HttpRequestHeaders>* extra_headers, + int* extra_load_flags) {} // Allow the embedder to control if the given cookie can be read. // This is called on the IO thread. @@ -975,6 +977,11 @@ bool is_main_frame, ui::PageTransition transition); #endif + + // Called on IO or UI thread to determine whether or not to allow load and + // render MHTML page from http/https URLs. + virtual bool AllowRenderingMhtmlOverHttp( + NavigationUIData* navigation_ui_data) const; }; } // namespace content
diff --git a/content/public/browser/resource_dispatcher_host_delegate.cc b/content/public/browser/resource_dispatcher_host_delegate.cc index a96a467..fe0f8d87 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.cc +++ b/content/public/browser/resource_dispatcher_host_delegate.cc
@@ -104,11 +104,6 @@ return std::unique_ptr<net::ClientCertStore>(); } -bool ResourceDispatcherHostDelegate::AllowRenderingMhtmlOverHttp( - net::URLRequest* request) const { - return false; -} - ResourceDispatcherHostDelegate::~ResourceDispatcherHostDelegate() { }
diff --git a/content/public/browser/resource_dispatcher_host_delegate.h b/content/public/browser/resource_dispatcher_host_delegate.h index 7dea653..ea004c5 100644 --- a/content/public/browser/resource_dispatcher_host_delegate.h +++ b/content/public/browser/resource_dispatcher_host_delegate.h
@@ -142,9 +142,6 @@ virtual std::unique_ptr<net::ClientCertStore> CreateClientCertStore( ResourceContext* resource_context); - // Whether or not to allow load and render MHTML page from http/https URLs. - virtual bool AllowRenderingMhtmlOverHttp(net::URLRequest* request) const; - protected: virtual ~ResourceDispatcherHostDelegate(); };
diff --git a/content/public/common/network_service.mojom b/content/public/common/network_service.mojom index 4ee8cae..b5333a9 100644 --- a/content/public/common/network_service.mojom +++ b/content/public/common/network_service.mojom
@@ -69,11 +69,7 @@ // proxy lookups will be deferred until a configuration is received via // |proxy_config_client_request|. // - // If both are null, the NetworkContext will attempt to automatically - // detect the system proxy configuration (Which defaults to no proxy on - // Linux and Android). - // - // TODO(mmenke): Use direct connections by default instead. + // If both are null, the NetworkContext will not use a proxy. ProxyConfig? initial_proxy_config; ProxyConfigClient&? proxy_config_client_request;
diff --git a/content/public/test/download_test_observer.cc b/content/public/test/download_test_observer.cc index 76568bf..da7fc55 100644 --- a/content/public/test/download_test_observer.cc +++ b/content/public/test/download_test_observer.cc
@@ -309,6 +309,28 @@ return download->GetState() == DownloadItem::INTERRUPTED; } +void PingIOThread(int cycle, base::OnceClosure callback); + +// Helper method to post a task to IO thread to ensure remaining operations on +// the IO thread complete. +void PingFileThread(int cycle, base::OnceClosure callback) { + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::BindOnce(&PingIOThread, cycle, std::move(callback))); +} + +// Post a task to file thread, and wait for it to be posted back on to the IO +// thread if |cycle| is larger than 1. This ensures that all remaining +// operations on the IO thread complete. +void PingIOThread(int cycle, base::OnceClosure callback) { + if (--cycle) { + DownloadManager::GetTaskRunner()->PostTask( + FROM_HERE, base::BindOnce(&PingFileThread, cycle, std::move(callback))); + } else { + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, std::move(callback)); + } +} + DownloadTestFlushObserver::DownloadTestFlushObserver( DownloadManager* download_manager) : download_manager_(download_manager), @@ -319,7 +341,7 @@ download_manager_->AddObserver(this); // The wait condition may have been met before WaitForFlush() was called. CheckDownloadsInProgress(true); - RunAllTasksUntilIdle(); + run_loop_.Run(); } void DownloadTestFlushObserver::OnDownloadCreated( @@ -328,6 +350,10 @@ CheckDownloadsInProgress(true); } +void DownloadTestFlushObserver::ManagerGoingDown(DownloadManager* manager) { + download_manager_ = nullptr; +} + void DownloadTestFlushObserver::OnDownloadDestroyed(DownloadItem* download) { // Stop observing. Do not do anything with it, as it is about to be gone. DownloadSet::iterator it = downloads_observed_.find(download); @@ -342,6 +368,9 @@ } DownloadTestFlushObserver::~DownloadTestFlushObserver() { + if (!download_manager_) + return; + download_manager_->RemoveObserver(this); for (DownloadSet::iterator it = downloads_observed_.begin(); it != downloads_observed_.end(); ++it) { @@ -351,7 +380,7 @@ // If we're waiting for that flush point, check the number // of downloads in the IN_PROGRESS state and take appropriate -// action. If requested, also observes all downloads while iterating. +// action. If requested, also observes all downloads while iterating. void DownloadTestFlushObserver::CheckDownloadsInProgress( bool observe_downloads) { if (waiting_for_zero_inprogress_) { @@ -389,29 +418,11 @@ // there's a self-task posting in the IO thread cancel path. DownloadManager::GetTaskRunner()->PostTask( FROM_HERE, - base::BindOnce(&DownloadTestFlushObserver::PingFileThread, this, 2)); + base::BindOnce(&PingFileThread, 2, run_loop_.QuitClosure())); } } } -void DownloadTestFlushObserver::PingFileThread(int cycle) { - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::BindOnce(&DownloadTestFlushObserver::PingIOThread, this, cycle)); -} - -void DownloadTestFlushObserver::PingIOThread(int cycle) { - if (--cycle) { - BrowserThread::PostTask( - BrowserThread::UI, FROM_HERE, - base::BindOnce(&DownloadTestFlushObserver::PingFileThread, this, - cycle)); - } else { - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, - base::MessageLoop::QuitWhenIdleClosure()); - } -} - DownloadTestItemCreationObserver::DownloadTestItemCreationObserver() : download_id_(DownloadItem::kInvalidId), interrupt_reason_(DOWNLOAD_INTERRUPT_REASON_NONE),
diff --git a/content/public/test/download_test_observer.h b/content/public/test/download_test_observer.h index 1e87631..3e4e1c1 100644 --- a/content/public/test/download_test_observer.h +++ b/content/public/test/download_test_observer.h
@@ -13,7 +13,7 @@ #include "base/callback_forward.h" #include "base/macros.h" -#include "base/memory/ref_counted.h" +#include "base/run_loop.h" #include "content/public/browser/download_interrupt_reasons.h" #include "content/public/browser/download_item.h" #include "content/public/browser/download_manager.h" @@ -232,27 +232,22 @@ // IO threads. // This almost certainly means that a Download cancel has propagated through // the system. -class DownloadTestFlushObserver - : public DownloadManager::Observer, - public DownloadItem::Observer, - public base::RefCountedThreadSafe<DownloadTestFlushObserver> { +class DownloadTestFlushObserver : public DownloadManager::Observer, + public DownloadItem::Observer { public: explicit DownloadTestFlushObserver(DownloadManager* download_manager); + ~DownloadTestFlushObserver() override; void WaitForFlush(); // DownloadsManager observer methods. void OnDownloadCreated(DownloadManager* manager, DownloadItem* item) override; + void ManagerGoingDown(DownloadManager* manager) override; // DownloadItem observer methods. void OnDownloadUpdated(DownloadItem* download) override; void OnDownloadDestroyed(DownloadItem* download) override; - protected: - friend class base::RefCountedThreadSafe<DownloadTestFlushObserver>; - - ~DownloadTestFlushObserver() override; - private: typedef std::set<DownloadItem*> DownloadSet; @@ -261,13 +256,10 @@ // action. If requested, also observes all downloads while iterating. void CheckDownloadsInProgress(bool observe_downloads); - void PingFileThread(int cycle); - - void PingIOThread(int cycle); - DownloadManager* download_manager_; DownloadSet downloads_observed_; bool waiting_for_zero_inprogress_; + base::RunLoop run_loop_; DISALLOW_COPY_AND_ASSIGN(DownloadTestFlushObserver); };
diff --git a/content/renderer/service_worker/web_service_worker_registration_impl.cc b/content/renderer/service_worker/web_service_worker_registration_impl.cc index aa5f279..bf5efd7 100644 --- a/content/renderer/service_worker/web_service_worker_registration_impl.cc +++ b/content/renderer/service_worker/web_service_worker_registration_impl.cc
@@ -65,9 +65,10 @@ impl->host_for_global_scope_ = blink::mojom::ThreadSafeServiceWorkerRegistrationObjectHostAssociatedPtr:: Create(std::move(impl->info_->host_ptr_info), io_task_runner); - // |impl|'s destruction happens only in OnConnectionError(), which cannot - // happen before BindRequest(), therefore using base::Unretained() here is - // safe. + // |impl|'s destruction needs both DetachAndMaybeDestroy() and + // OnConnectionError() to be called (see comments at LifecycleState enum), and + // OnConnectionError() cannot happen before BindRequest(), therefore using + // base::Unretained() here is safe. io_task_runner->PostTask( FROM_HERE, base::BindOnce(&WebServiceWorkerRegistrationImpl::BindRequest, base::Unretained(impl.get()), @@ -190,6 +191,11 @@ host_for_client_.reset(); host_for_global_scope_ = nullptr; info_ = nullptr; + if (state_ == LifecycleState::kUnbound) { + state_ = LifecycleState::kDead; + delete this; + return; + } DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); state_ = LifecycleState::kDetached; // We will continue in OnConnectionError() triggered by destruction of the @@ -222,9 +228,15 @@ base::Unretained(this))); return; } - DCHECK_EQ(LifecycleState::kDetached, state_); - state_ = LifecycleState::kDead; - delete this; + if (state_ == LifecycleState::kDetached) { + state_ = LifecycleState::kDead; + delete this; + return; + } + DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); + state_ = LifecycleState::kUnbound; + // We will continue in DetachAndMaybeDestroy() when all references of |this| + // have been released by Blink. } blink::WebServiceWorkerRegistrationProxy* @@ -238,7 +250,8 @@ void WebServiceWorkerRegistrationImpl::Update( std::unique_ptr<WebServiceWorkerUpdateCallbacks> callbacks) { - DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); + DCHECK(state_ == LifecycleState::kAttachedAndBound || + state_ == LifecycleState::kUnbound); GetRegistrationObjectHost()->Update( base::BindOnce(&WebServiceWorkerRegistrationImpl::OnUpdated, base::Unretained(this), std::move(callbacks))); @@ -246,7 +259,8 @@ void WebServiceWorkerRegistrationImpl::Unregister( std::unique_ptr<WebServiceWorkerUnregistrationCallbacks> callbacks) { - DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); + DCHECK(state_ == LifecycleState::kAttachedAndBound || + state_ == LifecycleState::kUnbound); GetRegistrationObjectHost()->Unregister( base::BindOnce(&WebServiceWorkerRegistrationImpl::OnUnregistered, base::Unretained(this), std::move(callbacks))); @@ -255,7 +269,8 @@ void WebServiceWorkerRegistrationImpl::EnableNavigationPreload( bool enable, std::unique_ptr<WebEnableNavigationPreloadCallbacks> callbacks) { - DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); + DCHECK(state_ == LifecycleState::kAttachedAndBound || + state_ == LifecycleState::kUnbound); GetRegistrationObjectHost()->EnableNavigationPreload( enable, base::BindOnce( @@ -265,7 +280,8 @@ void WebServiceWorkerRegistrationImpl::GetNavigationPreloadState( std::unique_ptr<WebGetNavigationPreloadStateCallbacks> callbacks) { - DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); + DCHECK(state_ == LifecycleState::kAttachedAndBound || + state_ == LifecycleState::kUnbound); GetRegistrationObjectHost()->GetNavigationPreloadState(base::BindOnce( &WebServiceWorkerRegistrationImpl::OnDidGetNavigationPreloadState, base::Unretained(this), std::move(callbacks))); @@ -274,7 +290,8 @@ void WebServiceWorkerRegistrationImpl::SetNavigationPreloadHeader( const blink::WebString& value, std::unique_ptr<WebSetNavigationPreloadHeaderCallbacks> callbacks) { - DCHECK_EQ(LifecycleState::kAttachedAndBound, state_); + DCHECK(state_ == LifecycleState::kAttachedAndBound || + state_ == LifecycleState::kUnbound); GetRegistrationObjectHost()->SetNavigationPreloadHeader( value.Utf8(), base::BindOnce(
diff --git a/content/renderer/service_worker/web_service_worker_registration_impl.h b/content/renderer/service_worker/web_service_worker_registration_impl.h index 05b370a3..2388b1d 100644 --- a/content/renderer/service_worker/web_service_worker_registration_impl.h +++ b/content/renderer/service_worker/web_service_worker_registration_impl.h
@@ -65,6 +65,12 @@ // is ready to be destroyed. If there was no ServiceWorkerRegistrationObjectInfo // inflight, the browser process destroys the Mojo connection to this instance, // which finally destroys it. +// +// Another destruction scenario is that the browser process destroys the +// ServiceWorkerRegistrationObject Mojo connection while some +// WebServiceWorkerRegistration::Handles are still held by Blink. In such a case +// this instance will finally be destroyed after all Blink destroys all the +// WebServiceWorkerRegistration::Handles. class CONTENT_EXPORT WebServiceWorkerRegistrationImpl : public blink::mojom::ServiceWorkerRegistrationObject, public blink::WebServiceWorkerRegistration, @@ -150,9 +156,13 @@ // When all references to |this| have been released by Blink, // DetachAndMaybeDestroy() will be triggered to change |state_| from // |kAttachedAndBound| to |kDetached|. - // - |kDetached| --> |kDead| - // OnConnectionError() will set |state_| to |kDead| and delete |this| - // immediately. + // - |kAttachedAndBound| --> |kUnbound| + // When |binding_| Mojo connection gets broken, OnConnectionError() will be + // triggered to change |state_| from |kAttachedAndBound| to |kUnbound|. + // - {|kUnbound|, |kDetached|} --> |kDead| + // But if DetachAndMaybeDestroy() saw that |state_| is already |kUnbound| or + // OnConnectionError() saw that |state_| is already |kDetached|, they will + // just set |state_| to |kDead| and delete |this| immediately. // - |kDetached| --> |kAttachedAndBound| // When |this| is in |kDetached| state, if an inflight // ServiceWorkerRegistrationObjectInfo for the same JavaScript registration @@ -161,6 +171,7 @@ enum class LifecycleState { kInitial, kAttachedAndBound, + kUnbound, kDetached, kDead };
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc index 46a89fa..a7959ff 100644 --- a/gpu/gles2_conform_support/egl/display.cc +++ b/gpu/gles2_conform_support/egl/display.cc
@@ -4,6 +4,7 @@ #include "gpu/gles2_conform_support/egl/display.h" +#include "build/build_config.h" #include "gpu/gles2_conform_support/egl/config.h" #include "gpu/gles2_conform_support/egl/context.h" #include "gpu/gles2_conform_support/egl/surface.h" @@ -214,8 +215,12 @@ return result; } scoped_refptr<gl::GLSurface> gl_surface; - gl_surface = - gl::init::CreateViewGLSurface(static_cast<gfx::AcceleratedWidget>(win)); +#if defined(OS_MACOSX) + gfx::AcceleratedWidget widget = gfx::kNullAcceleratedWidget; +#else + gfx::AcceleratedWidget widget = static_cast<gfx::AcceleratedWidget>(win); +#endif + gl_surface = gl::init::CreateViewGLSurface(widget); if (!gl_surface) return ts->ReturnError(EGL_BAD_ALLOC, EGL_NO_SURFACE); surfaces_.emplace_back(new Surface(gl_surface.get(), config));
diff --git a/gpu/ipc/common/BUILD.gn b/gpu/ipc/common/BUILD.gn index 1562a0b..25b9d4cc 100644 --- a/gpu/ipc/common/BUILD.gn +++ b/gpu/ipc/common/BUILD.gn
@@ -121,7 +121,7 @@ ] } - if (is_mac || is_android) { + if (is_android) { sources += [ "gpu_surface_lookup.cc", "gpu_surface_lookup.h",
diff --git a/gpu/ipc/common/surface_handle.h b/gpu/ipc/common/surface_handle.h index ecebc066..cb6f279 100644 --- a/gpu/ipc/common/surface_handle.h +++ b/gpu/ipc/common/surface_handle.h
@@ -9,7 +9,8 @@ #include "build/build_config.h" -#if (defined(OS_WIN) || defined(USE_X11) || defined(USE_OZONE)) && \ +#if (defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_X11) || \ + defined(USE_OZONE)) && \ !defined(OS_NACL) #include "ui/gfx/native_widget_types.h" #define GPU_SURFACE_HANDLE_IS_ACCELERATED_WINDOW
diff --git a/ios/chrome/browser/passwords/ios_chrome_update_password_infobar_delegate.h b/ios/chrome/browser/passwords/ios_chrome_update_password_infobar_delegate.h index 27c5d8f..ae836f3e 100644 --- a/ios/chrome/browser/passwords/ios_chrome_update_password_infobar_delegate.h +++ b/ios/chrome/browser/passwords/ios_chrome_update_password_infobar_delegate.h
@@ -11,6 +11,7 @@ #include "ios/chrome/browser/passwords/ios_chrome_password_manager_infobar_delegate.h" @protocol ApplicationCommands; +@class UIViewController; namespace password_manager { class PasswordFormManager; @@ -25,12 +26,14 @@ : public IOSChromePasswordManagerInfoBarDelegate { public: // Creates the infobar for |form_to_save| and adds it to |infobar_manager|. - // |is_smart_lock_enabled| controls the branding string. |dispatcher| is not - // retained. + // |is_smart_lock_enabled| controls the branding string. |baseViewController| + // is the base view controller from which to present UI, and is not retained. + // |dispatcher| is not retained. static void Create( bool is_smart_lock_branding_enabled, infobars::InfoBarManager* infobar_manager, std::unique_ptr<password_manager::PasswordFormManager> form_to_save, + UIViewController* baseViewController, id<ApplicationCommands> dispatcher); ~IOSChromeUpdatePasswordInfoBarDelegate() override;
diff --git a/ios/chrome/browser/passwords/ios_chrome_update_password_infobar_delegate.mm b/ios/chrome/browser/passwords/ios_chrome_update_password_infobar_delegate.mm index 86f6ec8..3f15503b 100644 --- a/ios/chrome/browser/passwords/ios_chrome_update_password_infobar_delegate.mm +++ b/ios/chrome/browser/passwords/ios_chrome_update_password_infobar_delegate.mm
@@ -31,6 +31,7 @@ bool is_smart_lock_branding_enabled, infobars::InfoBarManager* infobar_manager, std::unique_ptr<PasswordFormManager> form_manager, + UIViewController* baseViewController, id<ApplicationCommands> dispatcher) { DCHECK(infobar_manager); auto delegate = base::WrapUnique(new IOSChromeUpdatePasswordInfoBarDelegate( @@ -39,6 +40,7 @@ std::unique_ptr<InfoBarIOS> infobar(new InfoBarIOS(std::move(delegate))); UpdatePasswordInfoBarController* controller = [[UpdatePasswordInfoBarController alloc] initWithDelegate:infobar.get()]; + [controller setBaseViewController:baseViewController]; infobar->SetController(controller); infobar_manager->AddInfoBar(std::move(infobar)); }
diff --git a/ios/chrome/browser/passwords/password_controller.h b/ios/chrome/browser/passwords/password_controller.h index 56444733..90a5da3 100644 --- a/ios/chrome/browser/passwords/password_controller.h +++ b/ios/chrome/browser/passwords/password_controller.h
@@ -54,6 +54,9 @@ // The PasswordFormFiller owned by this PasswordController. @property(nonatomic, readonly) id<PasswordFormFiller> passwordFormFiller; +// The base view controller from which to present UI. +@property(nonatomic, readwrite, weak) UIViewController* baseViewController; + // The dispatcher used for the PasswordController. This property can return nil // even after being set to a non-nil object. @property(nonatomic, weak) id<ApplicationCommands> dispatcher;
diff --git a/ios/chrome/browser/passwords/password_controller.mm b/ios/chrome/browser/passwords/password_controller.mm index 146e139..1ac3016 100644 --- a/ios/chrome/browser/passwords/password_controller.mm +++ b/ios/chrome/browser/passwords/password_controller.mm
@@ -296,6 +296,8 @@ @synthesize isWebStateDestroyed = _isWebStateDestroyed; +@synthesize baseViewController = _baseViewController; + @synthesize dispatcher = _dispatcher; @synthesize delegate = _delegate; @@ -1011,7 +1013,7 @@ case PasswordInfoBarType::UPDATE: IOSChromeUpdatePasswordInfoBarDelegate::Create( isSmartLockBrandingEnabled, infoBarManager, std::move(form), - self.dispatcher); + self.baseViewController, self.dispatcher); break; } }
diff --git a/ios/chrome/browser/passwords/password_tab_helper.h b/ios/chrome/browser/passwords/password_tab_helper.h index ca311f6..3891910 100644 --- a/ios/chrome/browser/passwords/password_tab_helper.h +++ b/ios/chrome/browser/passwords/password_tab_helper.h
@@ -15,6 +15,7 @@ @protocol PasswordControllerDelegate; @protocol PasswordFormFiller; @protocol PasswordsUiDelegate; +@class UIViewController; // Class binding a PasswordController to a WebState. class PasswordTabHelper : public web::WebStateObserver, @@ -25,6 +26,9 @@ // Creates a PasswordTabHelper and attaches it to the given |web_state|. static void CreateForWebState(web::WebState* web_state); + // Sets the BaseViewController from which to present UI. + void SetBaseViewController(UIViewController* baseViewController); + // Sets the PasswordController dispatcher. void SetDispatcher(id<ApplicationCommands> dispatcher);
diff --git a/ios/chrome/browser/passwords/password_tab_helper.mm b/ios/chrome/browser/passwords/password_tab_helper.mm index 58946ce..edba437 100644 --- a/ios/chrome/browser/passwords/password_tab_helper.mm +++ b/ios/chrome/browser/passwords/password_tab_helper.mm
@@ -25,6 +25,11 @@ } } +void PasswordTabHelper::SetBaseViewController( + UIViewController* baseViewController) { + controller_.baseViewController = baseViewController; +} + void PasswordTabHelper::SetDispatcher(id<ApplicationCommands> dispatcher) { controller_.dispatcher = dispatcher; }
diff --git a/ios/chrome/browser/passwords/update_password_infobar_controller.h b/ios/chrome/browser/passwords/update_password_infobar_controller.h index 7aac940..b08c988 100644 --- a/ios/chrome/browser/passwords/update_password_infobar_controller.h +++ b/ios/chrome/browser/passwords/update_password_infobar_controller.h
@@ -13,6 +13,9 @@ // the user whether they want to update their password. @interface UpdatePasswordInfoBarController : ConfirmInfoBarController +// The base view controller from which to present UI. +@property(nonatomic, readwrite, weak) UIViewController* baseViewController; + - (InfoBarView*)viewForDelegate: (IOSChromeUpdatePasswordInfoBarDelegate*)delegate frame:(CGRect)frame;
diff --git a/ios/chrome/browser/passwords/update_password_infobar_controller.mm b/ios/chrome/browser/passwords/update_password_infobar_controller.mm index 50a68d8c..e743fc6 100644 --- a/ios/chrome/browser/passwords/update_password_infobar_controller.mm +++ b/ios/chrome/browser/passwords/update_password_infobar_controller.mm
@@ -28,7 +28,7 @@ @end @implementation UpdatePasswordInfoBarController - +@synthesize baseViewController = _baseViewController; @synthesize selectorCoordinator = _selectorCoordinator; - (InfoBarView*)viewForDelegate: @@ -65,10 +65,9 @@ if (tag != kAccountTag) return; - UIViewController* baseViewController = - [[UIApplication sharedApplication] keyWindow].rootViewController; + DCHECK(self.baseViewController); self.selectorCoordinator = [[SelectorCoordinator alloc] - initWithBaseViewController:baseViewController]; + initWithBaseViewController:self.baseViewController]; self.selectorCoordinator.delegate = self; self.selectorCoordinator.options = [NSOrderedSet orderedSetWithArray:_delegate->GetAccounts()];
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm index 6e5acae..391b6876 100644 --- a/ios/chrome/browser/ui/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -652,6 +652,9 @@ @property(nonatomic, strong) BubbleViewControllerPresenter* incognitoTabTipBubblePresenter; +// Vertical offset for fullscreen toolbar. +@property(nonatomic, strong) NSLayoutConstraint* toolbarOffsetConstraint; + // BVC initialization: // If the BVC is initialized with a valid browser state & tab model immediately, // the path is straightforward: functionality is enabled, and the UI is built @@ -917,6 +920,7 @@ @synthesize recentTabsCoordinator = _recentTabsCoordinator; @synthesize tabStripCoordinator = _tabStripCoordinator; @synthesize tabStripView = _tabStripView; +@synthesize toolbarOffsetConstraint = _toolbarOffsetConstraint; #pragma mark - Object lifecycle @@ -1896,11 +1900,13 @@ [_toolbarCoordinator adjustToolbarHeight]; + self.toolbarOffsetConstraint = + [_toolbarCoordinator.toolbarViewController.view.topAnchor + constraintEqualToAnchor:topAnchor]; [NSLayoutConstraint activateConstraints:@[ + self.toolbarOffsetConstraint, [_toolbarCoordinator.toolbarViewController.view.leadingAnchor constraintEqualToAnchor:[self view].leadingAnchor], - [_toolbarCoordinator.toolbarViewController.view.topAnchor - constraintEqualToAnchor:topAnchor], [_toolbarCoordinator.toolbarViewController.view.trailingAnchor constraintEqualToAnchor:[self view].trailingAnchor], ]]; @@ -2449,6 +2455,7 @@ // TODO(crbug.com/777557): do not pass the dispatcher to PasswordTabHelper. if (PasswordTabHelper* passwordTabHelper = PasswordTabHelper::FromWebState(tab.webState)) { + passwordTabHelper->SetBaseViewController(self); passwordTabHelper->SetDispatcher(self.dispatcher); passwordTabHelper->SetPasswordControllerDelegate(self); } @@ -3185,8 +3192,18 @@ atOffset:(CGFloat)headerOffset { CGFloat height = [self headerOffset]; for (HeaderDefinition* header in headers) { + CGFloat yOrigin = height - headerOffset - header.inset; + // Make sure the toolbarView's constraints are also updated. Leaving the + // -setFrame call to minimize changes in this CL -- otherwise the way + // toolbar_view manages it's alpha changes would also need to be updated. + // TODO(crbug.com/778822): This can be cleaned up when the new fullscreen + // is enabled. + if (IsSafeAreaCompatibleToolbarEnabled() && + header.view == _toolbarCoordinator.toolbarViewController.view) { + self.toolbarOffsetConstraint.constant = yOrigin; + } CGRect frame = [header.view frame]; - frame.origin.y = height - headerOffset - header.inset; + frame.origin.y = yOrigin; [header.view setFrame:frame]; if (header.behaviour != Overlap) height += CGRectGetHeight(frame);
diff --git a/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn b/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn index e277c8c..e7f1ee23 100644 --- a/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn +++ b/ios/chrome/browser/ui/ntp/recent_tabs/BUILD.gn
@@ -40,6 +40,7 @@ "//ios/chrome/browser/ui/ntp/recent_tabs/views", "//ios/chrome/browser/ui/settings/sync_utils", "//ios/chrome/browser/ui/signin_interaction/public", + "//ios/chrome/browser/ui/util", "//ios/web", "//ui/base", "//url",
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 bc3a9a7..4b989d1 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
@@ -42,6 +42,7 @@ #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" @@ -629,9 +630,9 @@ params.view.reset(self.tableView); // Present sheet/popover using controller that is added to view hierarchy. - UIViewController* topController = [params.view window].rootViewController; - while (topController.presentedViewController) - topController = topController.presentedViewController; + // TODO(crbug.com/754642): Remove TopPresentedViewController(). + UIViewController* topController = + top_view_controller::TopPresentedViewController(); _contextMenuCoordinator = [[ContextMenuCoordinator alloc] initWithBaseViewController:topController
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_button_factory.h b/ios/chrome/browser/ui/toolbar/clean/toolbar_button_factory.h index 2bdefd0..0b0dab1 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_button_factory.h +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_button_factory.h
@@ -46,6 +46,8 @@ - (ToolbarButton*)bookmarkToolbarButton; // VoiceSearch ToolbarButton. - (ToolbarButton*)voiceSearchButton; +// ContractToolbar ToolbarButton. +- (ToolbarButton*)contractToolbarButton; // Returns images for Voice Search in an array representing the NORMAL/PRESSED // state
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_button_factory.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_button_factory.mm index 7395be31..f62dfdd 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_button_factory.mm +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_button_factory.mm
@@ -49,6 +49,8 @@ return self; } +#pragma mark - Buttons + - (ToolbarButton*)backToolbarButton { int backButtonImages[styleCount][TOOLBAR_STATE_COUNT] = TOOLBAR_IDR_THREE_STATE(BACK); @@ -223,6 +225,21 @@ return voiceSearchButton; } +- (ToolbarButton*)contractToolbarButton { + NSString* collapseName = _style ? @"collapse_incognito" : @"collapse"; + NSString* collapsePressedName = + _style ? @"collapse_pressed_incognito" : @"collapse_pressed"; + ToolbarButton* contractToolbarButton = [ToolbarButton + toolbarButtonWithImageForNormalState:[UIImage imageNamed:collapseName] + imageForHighlightedState:[UIImage + imageNamed:collapsePressedName] + imageForDisabledState:nil]; + contractToolbarButton.accessibilityLabel = l10n_util::GetNSString(IDS_CANCEL); + return contractToolbarButton; +} + +#pragma mark - Helpers + - (NSArray<UIImage*>*)voiceSearchImages { // The voice search images can be overridden by the branded image provider. int imageID;
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h index 63fc247..3f4f4c4 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.h
@@ -20,6 +20,7 @@ extern const CGFloat kVerticalMargin; extern const CGFloat kHorizontalMargin; extern const CGFloat kStackViewSpacing; +extern const CGFloat kTrailingMargin; // Location bar styling. extern const CGFloat kLocationBarBorderWidth;
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm index 77272af..ad2dff32 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_constants.mm
@@ -14,6 +14,7 @@ const CGFloat kVerticalMargin = 7.0f; const CGFloat kHorizontalMargin = 1.0f; const CGFloat kStackViewSpacing = 2.0f; +const CGFloat kTrailingMargin = 10.0f; const CGFloat kLocationBarBorderWidth = 1.0f; const CGFloat kLocationBarBorderColor = 0xD0D0D0;
diff --git a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm index 3ab2948..f9003b38 100644 --- a/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm +++ b/ios/chrome/browser/ui/toolbar/clean/toolbar_view_controller.mm
@@ -42,6 +42,7 @@ @property(nonatomic, strong) ToolbarButton* stopButton; @property(nonatomic, strong) ToolbarButton* voiceSearchButton; @property(nonatomic, strong) ToolbarButton* bookmarkButton; +@property(nonatomic, strong) ToolbarButton* contractButton; @property(nonatomic, assign) BOOL voiceSearchEnabled; @property(nonatomic, strong) MDCProgressView* progressBar; // Background view, used to display the incognito NTP background color on the @@ -49,7 +50,9 @@ @property(nonatomic, strong) UIView* backgroundView; // Whether a page is loading. @property(nonatomic, assign, getter=isLoading) BOOL loading; -// Constraints used for the regular/contracted Toolbar state. +// Constraints used for the regular/contracted Toolbar state that will be +// deactivated and replaced by |_expandedToolbarConstraints| when animating the +// toolbar expansion. @property(nonatomic, strong) NSMutableArray* regularToolbarConstraints; // Constraints used to layout the Toolbar to its expanded state. If these are // active the locationBarContainer will expand to the size of this VC's view. @@ -78,6 +81,7 @@ @synthesize stopButton = _stopButton; @synthesize voiceSearchButton = _voiceSearchButton; @synthesize bookmarkButton = _bookmarkButton; +@synthesize contractButton = _contractButton; @synthesize voiceSearchEnabled = _voiceSearchEnabled; @synthesize progressBar = _progressBar; @synthesize expandedToolbarConstraints = _expandedToolbarConstraints; @@ -118,18 +122,26 @@ } - (void)addToolbarExpansionAnimations:(UIViewPropertyAnimator*)animator { + // iPad should never try to animate. + DCHECK(!IsIPadIdiom()); [NSLayoutConstraint deactivateConstraints:self.regularToolbarConstraints]; [NSLayoutConstraint activateConstraints:self.expandedToolbarConstraints]; [animator addAnimations:^{ [self.view layoutIfNeeded]; + self.contractButton.hidden = NO; + self.contractButton.alpha = 1; }]; } - (void)addToolbarContractionAnimations:(UIViewPropertyAnimator*)animator { + // iPad should never try to animate. + DCHECK(!IsIPadIdiom()); [NSLayoutConstraint deactivateConstraints:self.expandedToolbarConstraints]; [NSLayoutConstraint activateConstraints:self.regularToolbarConstraints]; [animator addAnimations:^{ [self.view layoutIfNeeded]; + self.contractButton.hidden = YES; + self.contractButton.alpha = 0; }]; } @@ -172,26 +184,7 @@ [self.buttonFactory.toolbarConfiguration backgroundColor]; [self setUpToolbarStackView]; - if (self.locationBarView) { - NSLayoutConstraint* locationBarTopAnchorConstraint = - [self.locationBarView.topAnchor - constraintEqualToAnchor:self.locationBarContainer.topAnchor]; - [self.locationBarContainer addSubview:self.locationBarView]; - NSArray* locationBarViewConstraints = @[ - [self.locationBarView.leadingAnchor - constraintEqualToAnchor:self.locationBarContainer.leadingAnchor], - [self.locationBarView.trailingAnchor - constraintEqualToAnchor:self.locationBarContainer.trailingAnchor], - [self.locationBarView.bottomAnchor - constraintEqualToAnchor:self.locationBarContainer.bottomAnchor], - locationBarTopAnchorConstraint, - ]; - // Adds - [self.regularToolbarConstraints addObject:locationBarTopAnchorConstraint]; - [NSLayoutConstraint activateConstraints:locationBarViewConstraints]; - } - [self.locationBarContainer addSubview:self.bookmarkButton]; - [self.locationBarContainer addSubview:self.voiceSearchButton]; + [self setUpToolbarContainerView]; [self.view addSubview:self.stackView]; [self.view addSubview:self.progressBar]; [self setConstraints]; @@ -216,12 +209,51 @@ self.stackView.distribution = UIStackViewDistributionFill; } +// Sets up the LocationContainerView. This contains the locationBarView, and +// other buttons like Voice Search, Bookmarks and Contract Toolbar. +- (void)setUpToolbarContainerView { + if (self.locationBarView) { + [self.locationBarContainer addSubview:self.locationBarView]; + + // Bookmarks and Voice Search buttons will only be part of the Toolbar on + // iPad. On the other hand the contract button is only needed on non iPad + // devices, since iPad doesn't animate, thus it doesn't need to contract. + if (IsIPadIdiom()) { + [self.locationBarContainer addSubview:self.bookmarkButton]; + [self.locationBarContainer addSubview:self.voiceSearchButton]; + } else { + [self.locationBarContainer addSubview:self.contractButton]; + } + + // LocationBarView constraints. + NSLayoutConstraint* locationBarViewTrailingConstraint = + [self.locationBarView.trailingAnchor + constraintEqualToAnchor:self.locationBarContainer.trailingAnchor]; + NSLayoutConstraint* locationBarViewTopConstraint = + [self.locationBarView.topAnchor + constraintEqualToAnchor:self.locationBarContainer.topAnchor]; + [self.regularToolbarConstraints addObjectsFromArray:@[ + locationBarViewTopConstraint, locationBarViewTrailingConstraint + ]]; + NSArray* locationBarViewConstraints = @[ + [self.locationBarView.leadingAnchor + constraintEqualToAnchor:self.locationBarContainer.leadingAnchor], + [self.locationBarView.bottomAnchor + constraintEqualToAnchor:self.locationBarContainer.bottomAnchor], + locationBarViewTrailingConstraint, + locationBarViewTopConstraint, + ]; + [NSLayoutConstraint activateConstraints:locationBarViewConstraints]; + } +} + - (void)setConstraints { self.view.translatesAutoresizingMaskIntoConstraints = NO; [self.view.bottomAnchor constraintEqualToAnchor:self.topSafeAnchor constant:kToolbarHeight] .active = YES; + // ProgressBar constraints. NSArray* progressBarConstraints = @[ [self.progressBar.leadingAnchor constraintEqualToAnchor:self.view.leadingAnchor], @@ -234,7 +266,8 @@ ]; [NSLayoutConstraint activateConstraints:progressBarConstraints]; - NSArray* constraints = @[ + // StackView constraints. + NSArray* stackViewConstraints = @[ [self.stackView.heightAnchor constraintEqualToConstant:kToolbarHeight - 2 * kVerticalMargin], [self.stackView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor @@ -245,17 +278,38 @@ [self.stackView.trailingAnchor constraintEqualToAnchor:self.view.trailingAnchor constant:-kHorizontalMargin], - [self.bookmarkButton.centerYAnchor - constraintEqualToAnchor:self.locationBarContainer.centerYAnchor], - [self.voiceSearchButton.centerYAnchor - constraintEqualToAnchor:self.locationBarContainer.centerYAnchor], - [self.voiceSearchButton.trailingAnchor - constraintEqualToAnchor:self.locationBarContainer.trailingAnchor], - [self.bookmarkButton.trailingAnchor - constraintEqualToAnchor:self.voiceSearchButton.leadingAnchor], ]; - [self.regularToolbarConstraints addObjectsFromArray:constraints]; - [NSLayoutConstraint activateConstraints:constraints]; + [self.regularToolbarConstraints addObjectsFromArray:stackViewConstraints]; + [NSLayoutConstraint activateConstraints:stackViewConstraints]; + + // LocationBarContainer Buttons constraints. + NSArray* locationBarButtonConstraints; + if (IsIPadIdiom()) { + locationBarButtonConstraints = @[ + [self.bookmarkButton.centerYAnchor + constraintEqualToAnchor:self.locationBarContainer.centerYAnchor], + [self.voiceSearchButton.centerYAnchor + constraintEqualToAnchor:self.locationBarContainer.centerYAnchor], + [self.voiceSearchButton.trailingAnchor + constraintEqualToAnchor:self.locationBarContainer.trailingAnchor], + [self.bookmarkButton.trailingAnchor + constraintEqualToAnchor:self.voiceSearchButton.leadingAnchor], + ]; + } else { + NSLayoutConstraint* contractButtonTrailingConstraint = + [self.contractButton.trailingAnchor + constraintEqualToAnchor:self.locationBarContainer.trailingAnchor + constant:-2 * kTrailingMargin]; + [self.regularToolbarConstraints addObject:contractButtonTrailingConstraint]; + locationBarButtonConstraints = @[ + [self.contractButton.topAnchor constraintEqualToAnchor:self.topSafeAnchor + constant:kVerticalMargin], + [self.contractButton.bottomAnchor + constraintEqualToAnchor:self.locationBarContainer.bottomAnchor], + contractButtonTrailingConstraint, + ]; + } + [NSLayoutConstraint activateConstraints:locationBarButtonConstraints]; } #pragma mark - Components Setup @@ -370,6 +424,16 @@ action:@selector(bookmarkPage) forControlEvents:UIControlEventTouchUpInside]; + // Contract button. + self.contractButton = [self.buttonFactory contractToolbarButton]; + self.contractButton.visibilityMask = ToolbarComponentVisibilityCompactWidth | + ToolbarComponentVisibilityRegularWidth; + self.contractButton.alpha = 0; + self.contractButton.hidden = YES; + [buttonConstraints + addObject:[self.contractButton.widthAnchor + constraintEqualToConstant:kToolbarButtonWidth]]; + // Add buttons to button updater. self.buttonUpdater.backButton = self.backButton; self.buttonUpdater.forwardButton = self.forwardButton; @@ -612,6 +676,12 @@ constraintEqualToAnchor:self.view.trailingAnchor], [self.locationBarView.topAnchor constraintEqualToAnchor:self.topSafeAnchor constant:kVerticalMargin], + [self.locationBarView.trailingAnchor + constraintEqualToAnchor:self.contractButton.leadingAnchor + constant:-kTrailingMargin], + [self.contractButton.trailingAnchor + constraintEqualToAnchor:self.locationBarContainer.trailingAnchor + constant:-kTrailingMargin], ]; } return _expandedToolbarConstraints;
diff --git a/ios/third_party/motion_animator_objc/BUILD.gn b/ios/third_party/motion_animator_objc/BUILD.gn new file mode 100644 index 0000000..d4013998 --- /dev/null +++ b/ios/third_party/motion_animator_objc/BUILD.gn
@@ -0,0 +1,61 @@ +# Copyright 2017 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import("//build/config/ios/ios_sdk.gni") +import("//build/config/ios/rules.gni") +import("//ios/build/chrome_build.gni") + +config("config") { + include_dirs = [ "src/src" ] + visibility = [ ":motion_animator_objc" ] + defines = [ "IS_BAZEL_BUILD" ] +} + +source_set("motion_animator_objc") { + sources = [ + "src/src/CATransaction+MotionAnimator.h", + "src/src/CATransaction+MotionAnimator.m", + "src/src/MDMAnimatableKeyPaths.h", + "src/src/MDMAnimatableKeyPaths.m", + "src/src/MDMCoreAnimationTraceable.h", + "src/src/MDMMotionAnimator.h", + "src/src/MDMMotionAnimator.m", + "src/src/MotionAnimator.h", + "src/src/private/CABasicAnimation+MotionAnimator.h", + "src/src/private/CABasicAnimation+MotionAnimator.m", + "src/src/private/CAMediaTimingFunction+MotionAnimator.h", + "src/src/private/CAMediaTimingFunction+MotionAnimator.m", + "src/src/private/MDMBlockAnimations.h", + "src/src/private/MDMBlockAnimations.m", + "src/src/private/MDMDragCoefficient.h", + "src/src/private/MDMDragCoefficient.m", + "src/src/private/MDMUIKitValueCoercion.h", + "src/src/private/MDMUIKitValueCoercion.m", + ] + public = [ + "src/src/CATransaction+MotionAnimator.h", + "src/src/MDMAnimatableKeyPaths.h", + "src/src/MDMCoreAnimationTraceable.h", + "src/src/MDMMotionAnimator.h", + "src/src/MotionAnimator.h", + ] + + libs = [ + "CoreGraphics.framework", + "Foundation.framework", + "QuartzCore.framework", + "UIKit.framework", + ] + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ + ":config", + "//build/config/compiler:enable_arc", + "//build/config/compiler:no_chromium_code", + ] + public_configs = [ ":config" ] + + public_deps = [ + "//ios/third_party/motion_interchange_objc", + ] +}
diff --git a/ios/third_party/motion_animator_objc/LICENSE b/ios/third_party/motion_animator_objc/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/ios/third_party/motion_animator_objc/LICENSE
@@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
diff --git a/ios/third_party/motion_animator_objc/OWNERS b/ios/third_party/motion_animator_objc/OWNERS new file mode 100644 index 0000000..e9a3f8b3 --- /dev/null +++ b/ios/third_party/motion_animator_objc/OWNERS
@@ -0,0 +1,9 @@ +sdefresne@chromium.org +rohitrao@chromium.org + +# These are for the common case of adding or renaming files. If you're doing +# structural changes, please get a review from an OWNER. +per-file BUILD.gn=* + +# TEAM: ios-directory-owners@chromium.org +# OS: iOS
diff --git a/ios/third_party/motion_animator_objc/README.chromium b/ios/third_party/motion_animator_objc/README.chromium new file mode 100644 index 0000000..20d2547 --- /dev/null +++ b/ios/third_party/motion_animator_objc/README.chromium
@@ -0,0 +1,14 @@ +Name: Motion Animator for Objective-C +URL: https://github.com/material-motion/motion-animator-objc +Version: 0 +Revision: 213bfb3a75018c49a223bf1269f6a48fbbfc3a12 +License: Apache 2.0 +License File: LICENSE +Security Critical: yes + +Description: +This library provides APIs that turn Motion Interchange motion specifications +into animations. + +Local Modifications: +None
diff --git a/mojo/public/cpp/bindings/interface_ptr_set.h b/mojo/public/cpp/bindings/interface_ptr_set.h index c7e7c16..02bfc4beb 100644 --- a/mojo/public/cpp/bindings/interface_ptr_set.h +++ b/mojo/public/cpp/bindings/interface_ptr_set.h
@@ -51,11 +51,14 @@ bool empty() const { return ptrs_.empty(); } + // Calls FlushForTesting on all Ptrs sequentially. Since each call is a + // blocking operation, may be very slow as the number of pointers increases. void FlushForTesting() { for (const auto& it : ptrs_) { if (it) it->FlushForTesting(); } + ClearNullPtrs(); } private:
diff --git a/net/http2/decoder/decode_buffer_test.cc b/net/http2/decoder/decode_buffer_test.cc index b982d4c9..2f1abdd 100644 --- a/net/http2/decoder/decode_buffer_test.cc +++ b/net/http2/decoder/decode_buffer_test.cc
@@ -43,7 +43,7 @@ class DecodeBufferTest : public ::testing::Test { public: - DecodeBufferTest() {} + DecodeBufferTest() = default; protected: Http2Random random_;
diff --git a/net/http2/decoder/http2_frame_decoder_listener_test_util.cc b/net/http2/decoder/http2_frame_decoder_listener_test_util.cc index 9159b6cd..74c59ee 100644 --- a/net/http2/decoder/http2_frame_decoder_listener_test_util.cc +++ b/net/http2/decoder/http2_frame_decoder_listener_test_util.cc
@@ -9,8 +9,8 @@ namespace net { -FailingHttp2FrameDecoderListener::FailingHttp2FrameDecoderListener() {} -FailingHttp2FrameDecoderListener::~FailingHttp2FrameDecoderListener() {} +FailingHttp2FrameDecoderListener::FailingHttp2FrameDecoderListener() = default; +FailingHttp2FrameDecoderListener::~FailingHttp2FrameDecoderListener() = default; bool FailingHttp2FrameDecoderListener::OnFrameHeader( const Http2FrameHeader& header) { @@ -196,7 +196,7 @@ LoggingHttp2FrameDecoderListener::LoggingHttp2FrameDecoderListener( Http2FrameDecoderListener* wrapped) : wrapped_(wrapped) {} -LoggingHttp2FrameDecoderListener::~LoggingHttp2FrameDecoderListener() {} +LoggingHttp2FrameDecoderListener::~LoggingHttp2FrameDecoderListener() = default; bool LoggingHttp2FrameDecoderListener::OnFrameHeader( const Http2FrameHeader& header) {
diff --git a/net/http2/hpack/decoder/hpack_block_collector.cc b/net/http2/hpack/decoder/hpack_block_collector.cc index 4e433e0e..2bb90b72 100644 --- a/net/http2/hpack/decoder/hpack_block_collector.cc +++ b/net/http2/hpack/decoder/hpack_block_collector.cc
@@ -17,10 +17,10 @@ namespace net { namespace test { -HpackBlockCollector::HpackBlockCollector() {} +HpackBlockCollector::HpackBlockCollector() = default; HpackBlockCollector::HpackBlockCollector(const HpackBlockCollector& other) : pending_entry_(other.pending_entry_), entries_(other.entries_) {} -HpackBlockCollector::~HpackBlockCollector() {} +HpackBlockCollector::~HpackBlockCollector() = default; void HpackBlockCollector::OnIndexedHeader(size_t index) { pending_entry_.OnIndexedHeader(index);
diff --git a/net/http2/hpack/decoder/hpack_decoder.cc b/net/http2/hpack/decoder/hpack_decoder.cc index 91a0f03..c3ce241 100644 --- a/net/http2/hpack/decoder/hpack_decoder.cc +++ b/net/http2/hpack/decoder/hpack_decoder.cc
@@ -17,7 +17,7 @@ block_decoder_(&entry_buffer_), error_detected_(false) {} -HpackDecoder::~HpackDecoder() {} +HpackDecoder::~HpackDecoder() = default; void HpackDecoder::set_tables_debug_listener( HpackDecoderTablesDebugListener* debug_listener) {
diff --git a/net/http2/hpack/decoder/hpack_decoder_listener.cc b/net/http2/hpack/decoder/hpack_decoder_listener.cc index 8f0e0a0..f85b903 100644 --- a/net/http2/hpack/decoder/hpack_decoder_listener.cc +++ b/net/http2/hpack/decoder/hpack_decoder_listener.cc
@@ -6,11 +6,11 @@ namespace net { -HpackDecoderListener::HpackDecoderListener() {} -HpackDecoderListener::~HpackDecoderListener() {} +HpackDecoderListener::HpackDecoderListener() = default; +HpackDecoderListener::~HpackDecoderListener() = default; -HpackDecoderNoOpListener::HpackDecoderNoOpListener() {} -HpackDecoderNoOpListener::~HpackDecoderNoOpListener() {} +HpackDecoderNoOpListener::HpackDecoderNoOpListener() = default; +HpackDecoderNoOpListener::~HpackDecoderNoOpListener() = default; void HpackDecoderNoOpListener::OnHeaderListStart() {} void HpackDecoderNoOpListener::OnHeader(HpackEntryType entry_type,
diff --git a/net/http2/hpack/decoder/hpack_decoder_state.cc b/net/http2/hpack/decoder/hpack_decoder_state.cc index 0e39994..60e7207 100644 --- a/net/http2/hpack/decoder/hpack_decoder_state.cc +++ b/net/http2/hpack/decoder/hpack_decoder_state.cc
@@ -33,7 +33,7 @@ error_detected_(false) { CHECK(listener); } -HpackDecoderState::~HpackDecoderState() {} +HpackDecoderState::~HpackDecoderState() = default; void HpackDecoderState::set_tables_debug_listener( HpackDecoderTablesDebugListener* debug_listener) {
diff --git a/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc b/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc index 3e4451c..9874320 100644 --- a/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc +++ b/net/http2/hpack/decoder/hpack_decoder_string_buffer.cc
@@ -53,7 +53,7 @@ is_huffman_encoded_(false), state_(State::RESET), backing_(Backing::RESET) {} -HpackDecoderStringBuffer::~HpackDecoderStringBuffer() {} +HpackDecoderStringBuffer::~HpackDecoderStringBuffer() = default; void HpackDecoderStringBuffer::Reset() { DVLOG(3) << "HpackDecoderStringBuffer::Reset";
diff --git a/net/http2/hpack/decoder/hpack_decoder_tables.cc b/net/http2/hpack/decoder/hpack_decoder_tables.cc index 61e7970..c185dfc 100644 --- a/net/http2/hpack/decoder/hpack_decoder_tables.cc +++ b/net/http2/hpack/decoder/hpack_decoder_tables.cc
@@ -33,8 +33,8 @@ } // namespace -HpackDecoderTablesDebugListener::HpackDecoderTablesDebugListener() {} -HpackDecoderTablesDebugListener::~HpackDecoderTablesDebugListener() {} +HpackDecoderTablesDebugListener::HpackDecoderTablesDebugListener() = default; +HpackDecoderTablesDebugListener::~HpackDecoderTablesDebugListener() = default; HpackDecoderStaticTable::HpackDecoderStaticTable( const std::vector<HpackStringPair>* table) @@ -56,7 +56,7 @@ HpackDecoderDynamicTable::HpackDecoderDynamicTable() : insert_count_(kFirstDynamicTableIndex - 1), debug_listener_(nullptr) {} -HpackDecoderDynamicTable::~HpackDecoderDynamicTable() {} +HpackDecoderDynamicTable::~HpackDecoderDynamicTable() = default; void HpackDecoderDynamicTable::DynamicTableSizeUpdate(size_t size_limit) { DVLOG(3) << "HpackDecoderDynamicTable::DynamicTableSizeUpdate " << size_limit; @@ -133,8 +133,8 @@ } } -HpackDecoderTables::HpackDecoderTables() {} -HpackDecoderTables::~HpackDecoderTables() {} +HpackDecoderTables::HpackDecoderTables() = default; +HpackDecoderTables::~HpackDecoderTables() = default; void HpackDecoderTables::set_debug_listener( HpackDecoderTablesDebugListener* debug_listener) {
diff --git a/net/http2/hpack/decoder/hpack_decoder_tables_test.cc b/net/http2/hpack/decoder/hpack_decoder_tables_test.cc index e9e6c54..77c2413 100644 --- a/net/http2/hpack/decoder/hpack_decoder_tables_test.cc +++ b/net/http2/hpack/decoder/hpack_decoder_tables_test.cc
@@ -56,7 +56,7 @@ class HpackDecoderStaticTableTest : public ::testing::Test { protected: - HpackDecoderStaticTableTest() {} + HpackDecoderStaticTableTest() = default; std::vector<StaticEntry> shuffled_static_entries() { std::vector<StaticEntry> entries = MakeSpecStaticEntries();
diff --git a/net/http2/hpack/decoder/hpack_decoder_test.cc b/net/http2/hpack/decoder/hpack_decoder_test.cc index 61e05ab..7a89e821 100644 --- a/net/http2/hpack/decoder/hpack_decoder_test.cc +++ b/net/http2/hpack/decoder/hpack_decoder_test.cc
@@ -83,7 +83,7 @@ HpackDecoderTest() : decoder_(this, 4096) { fragment_the_hpack_block_ = GetParam(); } - ~HpackDecoderTest() override {} + ~HpackDecoderTest() override = default; void OnHeaderListStart() override { ASSERT_FALSE(saw_start_);
diff --git a/net/http2/hpack/decoder/hpack_entry_collector.cc b/net/http2/hpack/decoder/hpack_entry_collector.cc index d4d39d4c..0ea55dc 100644 --- a/net/http2/hpack/decoder/hpack_entry_collector.cc +++ b/net/http2/hpack/decoder/hpack_entry_collector.cc
@@ -60,7 +60,7 @@ started_(true), ended_(true) {} -HpackEntryCollector::~HpackEntryCollector() {} +HpackEntryCollector::~HpackEntryCollector() = default; void HpackEntryCollector::OnIndexedHeader(size_t index) { ASSERT_FALSE(started_);
diff --git a/net/http2/hpack/decoder/hpack_whole_entry_buffer.cc b/net/http2/hpack/decoder/hpack_whole_entry_buffer.cc index 7131551..4799a6c8 100644 --- a/net/http2/hpack/decoder/hpack_whole_entry_buffer.cc +++ b/net/http2/hpack/decoder/hpack_whole_entry_buffer.cc
@@ -15,7 +15,7 @@ : max_string_size_bytes_(max_string_size_bytes) { set_listener(listener); } -HpackWholeEntryBuffer::~HpackWholeEntryBuffer() {} +HpackWholeEntryBuffer::~HpackWholeEntryBuffer() = default; void HpackWholeEntryBuffer::set_listener(HpackWholeEntryListener* listener) { CHECK(listener);
diff --git a/net/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc b/net/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc index b7260e29..6626bc8 100644 --- a/net/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc +++ b/net/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc
@@ -37,7 +37,7 @@ class MockHpackWholeEntryListener : public HpackWholeEntryListener { public: - ~MockHpackWholeEntryListener() override {} + ~MockHpackWholeEntryListener() override = default; MOCK_METHOD1(OnIndexedHeader, void(size_t index)); MOCK_METHOD3(OnNameIndexAndLiteralValue, @@ -55,7 +55,7 @@ class HpackWholeEntryBufferTest : public ::testing::Test { protected: HpackWholeEntryBufferTest() : entry_buffer_(&listener_, kMaxStringSize) {} - ~HpackWholeEntryBufferTest() override {} + ~HpackWholeEntryBufferTest() override = default; StrictMock<MockHpackWholeEntryListener> listener_; HpackWholeEntryBuffer entry_buffer_;
diff --git a/net/http2/hpack/decoder/hpack_whole_entry_listener.cc b/net/http2/hpack/decoder/hpack_whole_entry_listener.cc index ed18ff1..419c3356 100644 --- a/net/http2/hpack/decoder/hpack_whole_entry_listener.cc +++ b/net/http2/hpack/decoder/hpack_whole_entry_listener.cc
@@ -6,9 +6,9 @@ namespace net { -HpackWholeEntryListener::~HpackWholeEntryListener() {} +HpackWholeEntryListener::~HpackWholeEntryListener() = default; -HpackWholeEntryNoOpListener::~HpackWholeEntryNoOpListener() {} +HpackWholeEntryNoOpListener::~HpackWholeEntryNoOpListener() = default; void HpackWholeEntryNoOpListener::OnIndexedHeader(size_t index) {} void HpackWholeEntryNoOpListener::OnNameIndexAndLiteralValue(
diff --git a/net/http2/hpack/hpack_string.cc b/net/http2/hpack/hpack_string.cc index 4db9f48a..570a6cdb 100644 --- a/net/http2/hpack/hpack_string.cc +++ b/net/http2/hpack/hpack_string.cc
@@ -14,8 +14,8 @@ HpackString::HpackString(const char* data) : str_(data) {} HpackString::HpackString(Http2StringPiece str) : str_(str.as_string()) {} HpackString::HpackString(Http2String str) : str_(std::move(str)) {} -HpackString::HpackString(const HpackString& other) : str_(other.str_) {} -HpackString::~HpackString() {} +HpackString::HpackString(const HpackString& other) = default; +HpackString::~HpackString() = default; Http2StringPiece HpackString::ToStringPiece() const { return str_;
diff --git a/net/http2/hpack/huffman/hpack_huffman_decoder.cc b/net/http2/hpack/huffman/hpack_huffman_decoder.cc index 3621ca1..68246fd 100644 --- a/net/http2/hpack/huffman/hpack_huffman_decoder.cc +++ b/net/http2/hpack/huffman/hpack_huffman_decoder.cc
@@ -410,9 +410,9 @@ return ss.str(); } -HpackHuffmanDecoder::HpackHuffmanDecoder() {} +HpackHuffmanDecoder::HpackHuffmanDecoder() = default; -HpackHuffmanDecoder::~HpackHuffmanDecoder() {} +HpackHuffmanDecoder::~HpackHuffmanDecoder() = default; bool HpackHuffmanDecoder::Decode(Http2StringPiece input, Http2String* output) { return DecodeShortCodesFirst(input, output);
diff --git a/net/http2/test_tools/frame_parts.cc b/net/http2/test_tools/frame_parts.cc index db0ee356..6d08f677 100644 --- a/net/http2/test_tools/frame_parts.cc +++ b/net/http2/test_tools/frame_parts.cc
@@ -66,7 +66,7 @@ FrameParts::FrameParts(const FrameParts& header) = default; -FrameParts::~FrameParts() {} +FrameParts::~FrameParts() = default; AssertionResult FrameParts::VerifyEquals(const FrameParts& that) const { #define COMMON_MESSAGE "\n this: " << *this << "\n that: " << that
diff --git a/net/http2/test_tools/frame_parts_collector.cc b/net/http2/test_tools/frame_parts_collector.cc index 18978d7..7128edf0 100644 --- a/net/http2/test_tools/frame_parts_collector.cc +++ b/net/http2/test_tools/frame_parts_collector.cc
@@ -13,8 +13,8 @@ namespace net { namespace test { -FramePartsCollector::FramePartsCollector() {} -FramePartsCollector::~FramePartsCollector() {} +FramePartsCollector::FramePartsCollector() = default; +FramePartsCollector::~FramePartsCollector() = default; void FramePartsCollector::Reset() { current_frame_.reset();
diff --git a/net/http2/tools/random_decoder_test.cc b/net/http2/tools/random_decoder_test.cc index 47769fc3..be5aaa1b 100644 --- a/net/http2/tools/random_decoder_test.cc +++ b/net/http2/tools/random_decoder_test.cc
@@ -28,7 +28,7 @@ namespace net { namespace test { -RandomDecoderTest::RandomDecoderTest() {} +RandomDecoderTest::RandomDecoderTest() = default; bool RandomDecoderTest::StopDecodeOnDone() { return stop_decode_on_done_;
diff --git a/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc b/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc index c6f5d42..a92c304 100644 --- a/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc +++ b/net/spdy/chromium/bidirectional_stream_spdy_impl_unittest.cc
@@ -79,7 +79,7 @@ not_expect_callback_(false), on_failed_called_(false) {} - ~TestDelegateBase() override {} + ~TestDelegateBase() override = default; void OnStreamReady(bool request_headers_sent) override { CHECK(!on_failed_called_);
diff --git a/net/spdy/chromium/buffered_spdy_framer.cc b/net/spdy/chromium/buffered_spdy_framer.cc index 8da2d10..3448a38e 100644 --- a/net/spdy/chromium/buffered_spdy_framer.cc +++ b/net/spdy/chromium/buffered_spdy_framer.cc
@@ -32,8 +32,7 @@ max_header_list_size_); } -BufferedSpdyFramer::~BufferedSpdyFramer() { -} +BufferedSpdyFramer::~BufferedSpdyFramer() = default; void BufferedSpdyFramer::set_visitor( BufferedSpdyFramerVisitorInterface* visitor) {
diff --git a/net/spdy/chromium/http2_priority_dependencies.cc b/net/spdy/chromium/http2_priority_dependencies.cc index 991924e..97c4b39 100644 --- a/net/spdy/chromium/http2_priority_dependencies.cc +++ b/net/spdy/chromium/http2_priority_dependencies.cc
@@ -7,9 +7,9 @@ namespace net { -Http2PriorityDependencies::Http2PriorityDependencies() {} +Http2PriorityDependencies::Http2PriorityDependencies() = default; -Http2PriorityDependencies::~Http2PriorityDependencies() {} +Http2PriorityDependencies::~Http2PriorityDependencies() = default; void Http2PriorityDependencies::OnStreamCreation( SpdyStreamId id,
diff --git a/net/spdy/chromium/http2_push_promise_index.cc b/net/spdy/chromium/http2_push_promise_index.cc index 876b1ca9..4f5f7d1 100644 --- a/net/spdy/chromium/http2_push_promise_index.cc +++ b/net/spdy/chromium/http2_push_promise_index.cc
@@ -10,7 +10,7 @@ namespace net { -Http2PushPromiseIndex::Http2PushPromiseIndex() {} +Http2PushPromiseIndex::Http2PushPromiseIndex() = default; Http2PushPromiseIndex::~Http2PushPromiseIndex() { DCHECK(unclaimed_pushed_streams_.empty());
diff --git a/net/spdy/chromium/multiplexed_http_stream.cc b/net/spdy/chromium/multiplexed_http_stream.cc index 3148fed..0a68594 100644 --- a/net/spdy/chromium/multiplexed_http_stream.cc +++ b/net/spdy/chromium/multiplexed_http_stream.cc
@@ -14,7 +14,7 @@ std::unique_ptr<MultiplexedSessionHandle> session) : session_(std::move(session)) {} -MultiplexedHttpStream::~MultiplexedHttpStream() {} +MultiplexedHttpStream::~MultiplexedHttpStream() = default; bool MultiplexedHttpStream::GetRemoteEndpoint(IPEndPoint* endpoint) { return session_->GetRemoteEndpoint(endpoint);
diff --git a/net/spdy/chromium/multiplexed_session.cc b/net/spdy/chromium/multiplexed_session.cc index e49e69b..8b380265 100644 --- a/net/spdy/chromium/multiplexed_session.cc +++ b/net/spdy/chromium/multiplexed_session.cc
@@ -12,7 +12,7 @@ SaveSSLInfo(); } -MultiplexedSessionHandle::~MultiplexedSessionHandle() {} +MultiplexedSessionHandle::~MultiplexedSessionHandle() = default; bool MultiplexedSessionHandle::GetRemoteEndpoint(IPEndPoint* endpoint) { if (!session_)
diff --git a/net/spdy/chromium/spdy_buffer_producer.cc b/net/spdy/chromium/spdy_buffer_producer.cc index 08847ec..294d826c 100644 --- a/net/spdy/chromium/spdy_buffer_producer.cc +++ b/net/spdy/chromium/spdy_buffer_producer.cc
@@ -13,14 +13,14 @@ namespace net { -SpdyBufferProducer::SpdyBufferProducer() {} +SpdyBufferProducer::SpdyBufferProducer() = default; -SpdyBufferProducer::~SpdyBufferProducer() {} +SpdyBufferProducer::~SpdyBufferProducer() = default; SimpleBufferProducer::SimpleBufferProducer(std::unique_ptr<SpdyBuffer> buffer) : buffer_(std::move(buffer)) {} -SimpleBufferProducer::~SimpleBufferProducer() {} +SimpleBufferProducer::~SimpleBufferProducer() = default; std::unique_ptr<SpdyBuffer> SimpleBufferProducer::ProduceBuffer() { DCHECK(buffer_);
diff --git a/net/spdy/chromium/spdy_http_stream_unittest.cc b/net/spdy/chromium/spdy_http_stream_unittest.cc index 1db24232..d6d2778 100644 --- a/net/spdy/chromium/spdy_http_stream_unittest.cc +++ b/net/spdy/chromium/spdy_http_stream_unittest.cc
@@ -130,7 +130,7 @@ session_deps_.net_log = &net_log_; } - ~SpdyHttpStreamTest() override {} + ~SpdyHttpStreamTest() override = default; protected: void TearDown() override {
diff --git a/net/spdy/chromium/spdy_network_transaction_unittest.cc b/net/spdy/chromium/spdy_network_transaction_unittest.cc index 6d4e16f..108151f 100644 --- a/net/spdy/chromium/spdy_network_transaction_unittest.cc +++ b/net/spdy/chromium/spdy_network_transaction_unittest.cc
@@ -1237,7 +1237,7 @@ base::Unretained(this))) { } - ~KillerCallback() override {} + ~KillerCallback() override = default; const CompletionCallback& callback() const { return callback_; }
diff --git a/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc b/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc index df25f48c..63c8d10 100644 --- a/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc +++ b/net/spdy/chromium/spdy_proxy_client_socket_unittest.cc
@@ -1299,7 +1299,7 @@ callback_(base::Bind(&DeleteSockCallback::OnComplete, base::Unretained(this))) {} - ~DeleteSockCallback() override {} + ~DeleteSockCallback() override = default; const CompletionCallback& callback() const { return callback_; }
diff --git a/net/spdy/chromium/spdy_session.cc b/net/spdy/chromium/spdy_session.cc index 420ec31..4b248c89 100644 --- a/net/spdy/chromium/spdy_session.cc +++ b/net/spdy/chromium/spdy_session.cc
@@ -1379,8 +1379,8 @@ SpdySession::UnclaimedPushedStreamContainer::UnclaimedPushedStreamContainer( SpdySession* spdy_session) : spdy_session_(spdy_session) {} -SpdySession::UnclaimedPushedStreamContainer::~UnclaimedPushedStreamContainer() { -} +SpdySession::UnclaimedPushedStreamContainer::~UnclaimedPushedStreamContainer() = + default; bool SpdySession::UnclaimedPushedStreamContainer::erase(const GURL& url) { const_iterator it = find(url);
diff --git a/net/spdy/chromium/spdy_session_key.cc b/net/spdy/chromium/spdy_session_key.cc index 42e260c..41e7afb 100644 --- a/net/spdy/chromium/spdy_session_key.cc +++ b/net/spdy/chromium/spdy_session_key.cc
@@ -36,7 +36,7 @@ SpdySessionKey::SpdySessionKey(const SpdySessionKey& other) = default; -SpdySessionKey::~SpdySessionKey() {} +SpdySessionKey::~SpdySessionKey() = default; bool SpdySessionKey::operator<(const SpdySessionKey& other) const { return std::tie(privacy_mode_, host_port_proxy_pair_.first,
diff --git a/net/spdy/chromium/spdy_session_pool_unittest.cc b/net/spdy/chromium/spdy_session_pool_unittest.cc index 0d9cc49f..83614a4 100644 --- a/net/spdy/chromium/spdy_session_pool_unittest.cc +++ b/net/spdy/chromium/spdy_session_pool_unittest.cc
@@ -80,7 +80,7 @@ : spdy_session_pool_(spdy_session_pool), key_(key) {} - ~SessionOpeningDelegate() override {} + ~SessionOpeningDelegate() override = default; void OnHeadersSent() override {}
diff --git a/net/spdy/chromium/spdy_session_unittest.cc b/net/spdy/chromium/spdy_session_unittest.cc index c4fb3dc9..f45ebc6 100644 --- a/net/spdy/chromium/spdy_session_unittest.cc +++ b/net/spdy/chromium/spdy_session_unittest.cc
@@ -238,9 +238,9 @@ // given SpdyStreamRequest. class StreamRequestDestroyingCallback : public TestCompletionCallbackBase { public: - StreamRequestDestroyingCallback() {} + StreamRequestDestroyingCallback() = default; - ~StreamRequestDestroyingCallback() override {} + ~StreamRequestDestroyingCallback() override = default; void SetRequestToDestroy(std::unique_ptr<SpdyStreamRequest> request) { request_ = std::move(request); @@ -2481,7 +2481,7 @@ : StreamDelegateDoNothing(stream), session_to_close_(session_to_close) {} - ~SessionClosingDelegate() override {} + ~SessionClosingDelegate() override = default; void OnClose(int status) override { session_to_close_->CloseSessionOnError(ERR_SPDY_PROTOCOL_ERROR, "Error"); @@ -3545,7 +3545,7 @@ : StreamDelegateDoNothing(stream), session_(session) {} - ~StreamCreatingDelegate() override {} + ~StreamCreatingDelegate() override = default; void OnClose(int status) override { GURL url(kDefaultUrl); @@ -4046,7 +4046,7 @@ SpdyStringPiece data) : StreamDelegateSendImmediate(stream, data) {} - ~DropReceivedDataDelegate() override {} + ~DropReceivedDataDelegate() override = default; // Drop any received data. void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override {} @@ -4656,7 +4656,7 @@ SpdyStringPiece data) : StreamDelegateWithBody(stream, data) {} - ~StreamClosingDelegate() override {} + ~StreamClosingDelegate() override = default; void set_stream_to_close(const base::WeakPtr<SpdyStream>& stream_to_close) { stream_to_close_ = stream_to_close;
diff --git a/net/spdy/chromium/spdy_stream.cc b/net/spdy/chromium/spdy_stream.cc index 685bc838..decec4b2 100644 --- a/net/spdy/chromium/spdy_stream.cc +++ b/net/spdy/chromium/spdy_stream.cc
@@ -65,7 +65,7 @@ DCHECK(stream_.get()); } - ~HeadersBufferProducer() override {} + ~HeadersBufferProducer() override = default; std::unique_ptr<SpdyBuffer> ProduceBuffer() override { if (!stream_.get()) {
diff --git a/net/spdy/chromium/spdy_stream_test_util.cc b/net/spdy/chromium/spdy_stream_test_util.cc index 00b9ab9..b891cd2 100644 --- a/net/spdy/chromium/spdy_stream_test_util.cc +++ b/net/spdy/chromium/spdy_stream_test_util.cc
@@ -21,7 +21,7 @@ DCHECK(stream_); } -ClosingDelegate::~ClosingDelegate() {} +ClosingDelegate::~ClosingDelegate() = default; void ClosingDelegate::OnHeadersSent() {} @@ -51,8 +51,7 @@ send_headers_completed_(false) { } -StreamDelegateBase::~StreamDelegateBase() { -} +StreamDelegateBase::~StreamDelegateBase() = default; void StreamDelegateBase::OnHeadersSent() { stream_id_ = stream_->stream_id(); @@ -114,16 +113,14 @@ const base::WeakPtr<SpdyStream>& stream) : StreamDelegateBase(stream) {} -StreamDelegateDoNothing::~StreamDelegateDoNothing() { -} +StreamDelegateDoNothing::~StreamDelegateDoNothing() = default; StreamDelegateSendImmediate::StreamDelegateSendImmediate( const base::WeakPtr<SpdyStream>& stream, SpdyStringPiece data) : StreamDelegateBase(stream), data_(data) {} -StreamDelegateSendImmediate::~StreamDelegateSendImmediate() { -} +StreamDelegateSendImmediate::~StreamDelegateSendImmediate() = default; void StreamDelegateSendImmediate::OnHeadersReceived( const SpdyHeaderBlock& response_headers) { @@ -139,8 +136,7 @@ SpdyStringPiece data) : StreamDelegateBase(stream), buf_(new StringIOBuffer(data.as_string())) {} -StreamDelegateWithBody::~StreamDelegateWithBody() { -} +StreamDelegateWithBody::~StreamDelegateWithBody() = default; void StreamDelegateWithBody::OnHeadersSent() { StreamDelegateBase::OnHeadersSent(); @@ -152,8 +148,7 @@ : StreamDelegateBase(stream) { } -StreamDelegateCloseOnHeaders::~StreamDelegateCloseOnHeaders() { -} +StreamDelegateCloseOnHeaders::~StreamDelegateCloseOnHeaders() = default; void StreamDelegateCloseOnHeaders::OnHeadersReceived( const SpdyHeaderBlock& response_headers) {
diff --git a/net/spdy/chromium/spdy_stream_unittest.cc b/net/spdy/chromium/spdy_stream_unittest.cc index 911a183..8f546f81 100644 --- a/net/spdy/chromium/spdy_stream_unittest.cc +++ b/net/spdy/chromium/spdy_stream_unittest.cc
@@ -69,7 +69,7 @@ offset_(0), ssl_(SYNCHRONOUS, OK) {} - ~SpdyStreamTest() override {} + ~SpdyStreamTest() override = default; base::WeakPtr<SpdySession> CreateDefaultSpdySession() { SpdySessionKey key(HostPortPair::FromURL(url_), ProxyServer::Direct(), @@ -208,7 +208,7 @@ SpdyStringPiece data) : StreamDelegateWithBody(stream, data) {} - ~StreamDelegateWithTrailers() override {} + ~StreamDelegateWithTrailers() override = default; void OnTrailers(const SpdyHeaderBlock& trailers) override { trailers_ = trailers.Clone();
diff --git a/net/spdy/chromium/spdy_test_util_common.cc b/net/spdy/chromium/spdy_test_util_common.cc index 3a0dc7a..0c49f71 100644 --- a/net/spdy/chromium/spdy_test_util_common.cc +++ b/net/spdy/chromium/spdy_test_util_common.cc
@@ -156,7 +156,7 @@ class PriorityGetter : public BufferedSpdyFramerVisitorInterface { public: PriorityGetter() : priority_(0) {} - ~PriorityGetter() override {} + ~PriorityGetter() override = default; SpdyPriority priority() const { return priority_; @@ -238,9 +238,9 @@ (rv == OK) ? stream_request.ReleaseStream() : base::WeakPtr<SpdyStream>(); } -StreamReleaserCallback::StreamReleaserCallback() {} +StreamReleaserCallback::StreamReleaserCallback() = default; -StreamReleaserCallback::~StreamReleaserCallback() {} +StreamReleaserCallback::~StreamReleaserCallback() = default; CompletionCallback StreamReleaserCallback::MakeCallback( SpdyStreamRequest* request) { @@ -335,7 +335,7 @@ http2_settings[SETTINGS_INITIAL_WINDOW_SIZE] = kDefaultInitialWindowSize; } -SpdySessionDependencies::~SpdySessionDependencies() {} +SpdySessionDependencies::~SpdySessionDependencies() = default; // static std::unique_ptr<HttpNetworkSession> SpdySessionDependencies::SpdyCreateSession( @@ -405,7 +405,7 @@ class AllowAnyCertCTPolicyEnforcer : public CTPolicyEnforcer { public: - AllowAnyCertCTPolicyEnforcer() {} + AllowAnyCertCTPolicyEnforcer() = default; ~AllowAnyCertCTPolicyEnforcer() override = default; ct::CTPolicyCompliance CheckCompliance( @@ -529,7 +529,7 @@ explicit FakeSpdySessionClientSocket(int read_result) : MockClientSocket(NetLogWithSource()), read_result_(read_result) {} - ~FakeSpdySessionClientSocket() override {} + ~FakeSpdySessionClientSocket() override = default; int Read(IOBuffer* buf, int buf_len, @@ -627,7 +627,7 @@ response_spdy_framer_(SpdyFramer::ENABLE_COMPRESSION), default_url_(GURL(kDefaultUrl)) {} -SpdyTestUtil::~SpdyTestUtil() {} +SpdyTestUtil::~SpdyTestUtil() = default; void SpdyTestUtil::AddUrlToHeaderBlock(SpdyStringPiece url, SpdyHeaderBlock* headers) const {
diff --git a/net/spdy/chromium/spdy_write_queue.cc b/net/spdy/chromium/spdy_write_queue.cc index 246c4d9..2d874e4 100644 --- a/net/spdy/chromium/spdy_write_queue.cc +++ b/net/spdy/chromium/spdy_write_queue.cc
@@ -17,7 +17,7 @@ namespace net { -SpdyWriteQueue::PendingWrite::PendingWrite() {} +SpdyWriteQueue::PendingWrite::PendingWrite() = default; SpdyWriteQueue::PendingWrite::PendingWrite( SpdyFrameType frame_type, @@ -28,7 +28,7 @@ stream(stream), has_stream(stream.get() != nullptr) {} -SpdyWriteQueue::PendingWrite::~PendingWrite() {} +SpdyWriteQueue::PendingWrite::~PendingWrite() = default; SpdyWriteQueue::PendingWrite::PendingWrite(PendingWrite&& other) = default; SpdyWriteQueue::PendingWrite& SpdyWriteQueue::PendingWrite::operator=(
diff --git a/net/spdy/core/fuzzing/hpack_fuzz_util.cc b/net/spdy/core/fuzzing/hpack_fuzz_util.cc index 3d7ec4e..35604013 100644 --- a/net/spdy/core/fuzzing/hpack_fuzz_util.cc +++ b/net/spdy/core/fuzzing/hpack_fuzz_util.cc
@@ -35,14 +35,14 @@ using base::RandBytesAsString; using std::map; -HpackFuzzUtil::GeneratorContext::GeneratorContext() {} -HpackFuzzUtil::GeneratorContext::~GeneratorContext() {} +HpackFuzzUtil::GeneratorContext::GeneratorContext() = default; +HpackFuzzUtil::GeneratorContext::~GeneratorContext() = default; HpackFuzzUtil::Input::Input() : offset(0) {} -HpackFuzzUtil::Input::~Input() {} +HpackFuzzUtil::Input::~Input() = default; -HpackFuzzUtil::FuzzerContext::FuzzerContext() {} -HpackFuzzUtil::FuzzerContext::~FuzzerContext() {} +HpackFuzzUtil::FuzzerContext::FuzzerContext() = default; +HpackFuzzUtil::FuzzerContext::~FuzzerContext() = default; // static void HpackFuzzUtil::InitializeGeneratorContext(GeneratorContext* context) {
diff --git a/net/spdy/core/hpack/hpack_decoder_adapter.cc b/net/spdy/core/hpack/hpack_decoder_adapter.cc index c3197005..4a11a32b 100644 --- a/net/spdy/core/hpack/hpack_decoder_adapter.cc +++ b/net/spdy/core/hpack/hpack_decoder_adapter.cc
@@ -21,7 +21,7 @@ max_decode_buffer_size_bytes_(kMaxDecodeBufferSizeBytes), header_block_started_(false) {} -HpackDecoderAdapter::~HpackDecoderAdapter() {} +HpackDecoderAdapter::~HpackDecoderAdapter() = default; void HpackDecoderAdapter::ApplyHeaderTableSizeSetting(size_t size_setting) { DVLOG(2) << "HpackDecoderAdapter::ApplyHeaderTableSizeSetting"; @@ -111,7 +111,7 @@ } HpackDecoderAdapter::ListenerAdapter::ListenerAdapter() : handler_(nullptr) {} -HpackDecoderAdapter::ListenerAdapter::~ListenerAdapter() {} +HpackDecoderAdapter::ListenerAdapter::~ListenerAdapter() = default; void HpackDecoderAdapter::ListenerAdapter::set_handler( SpdyHeadersHandlerInterface* handler) {
diff --git a/net/spdy/core/hpack/hpack_encoder.cc b/net/spdy/core/hpack/hpack_encoder.cc index 1ae47c6..824b0a3e 100644 --- a/net/spdy/core/hpack/hpack_encoder.cc +++ b/net/spdy/core/hpack/hpack_encoder.cc
@@ -83,7 +83,7 @@ enable_compression_(true), should_emit_table_size_(false) {} -HpackEncoder::~HpackEncoder() {} +HpackEncoder::~HpackEncoder() = default; void HpackEncoder::EncodeHeaderSet(const Representations& representations, SpdyString* output) {
diff --git a/net/spdy/core/hpack/hpack_entry.cc b/net/spdy/core/hpack/hpack_entry.cc index 86d120bb..a948877 100644 --- a/net/spdy/core/hpack/hpack_entry.cc +++ b/net/spdy/core/hpack/hpack_entry.cc
@@ -63,7 +63,7 @@ return *this; } -HpackEntry::~HpackEntry() {} +HpackEntry::~HpackEntry() = default; // static size_t HpackEntry::Size(SpdyStringPiece name, SpdyStringPiece value) {
diff --git a/net/spdy/core/hpack/hpack_header_table.cc b/net/spdy/core/hpack/hpack_header_table.cc index dc29b5c..e59a5db 100644 --- a/net/spdy/core/hpack/hpack_header_table.cc +++ b/net/spdy/core/hpack/hpack_header_table.cc
@@ -39,7 +39,7 @@ max_size_(kDefaultHeaderTableSizeSetting), total_insertions_(static_entries_.size()) {} -HpackHeaderTable::~HpackHeaderTable() {} +HpackHeaderTable::~HpackHeaderTable() = default; const HpackEntry* HpackHeaderTable::GetByIndex(size_t index) { if (index == 0) {
diff --git a/net/spdy/core/hpack/hpack_huffman_table.cc b/net/spdy/core/hpack/hpack_huffman_table.cc index dbfa8e5..842acf2d 100644 --- a/net/spdy/core/hpack/hpack_huffman_table.cc +++ b/net/spdy/core/hpack/hpack_huffman_table.cc
@@ -32,7 +32,7 @@ HpackHuffmanTable::HpackHuffmanTable() : pad_bits_(0), failed_symbol_id_(0) {} -HpackHuffmanTable::~HpackHuffmanTable() {} +HpackHuffmanTable::~HpackHuffmanTable() = default; bool HpackHuffmanTable::Initialize(const HpackHuffmanSymbol* input_symbols, size_t symbol_count) {
diff --git a/net/spdy/core/hpack/hpack_output_stream.cc b/net/spdy/core/hpack/hpack_output_stream.cc index 6f01f64..49b2d60 100644 --- a/net/spdy/core/hpack/hpack_output_stream.cc +++ b/net/spdy/core/hpack/hpack_output_stream.cc
@@ -13,7 +13,7 @@ HpackOutputStream::HpackOutputStream() : bit_offset_(0) {} -HpackOutputStream::~HpackOutputStream() {} +HpackOutputStream::~HpackOutputStream() = default; void HpackOutputStream::AppendBits(uint8_t bits, size_t bit_size) { DCHECK_GT(bit_size, 0u);
diff --git a/net/spdy/core/hpack/hpack_static_table.cc b/net/spdy/core/hpack/hpack_static_table.cc index 2eb1720..0b3c0dc 100644 --- a/net/spdy/core/hpack/hpack_static_table.cc +++ b/net/spdy/core/hpack/hpack_static_table.cc
@@ -12,9 +12,9 @@ namespace net { -HpackStaticTable::HpackStaticTable() {} +HpackStaticTable::HpackStaticTable() = default; -HpackStaticTable::~HpackStaticTable() {} +HpackStaticTable::~HpackStaticTable() = default; void HpackStaticTable::Initialize(const HpackStaticEntry* static_entry_table, size_t static_entry_count) {
diff --git a/net/spdy/core/http2_frame_decoder_adapter.cc b/net/spdy/core/http2_frame_decoder_adapter.cc index ad71405..fcdf468 100644 --- a/net/spdy/core/http2_frame_decoder_adapter.cc +++ b/net/spdy/core/http2_frame_decoder_adapter.cc
@@ -165,7 +165,7 @@ ResetInternal(); } -Http2DecoderAdapter::~Http2DecoderAdapter() {} +Http2DecoderAdapter::~Http2DecoderAdapter() = default; void Http2DecoderAdapter::set_visitor(SpdyFramerVisitorInterface* visitor) { visitor_ = visitor;
diff --git a/net/spdy/core/mock_spdy_framer_visitor.cc b/net/spdy/core/mock_spdy_framer_visitor.cc index 437dc57..f9f3f407 100644 --- a/net/spdy/core/mock_spdy_framer_visitor.cc +++ b/net/spdy/core/mock_spdy_framer_visitor.cc
@@ -12,7 +12,7 @@ DelegateHeaderHandling(); } -MockSpdyFramerVisitor::~MockSpdyFramerVisitor() {} +MockSpdyFramerVisitor::~MockSpdyFramerVisitor() = default; } // namespace test
diff --git a/net/spdy/core/spdy_alt_svc_wire_format.cc b/net/spdy/core/spdy_alt_svc_wire_format.cc index a0a3783..df8b7d8 100644 --- a/net/spdy/core/spdy_alt_svc_wire_format.cc +++ b/net/spdy/core/spdy_alt_svc_wire_format.cc
@@ -35,7 +35,7 @@ } // namespace -SpdyAltSvcWireFormat::AlternativeService::AlternativeService() {} +SpdyAltSvcWireFormat::AlternativeService::AlternativeService() = default; SpdyAltSvcWireFormat::AlternativeService::AlternativeService( const SpdyString& protocol_id, @@ -49,7 +49,7 @@ max_age(max_age), version(version) {} -SpdyAltSvcWireFormat::AlternativeService::~AlternativeService() {} +SpdyAltSvcWireFormat::AlternativeService::~AlternativeService() = default; SpdyAltSvcWireFormat::AlternativeService::AlternativeService( const AlternativeService& other) = default;
diff --git a/net/spdy/core/spdy_deframer_visitor.cc b/net/spdy/core/spdy_deframer_visitor.cc index 20489d7..eadc070 100644 --- a/net/spdy/core/spdy_deframer_visitor.cc +++ b/net/spdy/core/spdy_deframer_visitor.cc
@@ -126,7 +126,7 @@ : listener_(std::move(listener)) { CHECK(listener_); } - ~SpdyTestDeframerImpl() override {} + ~SpdyTestDeframerImpl() override = default; bool AtFrameEnd() override; @@ -765,7 +765,7 @@ wrapped_ = SpdyMakeUnique<SpdyDeframerVisitorInterface>(); } } - ~LoggingSpdyDeframerDelegate() override {} + ~LoggingSpdyDeframerDelegate() override = default; void OnAltSvc(std::unique_ptr<SpdyAltSvcIR> frame) override { DVLOG(1) << "LoggingSpdyDeframerDelegate::OnAltSvc"; @@ -857,7 +857,7 @@ std::move(wrapped_listener)); } -CollectedFrame::CollectedFrame() {} +CollectedFrame::CollectedFrame() = default; CollectedFrame::CollectedFrame(CollectedFrame&& other) : frame_ir(std::move(other.frame_ir)), @@ -865,7 +865,7 @@ settings(std::move(other.settings)), error_reported(other.error_reported) {} -CollectedFrame::~CollectedFrame() {} +CollectedFrame::~CollectedFrame() = default; CollectedFrame& CollectedFrame::operator=(CollectedFrame&& other) { frame_ir = std::move(other.frame_ir);
diff --git a/net/spdy/core/spdy_frame_builder.cc b/net/spdy/core/spdy_frame_builder.cc index 23eff89..2e865e40 100644 --- a/net/spdy/core/spdy_frame_builder.cc +++ b/net/spdy/core/spdy_frame_builder.cc
@@ -26,7 +26,7 @@ length_(0), offset_(0) {} -SpdyFrameBuilder::~SpdyFrameBuilder() {} +SpdyFrameBuilder::~SpdyFrameBuilder() = default; char* SpdyFrameBuilder::GetWritableBuffer(size_t length) { if (!CanWrite(length)) {
diff --git a/net/spdy/core/spdy_framer.cc b/net/spdy/core/spdy_framer.cc index 4e90c05..581c2229 100644 --- a/net/spdy/core/spdy_framer.cc +++ b/net/spdy/core/spdy_framer.cc
@@ -290,7 +290,7 @@ "Our send limit should be at most our receive limit."); } -SpdyFramer::~SpdyFramer() {} +SpdyFramer::~SpdyFramer() = default; void SpdyFramer::set_debug_visitor( SpdyFramerDebugVisitorInterface* debug_visitor) { @@ -300,7 +300,7 @@ SpdyFramer::SpdyFrameIterator::SpdyFrameIterator(SpdyFramer* framer) : framer_(framer), is_first_frame_(true), has_next_frame_(true) {} -SpdyFramer::SpdyFrameIterator::~SpdyFrameIterator() {} +SpdyFramer::SpdyFrameIterator::~SpdyFrameIterator() = default; size_t SpdyFramer::SpdyFrameIterator::NextFrame(ZeroCopyOutputBuffer* output) { const SpdyFrameIR& frame_ir = GetIR(); @@ -352,7 +352,7 @@ SetEncoder(headers_ir_.get()); } -SpdyFramer::SpdyHeaderFrameIterator::~SpdyHeaderFrameIterator() {} +SpdyFramer::SpdyHeaderFrameIterator::~SpdyHeaderFrameIterator() = default; const SpdyFrameIR& SpdyFramer::SpdyHeaderFrameIterator::GetIR() const { return *(headers_ir_.get()); @@ -376,7 +376,8 @@ SetEncoder(push_promise_ir_.get()); } -SpdyFramer::SpdyPushPromiseFrameIterator::~SpdyPushPromiseFrameIterator() {} +SpdyFramer::SpdyPushPromiseFrameIterator::~SpdyPushPromiseFrameIterator() = + default; const SpdyFrameIR& SpdyFramer::SpdyPushPromiseFrameIterator::GetIR() const { return *(push_promise_ir_.get()); @@ -398,7 +399,7 @@ std::unique_ptr<const SpdyFrameIR> frame_ir) : framer_(framer), frame_ir_(std::move(frame_ir)) {} -SpdyFramer::SpdyControlFrameIterator::~SpdyControlFrameIterator() {} +SpdyFramer::SpdyControlFrameIterator::~SpdyControlFrameIterator() = default; size_t SpdyFramer::SpdyControlFrameIterator::NextFrame( ZeroCopyOutputBuffer* output) { @@ -790,7 +791,7 @@ public: explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer), frame_() {} - ~FrameSerializationVisitor() override {} + ~FrameSerializationVisitor() override = default; SpdySerializedFrame ReleaseSerializedFrame() { return std::move(frame_); } @@ -1214,7 +1215,7 @@ explicit FrameSerializationVisitorWithOutput(SpdyFramer* framer, ZeroCopyOutputBuffer* output) : framer_(framer), output_(output), result_(false) {} - ~FrameSerializationVisitorWithOutput() override {} + ~FrameSerializationVisitorWithOutput() override = default; size_t Result() { return result_; }
diff --git a/net/spdy/core/spdy_header_block.cc b/net/spdy/core/spdy_header_block.cc index 9fda908..b9468f58 100644 --- a/net/spdy/core/spdy_header_block.cc +++ b/net/spdy/core/spdy_header_block.cc
@@ -121,7 +121,7 @@ return *this; } -SpdyHeaderBlock::HeaderValue::~HeaderValue() {} +SpdyHeaderBlock::HeaderValue::~HeaderValue() = default; SpdyStringPiece SpdyHeaderBlock::HeaderValue::ConsolidatedValue() const { if (fragments_.empty()) { @@ -146,9 +146,9 @@ SpdyHeaderBlock::iterator::iterator(MapType::const_iterator it) : it_(it) {} -SpdyHeaderBlock::iterator::iterator(const iterator& other) : it_(other.it_) {} +SpdyHeaderBlock::iterator::iterator(const iterator& other) = default; -SpdyHeaderBlock::iterator::~iterator() {} +SpdyHeaderBlock::iterator::~iterator() = default; SpdyHeaderBlock::ValueProxy::ValueProxy( SpdyHeaderBlock::MapType* block, @@ -220,7 +220,7 @@ SpdyHeaderBlock::SpdyHeaderBlock(SpdyHeaderBlock&& other) = default; -SpdyHeaderBlock::~SpdyHeaderBlock() {} +SpdyHeaderBlock::~SpdyHeaderBlock() = default; SpdyHeaderBlock& SpdyHeaderBlock::operator=(SpdyHeaderBlock&& other) { block_.swap(other.block_);
diff --git a/net/spdy/core/spdy_no_op_visitor.cc b/net/spdy/core/spdy_no_op_visitor.cc index b82e547a..a196069c 100644 --- a/net/spdy/core/spdy_no_op_visitor.cc +++ b/net/spdy/core/spdy_no_op_visitor.cc
@@ -13,7 +13,7 @@ static_assert(std::is_abstract<SpdyNoOpVisitor>::value == false, "Need to update SpdyNoOpVisitor."); } -SpdyNoOpVisitor::~SpdyNoOpVisitor() {} +SpdyNoOpVisitor::~SpdyNoOpVisitor() = default; SpdyHeadersHandlerInterface* SpdyNoOpVisitor::OnHeaderFrameStart( SpdyStreamId stream_id) {
diff --git a/net/spdy/core/spdy_pinnable_buffer_piece.cc b/net/spdy/core/spdy_pinnable_buffer_piece.cc index a277060..588a17b 100644 --- a/net/spdy/core/spdy_pinnable_buffer_piece.cc +++ b/net/spdy/core/spdy_pinnable_buffer_piece.cc
@@ -11,7 +11,7 @@ SpdyPinnableBufferPiece::SpdyPinnableBufferPiece() : buffer_(nullptr), length_(0) {} -SpdyPinnableBufferPiece::~SpdyPinnableBufferPiece() {} +SpdyPinnableBufferPiece::~SpdyPinnableBufferPiece() = default; void SpdyPinnableBufferPiece::Pin() { if (!storage_ && buffer_ != nullptr && length_ != 0) {
diff --git a/net/spdy/core/spdy_protocol.cc b/net/spdy/core/spdy_protocol.cc index e13761b5..6beb2fa 100644 --- a/net/spdy/core/spdy_protocol.cc +++ b/net/spdy/core/spdy_protocol.cc
@@ -232,7 +232,7 @@ SpdyHeaderBlock header_block) : SpdyFrameWithFinIR(stream_id), header_block_(std::move(header_block)) {} -SpdyFrameWithHeaderBlockIR::~SpdyFrameWithHeaderBlockIR() {} +SpdyFrameWithHeaderBlockIR::~SpdyFrameWithHeaderBlockIR() = default; SpdyDataIR::SpdyDataIR(SpdyStreamId stream_id, SpdyStringPiece data) : SpdyFrameWithFinIR(stream_id), @@ -261,7 +261,7 @@ padded_(false), padding_payload_len_(0) {} -SpdyDataIR::~SpdyDataIR() {} +SpdyDataIR::~SpdyDataIR() = default; void SpdyDataIR::Visit(SpdyFrameVisitor* visitor) const { return visitor->VisitData(*this); @@ -281,7 +281,7 @@ set_error_code(error_code); } -SpdyRstStreamIR::~SpdyRstStreamIR() {} +SpdyRstStreamIR::~SpdyRstStreamIR() = default; void SpdyRstStreamIR::Visit(SpdyFrameVisitor* visitor) const { return visitor->VisitRstStream(*this); @@ -293,7 +293,7 @@ SpdySettingsIR::SpdySettingsIR() : is_ack_(false) {} -SpdySettingsIR::~SpdySettingsIR() {} +SpdySettingsIR::~SpdySettingsIR() = default; void SpdySettingsIR::Visit(SpdyFrameVisitor* visitor) const { return visitor->VisitSettings(*this); @@ -335,7 +335,7 @@ set_error_code(error_code); } -SpdyGoAwayIR::~SpdyGoAwayIR() {} +SpdyGoAwayIR::~SpdyGoAwayIR() = default; void SpdyGoAwayIR::Visit(SpdyFrameVisitor* visitor) const { return visitor->VisitGoAway(*this); @@ -350,7 +350,7 @@ encoding_ = SpdyMakeUnique<SpdyString>(); } -SpdyContinuationIR::~SpdyContinuationIR() {} +SpdyContinuationIR::~SpdyContinuationIR() = default; void SpdyContinuationIR::Visit(SpdyFrameVisitor* visitor) const { return visitor->VisitContinuation(*this); @@ -386,7 +386,7 @@ SpdyAltSvcIR::SpdyAltSvcIR(SpdyStreamId stream_id) : SpdyFrameIR(stream_id) {} -SpdyAltSvcIR::~SpdyAltSvcIR() {} +SpdyAltSvcIR::~SpdyAltSvcIR() = default; void SpdyAltSvcIR::Visit(SpdyFrameVisitor* visitor) const { return visitor->VisitAltSvc(*this);
diff --git a/net/spdy/core/spdy_test_utils.cc b/net/spdy/core/spdy_test_utils.cc index 1717236..e8e29f7 100644 --- a/net/spdy/core/spdy_test_utils.cc +++ b/net/spdy/core/spdy_test_utils.cc
@@ -149,9 +149,9 @@ compressed_header_bytes_parsed_ = compressed_header_bytes_parsed; } -TestServerPushDelegate::TestServerPushDelegate() {} +TestServerPushDelegate::TestServerPushDelegate() = default; -TestServerPushDelegate::~TestServerPushDelegate() {} +TestServerPushDelegate::~TestServerPushDelegate() = default; void TestServerPushDelegate::OnPush( std::unique_ptr<ServerPushHelper> push_helper,
diff --git a/sandbox/linux/syscall_broker/broker_process_unittest.cc b/sandbox/linux/syscall_broker/broker_process_unittest.cc index df49a50..ff7ff2b 100644 --- a/sandbox/linux/syscall_broker/broker_process_unittest.cc +++ b/sandbox/linux/syscall_broker/broker_process_unittest.cc
@@ -33,7 +33,6 @@ #include "testing/gtest/include/gtest/gtest.h" namespace sandbox { - namespace syscall_broker { class BrokerProcessTestHelper { @@ -48,6 +47,8 @@ namespace { +const int kFakeErrnoSentinel = 99999; + bool NoOpCallback() { return true; } @@ -55,22 +56,20 @@ } // namespace TEST(BrokerProcess, CreateAndDestroy) { - std::vector<BrokerFilePermission> permissions; - permissions.push_back(BrokerFilePermission::ReadOnly("/proc/cpuinfo")); - - std::unique_ptr<BrokerProcess> open_broker( - new BrokerProcess(EPERM, permissions)); - ASSERT_TRUE(open_broker->Init(base::BindRepeating(&NoOpCallback))); - - ASSERT_TRUE(TestUtils::CurrentProcessHasChildren()); + { + std::vector<BrokerFilePermission> permissions; + permissions.push_back(BrokerFilePermission::ReadOnly("/proc/cpuinfo")); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions); + ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); + ASSERT_TRUE(TestUtils::CurrentProcessHasChildren()); + } // Destroy the broker and check it has exited properly. - open_broker.reset(); ASSERT_FALSE(TestUtils::CurrentProcessHasChildren()); } TEST(BrokerProcess, TestOpenAccessNull) { std::vector<BrokerFilePermission> empty; - BrokerProcess open_broker(EPERM, empty); + BrokerProcess open_broker(kFakeErrnoSentinel, empty); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); int fd = open_broker.Open(NULL, O_RDONLY); @@ -250,43 +249,43 @@ const char kTrailingSlash[] = "/proc/"; std::vector<BrokerFilePermission> permissions; - permissions.push_back(BrokerFilePermission::ReadOnlyRecursive("/proc/")); - std::unique_ptr<BrokerProcess> open_broker( - new BrokerProcess(EPERM, permissions, fast_check_in_client)); - ASSERT_TRUE(open_broker->Init(base::BindRepeating(&NoOpCallback))); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); + ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); + // Open cpuinfo via the broker. - int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY); + int cpuinfo_fd = open_broker.Open(kFileCpuInfo, O_RDONLY); base::ScopedFD cpuinfo_fd_closer(cpuinfo_fd); ASSERT_GE(cpuinfo_fd, 0); int fd = -1; int can_access; - can_access = open_broker->Access(kNotAbsPath, R_OK); - ASSERT_EQ(can_access, -EPERM); - fd = open_broker->Open(kNotAbsPath, O_RDONLY); - ASSERT_EQ(fd, -EPERM); + can_access = open_broker.Access(kNotAbsPath, R_OK); + ASSERT_EQ(can_access, -kFakeErrnoSentinel); + fd = open_broker.Open(kNotAbsPath, O_RDONLY); + ASSERT_EQ(fd, -kFakeErrnoSentinel); - can_access = open_broker->Access(kDotDotStart, R_OK); - ASSERT_EQ(can_access, -EPERM); - fd = open_broker->Open(kDotDotStart, O_RDONLY); - ASSERT_EQ(fd, -EPERM); + can_access = open_broker.Access(kDotDotStart, R_OK); + ASSERT_EQ(can_access, -kFakeErrnoSentinel); + fd = open_broker.Open(kDotDotStart, O_RDONLY); + ASSERT_EQ(fd, -kFakeErrnoSentinel); - can_access = open_broker->Access(kDotDotMiddle, R_OK); - ASSERT_EQ(can_access, -EPERM); - fd = open_broker->Open(kDotDotMiddle, O_RDONLY); - ASSERT_EQ(fd, -EPERM); + can_access = open_broker.Access(kDotDotMiddle, R_OK); + ASSERT_EQ(can_access, -kFakeErrnoSentinel); + fd = open_broker.Open(kDotDotMiddle, O_RDONLY); + ASSERT_EQ(fd, -kFakeErrnoSentinel); - can_access = open_broker->Access(kDotDotEnd, R_OK); - ASSERT_EQ(can_access, -EPERM); - fd = open_broker->Open(kDotDotEnd, O_RDONLY); - ASSERT_EQ(fd, -EPERM); + can_access = open_broker.Access(kDotDotEnd, R_OK); + ASSERT_EQ(can_access, -kFakeErrnoSentinel); + fd = open_broker.Open(kDotDotEnd, O_RDONLY); + ASSERT_EQ(fd, -kFakeErrnoSentinel); - can_access = open_broker->Access(kTrailingSlash, R_OK); - ASSERT_EQ(can_access, -EPERM); - fd = open_broker->Open(kTrailingSlash, O_RDONLY); - ASSERT_EQ(fd, -EPERM); + can_access = open_broker.Access(kTrailingSlash, R_OK); + ASSERT_EQ(can_access, -kFakeErrnoSentinel); + fd = open_broker.Open(kTrailingSlash, O_RDONLY); + ASSERT_EQ(fd, -kFakeErrnoSentinel); } TEST(BrokerProcess, BadPathsClientCheck) { @@ -305,54 +304,53 @@ const char kFileCpuInfo[] = "/proc/cpuinfo"; const char kDirProc[] = "/proc/"; - std::vector<BrokerFilePermission> permissions; - if (recursive) - permissions.push_back(BrokerFilePermission::ReadOnlyRecursive(kDirProc)); - else - permissions.push_back(BrokerFilePermission::ReadOnly(kFileCpuInfo)); + { + std::vector<BrokerFilePermission> permissions; + permissions.push_back( + recursive ? BrokerFilePermission::ReadOnlyRecursive(kDirProc) + : BrokerFilePermission::ReadOnly(kFileCpuInfo)); - std::unique_ptr<BrokerProcess> open_broker( - new BrokerProcess(EPERM, permissions, fast_check_in_client)); - ASSERT_TRUE(open_broker->Init(base::BindRepeating(&NoOpCallback))); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); + ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); - int fd = -1; - fd = open_broker->Open(kFileCpuInfo, O_RDWR); - base::ScopedFD fd_closer(fd); - ASSERT_EQ(fd, -EPERM); + int fd = open_broker.Open(kFileCpuInfo, O_RDWR); + ASSERT_EQ(fd, -kFakeErrnoSentinel); - // Check we can read /proc/cpuinfo. - int can_access = open_broker->Access(kFileCpuInfo, R_OK); - ASSERT_EQ(can_access, 0); - can_access = open_broker->Access(kFileCpuInfo, W_OK); - ASSERT_EQ(can_access, -EPERM); - // Check we can not write /proc/cpuinfo. + // Check we can read /proc/cpuinfo. + int can_access = open_broker.Access(kFileCpuInfo, R_OK); + EXPECT_EQ(can_access, 0); + can_access = open_broker.Access(kFileCpuInfo, W_OK); + EXPECT_EQ(can_access, -kFakeErrnoSentinel); + // Check we can not write /proc/cpuinfo. - // Open cpuinfo via the broker. - int cpuinfo_fd = open_broker->Open(kFileCpuInfo, O_RDONLY); - base::ScopedFD cpuinfo_fd_closer(cpuinfo_fd); - ASSERT_GE(cpuinfo_fd, 0); - char buf[3]; - memset(buf, 0, sizeof(buf)); - int read_len1 = read(cpuinfo_fd, buf, sizeof(buf)); - ASSERT_GT(read_len1, 0); + // Open cpuinfo via the broker. + int cpuinfo_fd = open_broker.Open(kFileCpuInfo, O_RDONLY); + base::ScopedFD cpuinfo_fd_closer(cpuinfo_fd); + EXPECT_GE(cpuinfo_fd, 0); + char buf[3]; + memset(buf, 0, sizeof(buf)); + int read_len1 = read(cpuinfo_fd, buf, sizeof(buf)); + EXPECT_GT(read_len1, 0); - // Open cpuinfo directly. - int cpuinfo_fd2 = open(kFileCpuInfo, O_RDONLY); - base::ScopedFD cpuinfo_fd2_closer(cpuinfo_fd2); - ASSERT_GE(cpuinfo_fd2, 0); - char buf2[3]; - memset(buf2, 1, sizeof(buf2)); - int read_len2 = read(cpuinfo_fd2, buf2, sizeof(buf2)); - ASSERT_GT(read_len1, 0); + // Open cpuinfo directly. + int cpuinfo_fd2 = open(kFileCpuInfo, O_RDONLY); + base::ScopedFD cpuinfo_fd2_closer(cpuinfo_fd2); + EXPECT_GE(cpuinfo_fd2, 0); + char buf2[3]; + memset(buf2, 1, sizeof(buf2)); + int read_len2 = read(cpuinfo_fd2, buf2, sizeof(buf2)); + EXPECT_GT(read_len1, 0); - // The following is not guaranteed true, but will be in practice. - ASSERT_EQ(read_len1, read_len2); - // Compare the cpuinfo as returned by the broker with the one we opened - // ourselves. - ASSERT_EQ(memcmp(buf, buf2, read_len1), 0); + // The following is not guaranteed true, but will be in practice. + EXPECT_EQ(read_len1, read_len2); + // Compare the cpuinfo as returned by the broker with the one we opened + // ourselves. + EXPECT_EQ(memcmp(buf, buf2, read_len1), 0); - ASSERT_TRUE(TestUtils::CurrentProcessHasChildren()); - open_broker.reset(); + ASSERT_TRUE(TestUtils::CurrentProcessHasChildren()); + } + ASSERT_FALSE(TestUtils::CurrentProcessHasChildren()); } @@ -389,7 +387,7 @@ std::vector<BrokerFilePermission> permissions; permissions.push_back(BrokerFilePermission::ReadWrite(tempfile_name)); - BrokerProcess open_broker(EPERM, permissions); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); // Check we can access that file with read or write. @@ -423,7 +421,8 @@ std::vector<BrokerFilePermission> permissions; permissions.push_back(BrokerFilePermission::ReadOnly(kCpuInfo)); - BrokerProcess open_broker(EPERM, permissions, true /* fast_check_in_client */, + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + true /* fast_check_in_client */, true /* quiet_failures_for_tests */); SANDBOX_ASSERT(open_broker.Init(base::BindRepeating(&NoOpCallback))); const pid_t broker_pid = open_broker.broker_pid(); @@ -448,7 +447,8 @@ std::vector<BrokerFilePermission> permissions; permissions.push_back(BrokerFilePermission::ReadOnly(kCpuInfo)); - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); // Test that we do the right thing for O_CLOEXEC and O_NONBLOCK. int fd = -1; @@ -536,8 +536,7 @@ static const char kCpuInfo[] = "/proc/cpuinfo"; std::vector<BrokerFilePermission> permissions; permissions.push_back(BrokerFilePermission::ReadOnly(kCpuInfo)); - - BrokerProcess open_broker(EPERM, permissions); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions); SANDBOX_ASSERT(open_broker.Init(base::BindRepeating(&NoOpCallback))); const int ipc_fd = BrokerProcessTestHelper::GetIPCDescriptor(&open_broker); @@ -586,7 +585,8 @@ int lifeline_fds[2]; PCHECK(0 == pipe(lifeline_fds)); - BrokerProcess open_broker(EPERM, permissions, true /* fast_check_in_client */, + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + true /* fast_check_in_client */, false /* quiet_failures_for_tests */); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&CloseFD, lifeline_fds[0]))); // Make sure the writing end only exists in the broker process. @@ -622,15 +622,14 @@ std::vector<BrokerFilePermission> permissions; permissions.push_back(BrokerFilePermission::ReadWriteCreate(tempfile_name)); - - BrokerProcess open_broker(EPERM, permissions); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); int fd = -1; // Try without O_EXCL fd = open_broker.Open(tempfile_name, O_RDWR | O_CREAT); - ASSERT_EQ(fd, -EPERM); + ASSERT_EQ(fd, -kFakeErrnoSentinel); const char kTestText[] = "TESTTESTTEST"; // Create a file @@ -673,26 +672,29 @@ { // Nonexistent file with no permissions to see file. std::vector<BrokerFilePermission> permissions; - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); memset(&sb, 0, sizeof(sb)); - EXPECT_EQ(-EPERM, open_broker.Stat(nonesuch_name, &sb)); + EXPECT_EQ(-kFakeErrnoSentinel, open_broker.Stat(nonesuch_name, &sb)); } { // Actual file with no permission to see file. std::vector<BrokerFilePermission> permissions; - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); memset(&sb, 0, sizeof(sb)); - EXPECT_EQ(-EPERM, open_broker.Stat(tempfile_name, &sb)); + EXPECT_EQ(-kFakeErrnoSentinel, open_broker.Stat(tempfile_name, &sb)); } { // Nonexistent file with permissions to see file. std::vector<BrokerFilePermission> permissions; permissions.push_back(BrokerFilePermission::ReadOnly(nonesuch_name)); - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); memset(&sb, 0, sizeof(sb)); @@ -702,7 +704,8 @@ // Actual file with permissions to see file. std::vector<BrokerFilePermission> permissions; permissions.push_back(BrokerFilePermission::ReadOnly(tempfile_name)); - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); memset(&sb, 0, sizeof(sb)); @@ -753,9 +756,11 @@ permissions.push_back(BrokerFilePermission::ReadWrite(oldpath)); bool fast_check_in_client = false; - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); - EXPECT_EQ(-EPERM, open_broker.Rename(oldpath.c_str(), newpath.c_str())); + EXPECT_EQ(-kFakeErrnoSentinel, + open_broker.Rename(oldpath.c_str(), newpath.c_str())); // ... and no files moved around. EXPECT_TRUE(access(oldpath.c_str(), F_OK) == 0); @@ -767,9 +772,11 @@ permissions.push_back(BrokerFilePermission::ReadWrite(newpath)); bool fast_check_in_client = false; - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); - EXPECT_EQ(-EPERM, open_broker.Rename(oldpath.c_str(), newpath.c_str())); + EXPECT_EQ(-kFakeErrnoSentinel, + open_broker.Rename(oldpath.c_str(), newpath.c_str())); // ... and no files moved around. EXPECT_TRUE(access(oldpath.c_str(), F_OK) == 0); @@ -782,9 +789,11 @@ permissions.push_back(BrokerFilePermission::ReadWrite(newpath)); bool fast_check_in_client = false; - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); - EXPECT_EQ(-EPERM, open_broker.Rename(oldpath.c_str(), newpath.c_str())); + EXPECT_EQ(-kFakeErrnoSentinel, + open_broker.Rename(oldpath.c_str(), newpath.c_str())); // ... and no files moved around. EXPECT_TRUE(access(oldpath.c_str(), F_OK) == 0); @@ -797,9 +806,11 @@ permissions.push_back(BrokerFilePermission::ReadOnly(newpath)); bool fast_check_in_client = false; - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); - EXPECT_EQ(-EPERM, open_broker.Rename(oldpath.c_str(), newpath.c_str())); + EXPECT_EQ(-kFakeErrnoSentinel, + open_broker.Rename(oldpath.c_str(), newpath.c_str())); // ... and no files moved around. EXPECT_TRUE(access(oldpath.c_str(), F_OK) == 0); @@ -812,7 +823,8 @@ permissions.push_back(BrokerFilePermission::ReadWrite(newpath)); bool fast_check_in_client = false; - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); EXPECT_EQ(0, open_broker.Rename(oldpath.c_str(), newpath.c_str())); @@ -846,22 +858,27 @@ { // Nonexistent file with no permissions to see file. std::vector<BrokerFilePermission> permissions; - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); - EXPECT_EQ(-EPERM, open_broker.Readlink(nonesuch_name, buf, sizeof(buf))); + EXPECT_EQ(-kFakeErrnoSentinel, + open_broker.Readlink(nonesuch_name, buf, sizeof(buf))); } { // Actual file with no permissions to see file. std::vector<BrokerFilePermission> permissions; - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); - EXPECT_EQ(-EPERM, open_broker.Readlink(newpath_name, buf, sizeof(buf))); + EXPECT_EQ(-kFakeErrnoSentinel, + open_broker.Readlink(newpath_name, buf, sizeof(buf))); } { // Nonexistent file with permissions to see file. std::vector<BrokerFilePermission> permissions; permissions.push_back(BrokerFilePermission::ReadOnly(nonesuch_name)); - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); EXPECT_EQ(-ENOENT, open_broker.Readlink(nonesuch_name, buf, sizeof(buf))); } @@ -869,7 +886,8 @@ // Actual file with permissions to see file. std::vector<BrokerFilePermission> permissions; permissions.push_back(BrokerFilePermission::ReadOnly(newpath_name)); - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); ssize_t retlen = open_broker.Readlink(newpath_name, buf, sizeof(buf)); EXPECT_TRUE(retlen == static_cast<ssize_t>(strlen(oldpath_name))); @@ -879,7 +897,8 @@ // Actual file with permissions to see file, but too small a buffer. std::vector<BrokerFilePermission> permissions; permissions.push_back(BrokerFilePermission::ReadOnly(newpath_name)); - BrokerProcess open_broker(EPERM, permissions, fast_check_in_client); + BrokerProcess open_broker(kFakeErrnoSentinel, permissions, + fast_check_in_client); ASSERT_TRUE(open_broker.Init(base::BindRepeating(&NoOpCallback))); EXPECT_EQ(-ENAMETOOLONG, open_broker.Readlink(newpath_name, buf, 4)); }
diff --git a/services/service_manager/public/cpp/connector.cc b/services/service_manager/public/cpp/connector.cc index 850b940..6f0b1bc7 100644 --- a/services/service_manager/public/cpp/connector.cc +++ b/services/service_manager/public/cpp/connector.cc
@@ -95,6 +95,10 @@ return std::make_unique<Connector>(connector.PassInterface()); } +bool Connector::IsBound() const { + return connector_.is_bound(); +} + void Connector::FilterInterfaces(const std::string& spec, const Identity& source_identity, mojom::InterfaceProviderRequest request,
diff --git a/services/service_manager/public/cpp/connector.h b/services/service_manager/public/cpp/connector.h index 88c34882..932409079 100644 --- a/services/service_manager/public/cpp/connector.h +++ b/services/service_manager/public/cpp/connector.h
@@ -131,6 +131,9 @@ // to pass again. std::unique_ptr<Connector> Clone(); + // Returns true if this Connector instance is already bound to a thread. + bool IsBound() const; + void FilterInterfaces(const std::string& spec, const Identity& source_identity, mojom::InterfaceProviderRequest request,
diff --git a/services/ui/service.cc b/services/ui/service.cc index 246360a..574db166 100644 --- a/services/ui/service.cc +++ b/services/ui/service.cc
@@ -243,8 +243,13 @@ // Because GL libraries need to be initialized before entering the sandbox, // in MUS, |InitializeForUI| will load the GL libraries. ui::OzonePlatform::InitParams params; - params.connector = context()->connector(); - params.single_process = true; + if (should_host_viz_) { + // If mus is hosting viz, then it needs to set up ozone so that it can + // connect to the gpu service through the connector. + params.connector = context()->connector(); + // TODO(crbug.com/620927): This should be false once ozone-mojo is done. + params.single_process = true; + } ui::OzonePlatform::InitializeForUI(params); // Assume a client will change the layout to an appropriate configuration. @@ -265,9 +270,6 @@ input_device_controller_->AddInterface(®istry_); #endif -// TODO(rjkroege): Enter sandbox here before we start threads in GpuState -// http://crbug.com/584532 - #if !defined(OS_ANDROID) event_source_ = ui::PlatformEventSource::CreateDefault(); #endif
diff --git a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter index 6bce066..f150633 100644 --- a/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_browser_tests.filter
@@ -492,6 +492,14 @@ -RepostFormWarningTest.TestLoginAfterRepost -WebSocketBrowserTest.ReuseMainPageBasicAuthCredentialsForWebSocket +# These rely on proxy configuration and PAC execution being configured on the +# legacy in-process URLRequestContext. They should be removed or updated to +# use Mojo APIs instead. +-HangingPacRequestProxyScriptBrowserTest.Shutdown +-IOThreadBrowserTestWithHangingPacRequest.Shutdown +-IOThreadBrowserTestWithPacFileURL.FilePac +-ProxySettingsApiTest.ProxyEventsParseError + # http://crbug.com/783996 # Add support for TLS client auth. -PrerenderBrowserTest.PrerenderSSLClientCertIframe @@ -893,7 +901,3 @@ # TODO(jam): switch the tests to hook in via URLLoaderFactory to check load flags. -NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.IssuesIdlePriorityRequests/0 -NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.IssuesIdlePriorityRequests/1 --NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.Prefetch301LoadFlags/0 --NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.Prefetch301LoadFlags/1 --NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchLoadFlag/0 --NoStatePrefetchBrowserTest/NoStatePrefetchBrowserTest.PrefetchLoadFlag/1
diff --git a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter index 0556cad2..e799263 100644 --- a/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter +++ b/testing/buildbot/filters/mojo.fyi.network_content_browsertests.filter
@@ -15,10 +15,6 @@ # https://crbug.com/756312 -ServiceWorkerVersionBrowserV8CacheTest.Restart -# http://crbug.com/715630 -# This started failing when the test got added in r514724. --DownloadContentTest.ForceDownloadMhtml - # http://crbug.com/721398 -ClearSiteDataThrottleBrowserTest.CookiesIntegrationTest -ClearSiteDataThrottleBrowserTest.Credentials
diff --git a/testing/buildbot/filters/mojo.fyi.viz.content_browsertests.filter b/testing/buildbot/filters/mojo.fyi.viz.content_browsertests.filter index 340d045..7b6707b 100644 --- a/testing/buildbot/filters/mojo.fyi.viz.content_browsertests.filter +++ b/testing/buildbot/filters/mojo.fyi.viz.content_browsertests.filter
@@ -28,6 +28,7 @@ -PointerLockBrowserTest.* -SitePerProcessGestureBrowserTest.* -SitePerProcessHighDPIBrowserTest.* +-SitePerProcessInternalsBrowserTest.* -SitePerProcessMouseWheelBrowserTest.* -TouchSelectionForCrossProcessFramesTests/TouchSelectionControllerClientAuraSiteIsolationTest.*
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index f784d89..e4b3aa9 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -6279,7 +6279,7 @@ crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scaled.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scroll.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node.js [ Failure ] -crbug.com/591099 http/tests/devtools/elements/styles-1/color-aware-property-value-edit.html [ Failure ] +crbug.com/591099 http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/styles-2/add-import-rule.html [ Failure ] crbug.com/591099 http/tests/devtools/elements/styles-3/style-rule-from-imported-stylesheet.html [ Failure ] crbug.com/591099 http/tests/devtools/elements/styles-3/styles-add-new-rule-tab.js [ Failure Pass ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService index 391f8baa..53ac85b 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -192,7 +192,7 @@ # DevTools crbug.com/783982 crbug.com/783982 http/tests/devtools/startup/console/console-uncaught-promise-no-inspector.html [ Failure ] crbug.com/783982 http/tests/devtools/elements/styles-2/property-ui-location.html [ Failure ] -crbug.com/783982 http/tests/devtools/elements/styles-1/empty-background-url.html [ Failure ] +crbug.com/783982 http/tests/devtools/elements/styles-1/empty-background-url.js [ Failure ] # http/tests/fetch crbug.com/778721 http/tests/fetch/serviceworker-proxied/thorough/auth-base-https-other-https.html [ Pass Failure Timeout ]
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls index 7627acd..c546c81 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls +++ b/third_party/WebKit/LayoutTests/FlagExpectations/root-layer-scrolls
@@ -1,6 +1,5 @@ crbug.com/417782 compositing/iframes/become-composited-nested-iframes.html [ Failure ] crbug.com/417782 compositing/layer-creation/iframe-background-attachment-fixed.html [ Failure ] -crbug.com/417782 compositing/squashing/dont-squash-into-videos.html [ Failure ] crbug.com/417782 compositing/squashing/squash-above-fixed-1.html [ Failure ] crbug.com/417782 compositing/squashing/squash-above-fixed-3.html [ Failure ] crbug.com/417782 compositing/visibility/visibility-image-layers-dynamic.html [ Failure ] @@ -48,7 +47,6 @@ crbug.com/417782 inspector-protocol/layers/paint-profiler.js [ Crash ] crbug.com/417782 inspector-protocol/page/get-layout-metrics.js [ Failure ] crbug.com/417782 paint/invalidation/window-resize/window-resize-vertical-writing-mode.html [ Crash ] -crbug.com/417782 [ Mac Win ] paint/overflow/fixed-background-scroll-window.html [ Failure ] crbug.com/417782 plugins/webview-plugin-nested-iframe-scroll.html [ Failure ] crbug.com/417782 plugins/webview-plugin-scroll.html [ Failure ] crbug.com/417782 transforms/selection-bounds-in-transformed-view.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/SlowTests b/third_party/WebKit/LayoutTests/SlowTests index ea4eee8..2ddd271 100644 --- a/third_party/WebKit/LayoutTests/SlowTests +++ b/third_party/WebKit/LayoutTests/SlowTests
@@ -148,8 +148,8 @@ crbug.com/451577 virtual/mojo-loading/http/tests/devtools/resource-tree/resource-tree-crafted-frame-add.js [ Slow ] crbug.com/451577 http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame.js [ Slow ] crbug.com/451577 virtual/mojo-loading/http/tests/devtools/resource-tree/resource-tree-frame-in-crafted-frame.js [ Slow ] -crbug.com/510337 http/tests/devtools/elements/styles-1/edit-value-url-with-color.html [ Slow ] -crbug.com/667560 virtual/mojo-loading/http/tests/devtools/elements/styles-1/edit-value-url-with-color.html [ Slow ] +crbug.com/510337 http/tests/devtools/elements/styles-1/edit-value-url-with-color.js [ Slow ] +crbug.com/667560 virtual/mojo-loading/http/tests/devtools/elements/styles-1/edit-value-url-with-color.js [ Slow ] crbug.com/451577 [ Mac ] http/tests/devtools/extensions/extensions-reload.html [ Slow ] crbug.com/451577 [ Mac ] http/tests/devtools/extensions/extensions-resources.html [ Slow ] crbug.com/451577 [ Win10 ] http/tests/devtools/extensions/extensions-sidebar.html [ Slow ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations index 0c68300..89fdb4a 100644 --- a/third_party/WebKit/LayoutTests/TestExpectations +++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -2185,12 +2185,12 @@ crbug.com/626703 external/wpt/mediacapture-streams/MediaStreamTrack-end-manual.https.html [ Timeout Failure ] crbug.com/626703 external/wpt/media-source/mediasource-avtracks.html [ Failure Crash ] crbug.com/626703 external/wpt/media-source/mediasource-getvideoplaybackquality.html [ Timeout Failure ] -crbug.com/626703 external/wpt/notifications/constructor-basic.html [ Timeout ] -crbug.com/626703 external/wpt/notifications/constructor-invalid.html [ Timeout ] -crbug.com/626703 external/wpt/notifications/event-onclose.html [ Timeout ] -crbug.com/626703 external/wpt/notifications/event-onshow.html [ Timeout ] -crbug.com/626703 external/wpt/notifications/instance.html [ Timeout ] -crbug.com/626703 external/wpt/notifications/lang.html [ Timeout ] +crbug.com/626703 [ Mac10.13 ] external/wpt/notifications/constructor-basic.html [ Timeout ] +crbug.com/626703 [ Mac10.13 ] external/wpt/notifications/constructor-invalid.html [ Timeout ] +crbug.com/626703 [ Mac10.13 ] external/wpt/notifications/event-onclose.html [ Timeout ] +crbug.com/626703 [ Mac10.13 ] external/wpt/notifications/event-onshow.html [ Timeout ] +crbug.com/626703 [ Mac10.13 ] external/wpt/notifications/instance.html [ Timeout ] +crbug.com/626703 [ Mac10.13 ] external/wpt/notifications/lang.html [ Timeout ] crbug.com/626703 external/wpt/orientation-event/deviceorientationabsoluteevent.html [ Timeout ] crbug.com/626703 external/wpt/payment-request/payment-request-show-method.https.html [ Pass Failure ] crbug.com/626703 external/wpt/performance-timeline/po-observe.html [ Timeout ] @@ -2731,8 +2731,8 @@ crbug.com/619427 [ Mac Linux ] fast/overflow/overflow-height-float-not-removed-crash3.html [ Pass Failure ] -crbug.com/667371 http/tests/devtools/elements/styles-1/color-aware-property-value-edit.html [ Pass Failure ] -crbug.com/667560 virtual/mojo-loading/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.html [ Pass Failure ] +crbug.com/667371 http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js [ Pass Failure ] +crbug.com/667560 virtual/mojo-loading/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js [ Pass Failure ] # [css-ui] Imported tests from W3C suite. crbug.com/669473 external/wpt/css/css-ui/box-sizing-014.html [ Failure ]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json index c1f82744..3ca95b8 100644 --- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json +++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -42190,7 +42190,7 @@ "/css/css-multicol/multicol-br-inside-avoidcolumn-001.xht", [ [ - "/css/css-multicol/multicol-br-inside-avoidcolumn-ref.xht", + "/css/reference/ref-filled-green-200px-square.html", "==" ] ], @@ -92426,6 +92426,11 @@ {} ] ], + "content-security-policy/script-src/nonce-enforce-blocked-expected.txt": [ + [ + {} + ] + ], "content-security-policy/script-src/script-src-multiple-policies-multiple-hashing-algorithms.html.sub.headers": [ [ {} @@ -108881,11 +108886,6 @@ {} ] ], - "css/css-multicol/multicol-br-inside-avoidcolumn-ref.xht": [ - [ - {} - ] - ], "css/css-multicol/multicol-break-000-ref.xht": [ [ {} @@ -123571,6 +123571,11 @@ {} ] ], + "domxpath/001-expected.txt": [ + [ + {} + ] + ], "domxpath/002-expected.txt": [ [ {} @@ -140366,6 +140371,36 @@ {} ] ], + "notifications/constructor-basic-expected.txt": [ + [ + {} + ] + ], + "notifications/constructor-invalid-expected.txt": [ + [ + {} + ] + ], + "notifications/event-onclose-expected.txt": [ + [ + {} + ] + ], + "notifications/event-onshow-expected.txt": [ + [ + {} + ] + ], + "notifications/instance-expected.txt": [ + [ + {} + ] + ], + "notifications/lang-expected.txt": [ + [ + {} + ] + ], "notifications/resources/icon.png": [ [ {} @@ -162177,6 +162212,12 @@ {} ] ], + "content-security-policy/inheritance/inherited-csp-list-modifications-are-local.html": [ + [ + "/content-security-policy/inheritance/inherited-csp-list-modifications-are-local.html", + {} + ] + ], "content-security-policy/inheritance/window.html": [ [ "/content-security-policy/inheritance/window.html", @@ -222195,7 +222236,7 @@ "support" ], "./lint.whitelist": [ - "d92bc2e8adfdf40cd2023883e69e42fe59b5f069", + "c7da7debb6b2bcc32be61b6f0f89d4c4c1ba3d4d", "support" ], "./update-built-tests.sh": [ @@ -232126,6 +232167,10 @@ "3121f2277196e721af7d8cd522be148c875c79bd", "testharness" ], + "content-security-policy/inheritance/inherited-csp-list-modifications-are-local.html": [ + "b11ead62cbc23529449cdfd5dceba1058c1127b8", + "testharness" + ], "content-security-policy/inheritance/window.html": [ "5a59b9b239186ad49aa1928f0beb9cf4234b4a6e", "testharness" @@ -232462,6 +232507,10 @@ "e8583f7292cd90aa13e0e997aedf41763eb18928", "support" ], + "content-security-policy/script-src/nonce-enforce-blocked-expected.txt": [ + "8aaf7baa550f1fe8460868f3960def0a6a9bf8df", + "support" + ], "content-security-policy/script-src/nonce-enforce-blocked.html": [ "79bb6635e0964eef935cc2c9e93ff68034353f55", "testharness" @@ -233167,7 +233216,7 @@ "support" ], "content-security-policy/svg/including.sub.svg": [ - "4a7db45f8feeee77456ef0f837210b6f2f734a47", + "6e6534212bf7ac65d317b06ad7d9b719e6123b09", "support" ], "content-security-policy/svg/including.sub.svg.sub.headers": [ @@ -264319,13 +264368,9 @@ "reftest" ], "css/css-multicol/multicol-br-inside-avoidcolumn-001.xht": [ - "f2fe604ad53155fe3ba1eaaaadad7d4842aef239", + "934a25d72288a1400325662a7b3b9c47ceadd88d", "reftest" ], - "css/css-multicol/multicol-br-inside-avoidcolumn-ref.xht": [ - "d6c09e048d1a938cbf814a9e88b9ba0877b0222f", - "support" - ], "css/css-multicol/multicol-break-000-ref.xht": [ "213ce08f5d1294ce5ed571eca674886e20a10bde", "support" @@ -294198,6 +294243,10 @@ "b62d4cf898f819ccaf02769de3af12cdc80cea7e", "testharness" ], + "domxpath/001-expected.txt": [ + "940467b338503727c4bfae21fba04eeb23047931", + "support" + ], "domxpath/001.html": [ "f7161655a8955dd5a028b2e7dd5ada945176a930", "testharness" @@ -320186,10 +320235,18 @@ "8e1817d9460c31d4a761491d77a0651469fb9195", "support" ], + "notifications/constructor-basic-expected.txt": [ + "d9bf190aed1a7792e43cdb90d32a366863860e8c", + "support" + ], "notifications/constructor-basic.html": [ "f44faf981ecf76d2545709a510972c4f7687d75a", "testharness" ], + "notifications/constructor-invalid-expected.txt": [ + "bc1d38db6ebc265bcf98be8d1d203f1055b8f695", + "support" + ], "notifications/constructor-invalid.html": [ "9eb3e60038febe0953444e7032778a555fb5a98c", "testharness" @@ -320198,6 +320255,10 @@ "bd6af979456cb4f635ebd9db9c7db0ea9b719eba", "manual" ], + "notifications/event-onclose-expected.txt": [ + "a1ff7d2129b7b58b1c83bf1029fd39bfde338353", + "support" + ], "notifications/event-onclose.html": [ "746b480ea172babfb53352640479195eab5b1a75", "testharness" @@ -320210,6 +320271,10 @@ "1e82f951bc9c173dad643bed6f29d4db4f72c35a", "manual" ], + "notifications/event-onshow-expected.txt": [ + "4651931f3f1deee063e483581c7720a5bea82858", + "support" + ], "notifications/event-onshow.html": [ "6d222c489c530f03b8cc876150a1f12275454e9d", "testharness" @@ -320222,6 +320287,10 @@ "444f20a7ce7348764efe1b7eeb33e9611c4857ac", "manual" ], + "notifications/instance-expected.txt": [ + "09b69a66ddfc87cacfa2fb2cf68eb147d6c7cba7", + "support" + ], "notifications/instance.html": [ "0d1c3d540163dc596080f7c09291d41a41f5c9b9", "testharness" @@ -320230,6 +320299,10 @@ "0a653fc93d0d01761fb642d426461130134d9cbf", "testharness" ], + "notifications/lang-expected.txt": [ + "d7cdf784912c710774225f14e0d6b54cc7885e98", + "support" + ], "notifications/lang.html": [ "2fd743cbeb5f46435eb4ca739ff0c70c97ff3323", "testharness" @@ -343523,7 +343596,7 @@ "support" ], "webrtc/RTCTrackEvent-constructor.html": [ - "a73dde79625035cdd40d5abd8856cd44161dfdf9", + "4e9060c8c67de3a13f9d5727a8140a8ecfb8dfbf", "testharness" ], "webrtc/coverage/RTCDTMFSender.txt": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/svg/including.sub.svg b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/svg/including.sub.svg index 99b416b5..51215d90 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/svg/including.sub.svg +++ b/third_party/WebKit/LayoutTests/external/wpt/content-security-policy/svg/including.sub.svg
@@ -2,7 +2,8 @@ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="6cm" height="5cm" viewBox="0 0 600 500" - xmlns="http://www.w3.org/2000/svg" version="1.1"> + xmlns="http://www.w3.org/2000/svg" version="1.1" + xmlns:xlink="http://www.w3.org/1999/xlink"> <desc>using SVG as a resource doc should apply this doc's CSP</desc> <use xlink:href="scripted.svg#postmessagescript" />
diff --git a/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist b/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist index be63695..1b35835a 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist +++ b/third_party/WebKit/LayoutTests/external/wpt/lint.whitelist
@@ -119,9 +119,6 @@ CONSOLE: annotation-model/scripts/showdown.min.js CR AT EOL: annotation-model/scripts/showdown.min.js -# Lint doesn't know about sub.svg I guess -PARSE-FAILED: content-security-policy/svg/including.sub.svg - # Helper files that aren't valid XML PARSE-FAILED: acid/acid3/empty.xml PARSE-FAILED: dom/nodes/Document-createElement-namespace-tests/empty.svg
diff --git a/third_party/WebKit/LayoutTests/external/wpt/notifications/constructor-basic-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/notifications/constructor-basic-expected.txt new file mode 100644 index 0000000..e619090f --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/notifications/constructor-basic-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +NOTRUN Called the notification constructor with one argument. You must allow notifications for this origin before running this test. +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/notifications/constructor-invalid-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/notifications/constructor-invalid-expected.txt new file mode 100644 index 0000000..812d44e5 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/notifications/constructor-invalid-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +NOTRUN Called the notification constructor with no arguments. You must allow notifications for this origin before running this test. +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/notifications/event-onclose-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/notifications/event-onclose-expected.txt new file mode 100644 index 0000000..7736a0b9 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/notifications/event-onclose-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +NOTRUN Checked test prerequisites. You must allow notifications for thisorigin before running this test. +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/notifications/event-onshow-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/notifications/event-onshow-expected.txt new file mode 100644 index 0000000..f908574 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/notifications/event-onshow-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +NOTRUN Checked test prerequisites. You must allow notifications for this origin before running this test. +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/notifications/instance-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/notifications/instance-expected.txt new file mode 100644 index 0000000..a464abf --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/notifications/instance-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +NOTRUN Notification instance basic tests You must allow notifications for this origin before running this test. +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/notifications/lang-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/notifications/lang-expected.txt new file mode 100644 index 0000000..ffb5334 --- /dev/null +++ b/third_party/WebKit/LayoutTests/external/wpt/notifications/lang-expected.txt
@@ -0,0 +1,40 @@ +This is a testharness.js-based test. +NOTRUN Roundtripping lang "". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "en". Expecting "en". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "en-US-x-hixie". Expecting "en-US-x-hixie". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "de-DE". Expecting "de-DE". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "de-de". Expecting "de-de". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "de-De". Expecting "de-De". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "de-dE". Expecting "de-dE". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "de-DE-1996". Expecting "de-DE-1996". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "de-Latn-DE". Expecting "de-Latn-DE". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "de-Latf-DE". Expecting "de-Latf-DE". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "de-Latn-DE-1996". Expecting "de-Latn-DE-1996". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "de-CH". Expecting "de-CH". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "it-CH". Expecting "it-CH". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "fr-CH". Expecting "fr-CH". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "rm-CH". Expecting "rm-CH". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "es-CH". Expecting "es-CH". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "Latn-de". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "Latf-de". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "tic-tac-tac-toe". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "cocoa-1-bar". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "cocoa-a-bar". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "en-". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "en--". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "foo--bar". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "id---Java". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "fr-x". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "fr-xenomorph". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "fr-x-xenomorph". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "a". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "a-fr-lang". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "b-fr-lang". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "es1-KK-aa-bb-cc-dd". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "es2-KL-aa-bb-cc-dd". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "es3-KM-aa-bb-cc-dd". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "fooÉ". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "foöÉ-bÁr". Expecting "". You must allow notifications for this origin before running this test. +NOTRUN Roundtripping lang "foöÉbÁr". Expecting "". You must allow notifications for this origin before running this test. +Harness: the test ran to completion. +
diff --git a/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js b/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js index 2b478e9..0907b85 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js +++ b/third_party/WebKit/LayoutTests/external/wpt/resources/testharness.js
@@ -1569,11 +1569,6 @@ this._add_cleanup(callback); }; - Test.prototype.force_timeout = function() { - this.set_status(this.TIMEOUT); - this.phase = this.phases.HAS_RESULT; - }; - Test.prototype.set_timeout = function() { if (this.timeout_length !== null) { @@ -1600,6 +1595,8 @@ this.done(); }; + Test.prototype.force_timeout = Test.prototype.timeout; + Test.prototype.done = function() { if (this.phase == this.phases.COMPLETE) {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCTrackEvent-constructor.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCTrackEvent-constructor.html index d5c5f62..9579dd4 100644 --- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCTrackEvent-constructor.html +++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCTrackEvent-constructor.html
@@ -41,6 +41,7 @@ assert_equals(trackEvent.receiver, receiver); assert_equals(trackEvent.track, track); assert_array_equals(trackEvent.streams, []); + assert_equals(trackEvent.streams, trackEvent.streams); // [SameObject] assert_equals(trackEvent.transceiver, transceiver); assert_equals(trackEvent.type, 'track');
diff --git a/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/compositing/squashing/dont-squash-into-videos-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/compositing/squashing/dont-squash-into-videos-expected.txt index 7c33d99..6bda0c3 100644 --- a/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/compositing/squashing/dont-squash-into-videos-expected.txt +++ b/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/compositing/squashing/dont-squash-into-videos-expected.txt
@@ -23,7 +23,7 @@ "backgroundColor": "#ADD8E6" }, { - "name": "LayoutFlexibleBox (relative positioned) DIV class='phase-pre-ready state-no-source'", + "name": "LayoutFlexibleBox (relative positioned) DIV class='phase-pre-ready state-no-source use-default-poster'", "bounds": [100, 100] }, {
diff --git a/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/paint/overflow/fixed-background-scroll-window-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/platform/linux/paint/overflow/fixed-background-scroll-window-expected.txt similarity index 100% rename from third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/paint/overflow/fixed-background-scroll-window-expected.txt rename to third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/platform/linux/paint/overflow/fixed-background-scroll-window-expected.txt
diff --git a/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/platform/mac/paint/overflow/fixed-background-scroll-window-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/platform/mac/paint/overflow/fixed-background-scroll-window-expected.txt new file mode 100644 index 0000000..222722a --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/platform/mac/paint/overflow/fixed-background-scroll-window-expected.txt
@@ -0,0 +1,10 @@ +layer at (0,0) size 800x600 scrollY 1000.00 scrollHeight 4016 + LayoutView at (0,0) size 800x600 +layer at (0,-1000) size 800x4016 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x4016 + LayoutBlockFlow {BODY} at (8,8) size 784x4000 +layer at (8,116) size 666x18 + LayoutBlockFlow (positioned) {P} at (8,1116) size 665.63x18 + LayoutText {#text} at (0,0) size 666x18 + text run at (0,0) width 666: "Tests painting of fixed background content in scrolled container. Passes if the background doesn't scroll." +scrolled to 0,1000 \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/platform/win/paint/overflow/fixed-background-scroll-window-expected.txt b/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/platform/win/paint/overflow/fixed-background-scroll-window-expected.txt new file mode 100644 index 0000000..a6574ba --- /dev/null +++ b/third_party/WebKit/LayoutTests/flag-specific/root-layer-scrolls/platform/win/paint/overflow/fixed-background-scroll-window-expected.txt
@@ -0,0 +1,10 @@ +layer at (0,0) size 800x600 scrollY 1000.00 scrollHeight 4016 + LayoutView at (0,0) size 800x600 +layer at (0,-1000) size 800x4016 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600 + LayoutBlockFlow {HTML} at (0,0) size 800x4016 + LayoutBlockFlow {BODY} at (8,8) size 784x4000 +layer at (8,116) size 622x20 + LayoutBlockFlow (positioned) {P} at (8,1116) size 622x20 + LayoutText {#text} at (0,0) size 622x19 + text run at (0,0) width 622: "Tests painting of fixed background content in scrolled container. Passes if the background doesn't scroll." +scrolled to 0,1000 \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-inline-style-csp-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-inline-style-csp-expected.txt index e8f0aba..88b2abe 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-inline-style-csp-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-inline-style-csp-expected.txt
@@ -1,6 +1,5 @@ Tests that adding a new rule does not crash the renderer and modifying an inline style does not report errors when forbidden by Content-Security-Policy. -Text Running: testSetUp
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-inline-style-csp.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-inline-style-csp.js similarity index 85% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-inline-style-csp.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-inline-style-csp.js index 2e9fe6f..0c5f2e83 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-inline-style-csp.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-inline-style-csp.js
@@ -1,11 +1,16 @@ -<html> -<head> -<meta http-equiv="Content-Security-Policy" content="style-src https://*:443 'unsafe-eval'"> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> +// 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. -function test() { +(async function() { + TestRunner.addResult( + `Tests that adding a new rule does not crash the renderer and modifying an inline style does not report errors when forbidden by Content-Security-Policy.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <div id="inspected">Text</div> + `); + var nodeId; var rule; var matchedStyles; @@ -106,16 +111,4 @@ for (var i = 0; i < allProperties.length; ++i) TestRunner.addResult(allProperties[i].text); } -} -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that adding a new rule does not crash the renderer and modifying an inline style does not report errors when forbidden by Content-Security-Policy. -</p> - -<div id="inspected">Text</div> - -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-invalid-selector-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-invalid-selector-expected.txt index 3d22cbc8..bb0a5e1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-invalid-selector-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-invalid-selector-expected.txt
@@ -1,6 +1,5 @@ Tests that adding a new rule with invalid selector works as expected. -Text Running: init
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-invalid-selector.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-invalid-selector.html deleted file mode 100644 index 66dbc11..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-invalid-selector.html +++ /dev/null
@@ -1,35 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> - -function test() { - TestRunner.runTestSuite([ - function init(next) { - ElementsTestRunner.selectNodeAndWaitForStyles('inspected', next); - }, - - function keyframesRuleSelector(next) { - ElementsTestRunner.addNewRule('@-webkit-keyframes shake', callback); - - function callback() { - ElementsTestRunner.dumpSelectedElementStyles(true, false, true); - next(); - } - } - ]); -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that adding a new rule with invalid selector works as expected. -</p> - -<div id="inspected">Text</div> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-invalid-selector.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-invalid-selector.js new file mode 100644 index 0000000..81e898e --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-invalid-selector.js
@@ -0,0 +1,27 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Tests that adding a new rule with invalid selector works as expected.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <div id="inspected">Text</div> + `); + + TestRunner.runTestSuite([ + function init(next) { + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', next); + }, + + function keyframesRuleSelector(next) { + ElementsTestRunner.addNewRule('@-webkit-keyframes shake', callback); + + function callback() { + ElementsTestRunner.dumpSelectedElementStyles(true, false, true); + next(); + } + } + ]); +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-keyboard-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-keyboard-expected.txt index b44bba4..67bac53 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-keyboard-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-keyboard-expected.txt
@@ -1,6 +1,5 @@ Tests that adding a new rule works properly with user input. -Text Is editing? true [expanded] element.style { ()
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-keyboard.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-keyboard.html deleted file mode 100644 index ad3c71d..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-keyboard.html +++ /dev/null
@@ -1,34 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> - -function test() { - ElementsTestRunner.selectNodeAndWaitForStyles('inspected', next); - - async function next() { - await Elements.StylesSidebarPane._instance._createNewRuleInViaInspectorStyleSheet(); - eventSender.keyDown("Tab"); - await TestRunner.addSnifferPromise(Elements.StylePropertiesSection.prototype, "_editingSelectorCommittedForTest"); - - TestRunner.addResult("Is editing? " + UI.isEditing()); - ElementsTestRunner.dumpSelectedElementStyles(true, false, true); - - - TestRunner.completeTest(); - } -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that adding a new rule works properly with user input. -</p> - -<div id="inspected">Text</div> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-keyboard.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-keyboard.js new file mode 100644 index 0000000..68dd47f --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-keyboard.js
@@ -0,0 +1,26 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Tests that adding a new rule works properly with user input.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <div id="inspected">Text</div> + `); + + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', next); + + async function next() { + await Elements.StylesSidebarPane._instance._createNewRuleInViaInspectorStyleSheet(); + eventSender.keyDown('Tab'); + await TestRunner.addSnifferPromise(Elements.StylePropertiesSection.prototype, '_editingSelectorCommittedForTest'); + + TestRunner.addResult('Is editing? ' + UI.isEditing()); + ElementsTestRunner.dumpSelectedElementStyles(true, false, true); + + + TestRunner.completeTest(); + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body-expected.txt index 56e9191..51a5349e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body-expected.txt
@@ -1,6 +1,5 @@ -Tests that adding a new rule works when there is a STYLE element after BODY. TIMEOUT SHOULD NOT OCCUR! Bug 111299 +Tests that adding a new rule works when there is a STYLE element after BODY. TIMEOUT SHOULD NOT OCCUR! Bug 111299 https://bugs.webkit.org/show_bug.cgi?id=111299 -Text After adding new rule: [expanded] element.style { ()
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body.html deleted file mode 100644 index 1f73899..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body.html +++ /dev/null
@@ -1,58 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> -function addStyle() -{ - var style = document.createElement("style"); - document.documentElement.appendChild(style); - style.sheet.insertRule("foo {display: none;}", 0); -} - -function test() { - TestRunner.cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, stylesheetAdded); - TestRunner.evaluateInPage('addStyle()'); - - function stylesheetAdded() { - TestRunner.cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetAdded, stylesheetAdded); - ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); - } - - var treeElement; - var hasResourceChanged; - - function step1() { - ElementsTestRunner.addNewRule('inspected', step2); - } - - function step2() { - var section = ElementsTestRunner.firstMatchedStyleSection(); - var newProperty = section.addNewBlankProperty(); - newProperty.startEditing(); - newProperty.nameElement.textContent = 'color'; - newProperty.nameElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); - newProperty.valueElement.textContent = 'maroon'; - newProperty.valueElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); - ElementsTestRunner.waitForStyles('inspected', step3); - } - - function step3() { - TestRunner.addResult('After adding new rule:'); - ElementsTestRunner.dumpSelectedElementStyles(true, false, true); - TestRunner.completeTest(); - } -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that adding a new rule works when there is a STYLE element after BODY. TIMEOUT SHOULD NOT OCCUR! <a href="https://bugs.webkit.org/show_bug.cgi?id=111299">Bug 111299</a> -</p> - -<div id="inspected" style="font-size: 12px">Text</div> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body.js new file mode 100644 index 0000000..bdc89fb --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body.js
@@ -0,0 +1,57 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult( + `Tests that adding a new rule works when there is a STYLE element after BODY. TIMEOUT SHOULD NOT OCCUR! Bug 111299 https://bugs.webkit.org/show_bug.cgi?id=111299\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <p> + Tests that adding a new rule works when there is a STYLE element after BODY. TIMEOUT SHOULD NOT OCCUR! <a href="https://bugs.webkit.org/show_bug.cgi?id=111299">Bug 111299</a> + </p> + + <div id="inspected" style="font-size: 12px">Text</div> + `); + await TestRunner.evaluateInPagePromise(` + function addStyle() + { + var style = document.createElement("style"); + document.documentElement.appendChild(style); + style.sheet.insertRule("foo {display: none;}", 0); + } + `); + + TestRunner.cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded, stylesheetAdded); + TestRunner.evaluateInPage('addStyle()'); + + function stylesheetAdded() { + TestRunner.cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetAdded, stylesheetAdded); + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); + } + + var treeElement; + var hasResourceChanged; + + function step1() { + ElementsTestRunner.addNewRule('inspected', step2); + } + + function step2() { + var section = ElementsTestRunner.firstMatchedStyleSection(); + var newProperty = section.addNewBlankProperty(); + newProperty.startEditing(); + newProperty.nameElement.textContent = 'color'; + newProperty.nameElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); + newProperty.valueElement.textContent = 'maroon'; + newProperty.valueElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); + ElementsTestRunner.waitForStyles('inspected', step3); + } + + function step3() { + TestRunner.addResult('After adding new rule:'); + ElementsTestRunner.dumpSelectedElementStyles(true, false, true); + TestRunner.completeTest(); + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/background-parsing-crash-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/background-parsing-crash-expected.txt index 2a3d11d..2680e84 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/background-parsing-crash-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/background-parsing-crash-expected.txt
@@ -1 +1,3 @@ This test passes if it doesn't ASSERT. + +
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/background-parsing-crash.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/background-parsing-crash.html deleted file mode 100644 index 53bbb463..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/background-parsing-crash.html +++ /dev/null
@@ -1,22 +0,0 @@ -<html> -<head> -<style> -.absent { - background: #fff url(foo.png) no-repeat left 4px; -} - -body { - background: #fff; -} -</style> -<script src="../../../inspector/inspector-test.js"></script> -<script> -function test() { - TestRunner.completeTest(); -} -</script> -</head> -<body onload="runTest()"> -This test passes if it doesn't ASSERT. -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/background-parsing-crash.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/background-parsing-crash.js new file mode 100644 index 0000000..d2251047 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/background-parsing-crash.js
@@ -0,0 +1,21 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`This test passes if it doesn't ASSERT.\n`); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <style> + .absent { + background: #fff url(foo.png) no-repeat left 4px; + } + + body { + background: #fff; + } + </style> + `); + + TestRunner.completeTest(); +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cached-sync-computed-styles-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cached-sync-computed-styles-expected.txt index e5891ff..5e7be13e 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cached-sync-computed-styles-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cached-sync-computed-styles-expected.txt
@@ -1,6 +1,5 @@ Tests that computed styles are cached across synchronous requests. -Test # of backend calls sent [2 requests]: 1 # of backend calls sent [style update + another request]: 2
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cached-sync-computed-styles.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cached-sync-computed-styles.html deleted file mode 100644 index 506d2c808..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cached-sync-computed-styles.html +++ /dev/null
@@ -1,62 +0,0 @@ -<html> -<head> -<style id="style"> -#inspected { - background-color: green; -} -</style> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> - -function updateStyle() -{ - document.getElementById("style").textContent = "#inspected { color: red }"; -} - -function test() { - ElementsTestRunner.nodeWithId('inspected', step1); - var backendCallCount = 0; - var nodeId; - - function onBackendCall(domain, method, params) { - if (method === 'CSS.getComputedStyleForNode' && params.nodeId === nodeId) - ++backendCallCount; - } - - function step1(node) { - var callsLeft = 2; - nodeId = node.id; - TestRunner.addSniffer(Protocol.TargetBase.prototype, '_wrapCallbackAndSendMessageObject', onBackendCall, true); - TestRunner.cssModel.computedStylePromise(nodeId).then(styleCallback); - TestRunner.cssModel.computedStylePromise(nodeId).then(styleCallback); - function styleCallback() { - if (--callsLeft) - return; - TestRunner.addResult('# of backend calls sent [2 requests]: ' + backendCallCount); - TestRunner.evaluateInPage('updateStyle()', step2); - } - } - - function step2() { - TestRunner.cssModel.computedStylePromise(nodeId).then(callback); - function callback() { - TestRunner.addResult('# of backend calls sent [style update + another request]: ' + backendCallCount); - TestRunner.completeTest(); - } - } -} -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that computed styles are cached across synchronous requests. -</p> - -<div> - <div id="inspected">Test</div> -</div> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cached-sync-computed-styles.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cached-sync-computed-styles.js new file mode 100644 index 0000000..b4c5435f --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cached-sync-computed-styles.js
@@ -0,0 +1,56 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Tests that computed styles are cached across synchronous requests.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <style> + #inspected { + background-color: green; + } + </style> + <div> + <div id="inspected">Test</div> + </div> + `); + await TestRunner.evaluateInPagePromise(` + function updateStyle() + { + document.getElementById("style").textContent = "#inspected { color: red }"; + } + `); + + ElementsTestRunner.nodeWithId('inspected', step1); + var backendCallCount = 0; + var nodeId; + + function onBackendCall(domain, method, params) { + if (method === 'CSS.getComputedStyleForNode' && params.nodeId === nodeId) + ++backendCallCount; + } + + function step1(node) { + var callsLeft = 2; + nodeId = node.id; + TestRunner.addSniffer(Protocol.TargetBase.prototype, '_wrapCallbackAndSendMessageObject', onBackendCall, true); + TestRunner.cssModel.computedStylePromise(nodeId).then(styleCallback); + TestRunner.cssModel.computedStylePromise(nodeId).then(styleCallback); + function styleCallback() { + if (--callsLeft) + return; + TestRunner.addResult('# of backend calls sent [2 requests]: ' + backendCallCount); + TestRunner.evaluateInPage('updateStyle()', step2); + } + } + + function step2() { + TestRunner.cssModel.computedStylePromise(nodeId).then(callback); + function callback() { + TestRunner.addResult('# of backend calls sent [style update + another request]: ' + backendCallCount); + TestRunner.completeTest(); + } + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/case-sensitive-suggestions.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/case-sensitive-suggestions.js similarity index 82% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/case-sensitive-suggestions.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/case-sensitive-suggestions.js index 804c2a8..88f1c655 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/case-sensitive-suggestions.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/case-sensitive-suggestions.js
@@ -1,10 +1,12 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> +// 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. -function test() { +(async function() { + TestRunner.addResult(`Tests that text prompt suggestions' casing follows that of the user input.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + var prompt = new Elements.StylesSidebarPane.CSSPropertyPrompt(SDK.cssMetadata().allProperties(), [], null, true); TestRunner.runTestSuite([ @@ -59,13 +61,4 @@ callback(); } } -} -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that text prompt suggestions' casing follows that of the user input. -</p> -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit-expected.txt index e46a3d5..51cd6954e1 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit-expected.txt
@@ -1,7 +1,5 @@ Tests that property value being edited uses the user-specified color format. -inspected1 -inspected2 Running: init @@ -30,5 +28,5 @@ rgb(255, 255, 238) Running: editNewProperty -alicebluehsl(120, 100%, 25%) +hsl(120, 100%, 25%)
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js similarity index 81% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js index 351a90e..8bce8a3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-aware-property-value-edit.js
@@ -1,10 +1,16 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> +// 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. -function test() { +(async function() { + TestRunner.addResult(`Tests that property value being edited uses the user-specified color format.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <div id="inspected1" style="border: 1px solid red">inspected1</div> + <div id="inspected2" style="color: #ffffee">inspected2</div> + `); + TestRunner.runTestSuite([ function init(next) { ElementsTestRunner.selectNodeAndWaitForStyles('inspected1', next); @@ -81,18 +87,4 @@ next(); } } -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that property value being edited uses the user-specified color format. -</p> - -<div id="inspected1" style="border: 1px solid red">inspected1</div> -<div id="inspected2" style="color: #ffffee">inspected2</div> - -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-nicknames-lowercase.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-nicknames-lowercase.html deleted file mode 100644 index ff48435..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-nicknames-lowercase.html +++ /dev/null
@@ -1,26 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script> - -function test() { - var badNames = []; - for (var nickname in Common.Color.Nicknames) { - if (nickname.toLowerCase() !== nickname) - badNames.push(nickname); - } - - if (badNames.length === 0) - TestRunner.addResult('PASSED'); - else - TestRunner.addResult('Non-lowercase color nicknames: ' + badNames.join(', ')); - - TestRunner.completeTest(); -} - -</script> -</head> -<body onload="runTest()"> -<p>Tests that all color nicknames are lowercase to facilitate lookup</p> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-nicknames-lowercase.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-nicknames-lowercase.js new file mode 100644 index 0000000..a819e6d --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-nicknames-lowercase.js
@@ -0,0 +1,21 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Tests that all color nicknames are lowercase to facilitate lookup\n`); + await TestRunner.showPanel('elements'); + + var badNames = []; + for (var nickname in Common.Color.Nicknames) { + if (nickname.toLowerCase() !== nickname) + badNames.push(nickname); + } + + if (badNames.length === 0) + TestRunner.addResult('PASSED'); + else + TestRunner.addResult('Non-lowercase color nicknames: ' + badNames.join(', ')); + + TestRunner.completeTest(); +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-swatch-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-swatch-expected.txt index 47015b12..8b14301 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-swatch-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-swatch-expected.txt
@@ -1,6 +1,5 @@ The patch verifies that color swatch functions properly in matched and computed styles. crbug.com/461363 -Inspected div Running: selectNode
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-swatch.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-swatch.js similarity index 77% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-swatch.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-swatch.js index 415934b..874eb52 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-swatch.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/color-swatch.js
@@ -1,15 +1,22 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<style> -#inspected { - color: red; - --variable: red; -} -</style> -<script> -function test() { +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult( + `The patch verifies that color swatch functions properly in matched and computed styles. crbug.com/461363\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <style> + #inspected { + color: red; + --variable: red; + } + </style> + <div id="inspected">Inspected div</div> + `); + TestRunner.runTestSuite([ function selectNode(next) { ElementsTestRunner.selectNodeAndWaitForStylesWithComputed('inspected', next); @@ -57,14 +64,4 @@ function popoverVisible() { return !!document.body.querySelector('* /deep/ .spectrum-color'); } -} -</script> -</head> - -<body onload="runTest()"> -<p>The patch verifies that color swatch functions properly in matched and computed styles. crbug.com/461363</p> - -<div id="inspected">Inspected div</div> - -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector-expected.txt index 55aeab6..6c42192 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector-expected.txt
@@ -1,13 +1,12 @@ -Tests that renaming a selector updates element styles. Bug 70018. +Tests that renaming a selector updates element styles. Bug 70018. https://bugs.webkit.org/show_bug.cgi?id=70018 -Text === Before selector modification === [expanded] element.style { () color: red; [expanded] -#inspected { (commit-selector.html:4 -> commit-selector.html:4:13) +#inspected { (<style>…</style>) /-- overloaded --/ color: green; [expanded] @@ -20,7 +19,7 @@ color: red; [expanded] -hr, #inspected { (commit-selector.html:4 -> commit-selector.html:4:17) +hr, #inspected { (<style>…</style>) /-- overloaded --/ color: green; [expanded] @@ -33,7 +32,7 @@ color: red; [expanded] [no-affect] -#inspectedChanged { (commit-selector.html:4 -> commit-selector.html:4:20) +#inspectedChanged { (<style>…</style>) color: green; [expanded]
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector-mark-matching.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector-mark-matching.js similarity index 69% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector-mark-matching.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector-mark-matching.js index 2f1b431..182e97f 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector-mark-matching.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector-mark-matching.js
@@ -1,10 +1,16 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> +// 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. -function test() { +(async function() { + TestRunner.addResult( + `Tests that matching selectors are marked properly after new rule creation and selector change.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <div id="inspected"></div> + `); + var nodeId; var stylesPane; @@ -42,17 +48,4 @@ } } ]); -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that matching selectors are marked properly after new rule creation and selector change. -</p> - -<div id="inspected"></div> - -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector.html deleted file mode 100644 index 563acaa9..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector.html +++ /dev/null
@@ -1,54 +0,0 @@ -<html> -<head> -<style> -#inspected { - color: green; -} -</style> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> - -function test() { - ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); - - function step1() { - TestRunner.addResult('=== Before selector modification ==='); - ElementsTestRunner.dumpSelectedElementStyles(true); - var section = ElementsTestRunner.firstMatchedStyleSection(); - section.startEditingSelector(); - section._selectorElement.textContent = 'hr, #inspected '; - ElementsTestRunner.waitForSelectorCommitted(step2); - section._selectorElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); - } - - function step2() { - TestRunner.addResult('=== After non-affecting selector modification ==='); - ElementsTestRunner.dumpSelectedElementStyles(true); - var section = ElementsTestRunner.firstMatchedStyleSection(); - section.startEditingSelector(); - section._selectorElement.textContent = '#inspectedChanged'; - ElementsTestRunner.waitForSelectorCommitted(step3); - section._selectorElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); - } - - function step3() { - TestRunner.addResult('=== After affecting selector modification ==='); - ElementsTestRunner.dumpSelectedElementStyles(true); - TestRunner.completeTest(); - } -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that renaming a selector updates element styles. <a href="https://bugs.webkit.org/show_bug.cgi?id=70018">Bug 70018</a>. -</p> - -<div id="inspected" style="color: red">Text</div> -<div id="other"></div> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector.js new file mode 100644 index 0000000..4facc3f2 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/commit-selector.js
@@ -0,0 +1,51 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult( + `Tests that renaming a selector updates element styles. Bug 70018. https://bugs.webkit.org/show_bug.cgi?id=70018\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <style> + #inspected { + color: green; + } + </style> + <p> + Tests that renaming a selector updates element styles. <a href="https://bugs.webkit.org/show_bug.cgi?id=70018">Bug 70018</a>. + </p> + + <div id="inspected" style="color: red">Text</div> + <div id="other"></div> + `); + + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); + + function step1() { + TestRunner.addResult('=== Before selector modification ==='); + ElementsTestRunner.dumpSelectedElementStyles(true); + var section = ElementsTestRunner.firstMatchedStyleSection(); + section.startEditingSelector(); + section._selectorElement.textContent = 'hr, #inspected '; + ElementsTestRunner.waitForSelectorCommitted(step2); + section._selectorElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); + } + + function step2() { + TestRunner.addResult('=== After non-affecting selector modification ==='); + ElementsTestRunner.dumpSelectedElementStyles(true); + var section = ElementsTestRunner.firstMatchedStyleSection(); + section.startEditingSelector(); + section._selectorElement.textContent = '#inspectedChanged'; + ElementsTestRunner.waitForSelectorCommitted(step3); + section._selectorElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); + } + + function step3() { + TestRunner.addResult('=== After affecting selector modification ==='); + ElementsTestRunner.dumpSelectedElementStyles(true); + TestRunner.completeTest(); + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-live-edit.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-live-edit.html deleted file mode 100644 index 197aa6d..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-live-edit.html +++ /dev/null
@@ -1,39 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script src="../../../inspector/live-edit-test.js"></script> -<script src="../../../inspector/debugger-test.js"></script> -<link rel="stylesheet" href="../styles/resources/css-live-edit.css"> -<div id=foo></div> -<script> - -function test() { - TestRunner.runTestSuite([function testLiveEdit(next) { - SourcesTestRunner.showScriptSource('css-live-edit.css', didShowResource); - - function didShowResource(sourceFrame) { - TestRunner.addSniffer(SDK.CSSModel.prototype, '_fireStyleSheetChanged', didEditResource); - SourcesTestRunner.replaceInSource(sourceFrame, 'font-size: 12px;', 'font-size: 20px;'); - } - - function didEditResource() { - ElementsTestRunner.selectNodeAndWaitForStylesWithComputed('foo', didSelectElement); - } - - function didSelectElement() { - ElementsTestRunner.dumpSelectedElementStyles(false, true); - next(); - } - }]); -}; - -</script> - -</head> - -<body onload="runTest()"> -<p>Tests that styles are updated when live-editing css resource.</p> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-live-edit.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-live-edit.js new file mode 100644 index 0000000..7202c7c --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-live-edit.js
@@ -0,0 +1,32 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Tests that styles are updated when live-editing css resource.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.loadModule('sources_test_runner'); + await TestRunner.showPanel('sources'); + await TestRunner.loadHTML(` + <div id="foo"></div> + `); + await TestRunner.addStylesheetTag('../styles/resources/css-live-edit.css'); + + TestRunner.runTestSuite([function testLiveEdit(next) { + SourcesTestRunner.showScriptSource('css-live-edit.css', didShowResource); + + function didShowResource(sourceFrame) { + TestRunner.addSniffer(SDK.CSSModel.prototype, '_fireStyleSheetChanged', didEditResource); + SourcesTestRunner.replaceInSource(sourceFrame, 'font-size: 12px;', 'font-size: 20px;'); + } + + function didEditResource() { + ElementsTestRunner.selectNodeAndWaitForStylesWithComputed('foo', didSelectElement); + } + + function didSelectElement() { + ElementsTestRunner.dumpSelectedElementStyles(false, true); + next(); + } + }]); +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-outline.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-outline.js similarity index 68% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-outline.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-outline.js index cd350a8..0a75d8f 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-outline.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/css-outline.js
@@ -1,6 +1,12 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`The test verifies the CSS outline functionality.\n`); + await TestRunner.loadModule('formatter'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` <style id="styler"> @import url("some-url-to-load-css.css") print; @charset "ISO-8859-15"; @@ -51,18 +57,18 @@ } } </style> -<script> + `); + await TestRunner.evaluateInPagePromise(` + function initialize_Formatter() { + InspectorTest.preloadModule('formatter'); + } -function initialize_Formatter() { - InspectorTest.preloadModule('formatter'); -} + function getCSS() + { + return document.querySelector("#styler").textContent; + } + `); -function getCSS() -{ - return document.querySelector("#styler").textContent; -} - -function test() { function onRulesParsed(isLastChunk, rules) { for (var i = 0; i < rules.length; ++i) TestRunner.addObject(rules[i]); @@ -75,13 +81,4 @@ } TestRunner.evaluateInPage('getCSS()', onStyleFetched); -} - -</script> - -</head> - -<body onload="runTest()"> -<p>The test verifies the CSS outline functionality.</p> -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cssom-media-insert-crash-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cssom-media-insert-crash-expected.txt index 30ca49a4..507c282 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cssom-media-insert-crash-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cssom-media-insert-crash-expected.txt
@@ -1,5 +1,5 @@ -Tests that the inspected page does not crash after inspecting element with CSSOM added rules. Bug 373508 -Inspecting this element crashes DevTools +Tests that the inspected page does not crash after inspecting element with CSSOM added rules. Bug 373508 crbug.com/373508 + [expanded] element.style { () @@ -9,7 +9,7 @@ background: red; [expanded] -div { (cssom-media-ins…-crash.html:18 -> cssom-media-insert-crash.html:18:6) +div { (<style>…</style>) border: 1px solid black; /-- overloaded --/ background-color: white; padding: 20px;
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cssom-media-insert-crash.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cssom-media-insert-crash.html deleted file mode 100644 index e066e85..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cssom-media-insert-crash.html +++ /dev/null
@@ -1,36 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> - -function test() { - ElementsTestRunner.selectNodeAndWaitForStyles('box', step1); - - function step1() { - ElementsTestRunner.dumpSelectedElementStyles(true, false, true, false); - TestRunner.completeTest(); - } -} - -</script> -<style> -div { - border: 1px solid black; - background-color: white; - padding: 20px; -} -</style> -</head> - -<body onload="runTest()"> -Tests that the inspected page does not crash after inspecting element with CSSOM added rules. <a href="http://crbug.com/373508">Bug 373508</a> -<div id="box">Inspecting this element crashes DevTools</div> -<script> -var lastSheet = document.styleSheets[document.styleSheets.length - 1]; -var mediaIndex = lastSheet.insertRule('@media all { }', lastSheet.cssRules.length); -var mediaRule = lastSheet.cssRules[mediaIndex]; -mediaRule.insertRule('#box { background: red; color: white; }', mediaRule.cssRules.length); -</script> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cssom-media-insert-crash.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cssom-media-insert-crash.js new file mode 100644 index 0000000..ec861d3 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/cssom-media-insert-crash.js
@@ -0,0 +1,34 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult( + `Tests that the inspected page does not crash after inspecting element with CSSOM added rules. Bug 373508 crbug.com/373508\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <style> + div { + border: 1px solid black; + background-color: white; + padding: 20px; + } + </style> + Tests that the inspected page does not crash after inspecting element with CSSOM added rules. <a href="http://crbug.com/373508">Bug 373508</a> + <div id="box">Inspecting this element crashes DevTools</div> + `); + await TestRunner.evaluateInPagePromise(` + var lastSheet = document.styleSheets[document.styleSheets.length - 1]; + var mediaIndex = lastSheet.insertRule('@media all { }', lastSheet.cssRules.length); + var mediaRule = lastSheet.cssRules[mediaIndex]; + mediaRule.insertRule('#box { background: red; color: white; }', mediaRule.cssRules.length); + `); + + ElementsTestRunner.selectNodeAndWaitForStyles('box', step1); + + function step1() { + ElementsTestRunner.dumpSelectedElementStyles(true, false, true, false); + TestRunner.completeTest(); + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/disable-property-workingcopy-update.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/disable-property-workingcopy-update.js similarity index 72% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/disable-property-workingcopy-update.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/disable-property-workingcopy-update.js index 24c14a1..11adf5c 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/disable-property-workingcopy-update.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/disable-property-workingcopy-update.js
@@ -1,12 +1,19 @@ -<html> -<head> -<link rel="stylesheet" href="../styles/resources/disable-property-workingcopy-update.css"> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/debugger-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> +// 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. -function test() { +(async function() { + TestRunner.addResult( + `Tests that style property disablement is propagated into the stylesheet UISourceCode working copy.\n`); + await TestRunner.loadModule('sources_test_runner'); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('sources'); + await TestRunner.loadHTML(` + <div id="inspected"> + </div> + `); + await TestRunner.addStylesheetTag('../styles/resources/disable-property-workingcopy-update.css'); + var cssSourceFrame; Bindings.StylesSourceMapping.MinorChangeUpdateTimeoutMs = 10; @@ -65,17 +72,4 @@ next(); } } -} -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that style property disablement is propagated into the stylesheet UISourceCode working copy. -</p> - -<div id="inspected"> -</div> - -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/dynamic-style-tag-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/dynamic-style-tag-expected.txt index 4aa0b93..b18a0e4 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/dynamic-style-tag-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/dynamic-style-tag-expected.txt
@@ -22,7 +22,7 @@ - hasSourceURL: false - contents: /* comment */.inline-style-added-by-parser { - color: red; + color: red; } Stylesheet added: @@ -41,7 +41,7 @@ - hasSourceURL: true - contents: .inline-style-added-by-parser-with-source-url { - color: green; + color: green; } /*# sourceURL=inlineStyleAddedByParser.css*/ @@ -78,7 +78,7 @@ /-- overloaded --/ color: green; [expanded] -.inline-style-added-by-parser { (dynamic-style-tag.html:6 -> dynamic-style-tag.html:6:45) +.inline-style-added-by-parser { (dynamic-style-tag.html:3 -> dynamic-style-tag.html:3:45) /-- overloaded --/ color: red; [expanded]
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/dynamic-style-tag.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/dynamic-style-tag.html deleted file mode 100644 index a578d7524..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/dynamic-style-tag.html +++ /dev/null
@@ -1,55 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<style> -/* comment */.inline-style-added-by-parser { - color: red; -} -</style> -<style> -.inline-style-added-by-parser-with-source-url { - color: green; -} -/*# sourceURL=inlineStyleAddedByParser.css*/ -</style> -<script> -document.write("<style>\n.inline-style-added-by-parser-in-document-write {\n color: blue;\n}\n</style>"); -document.write("<style>\n.inline-style-added-by-document-write-with-source-url {\n color: yellow;\n}\n/*# sourceURL=inlineStyleAddedByDocumentWrite.css*/\n</style>"); -addStyleElement(".inline-style-created-by-script {\n color: orange;\n}"); -addStyleElement(".inline-style-created-by-script-with-source-url {\n color: grey;\n}\n/*# sourceURL=inlineStyleCreatedByScript.css*/"); - -function addStyleElement(styleContent) -{ - var styleElement = document.createElement("style"); - styleElement.textContent = styleContent; - document.head.appendChild(styleElement); -} - -function test() { - ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); - - async function step1() { - var styleSheets = TestRunner.cssModel.allStyleSheets(); - styleSheets.sort(); - for (var header of styleSheets) { - var content = await TestRunner.CSSAgent.getStyleSheetText(header.id); - - TestRunner.addResult('Stylesheet added:'); - TestRunner.addResult(' - isInline: ' + header.isInline); - TestRunner.addResult(' - sourceURL: ' + header.sourceURL.substring(header.sourceURL.lastIndexOf('/') + 1)); - TestRunner.addResult(' - hasSourceURL: ' + header.hasSourceURL); - TestRunner.addResult(' - contents: ' + content); - } - ElementsTestRunner.dumpSelectedElementStyles(true, false, true); - TestRunner.completeTest(); - } -} -</script> -</head> -<body onload="runTest()"> -<p>Tests that different types of inline styles are correctly disambiguated and their sourceURL is correct. -<div id="inspected" style="color:red" class="inline-style-added-by-parser inline-style-added-by-parser-with-source-url inline-style-added-by-parser-in-document-write inline-style-added-by-document-write-with-source-url inline-style-created-by-script inline-style-created-by-script-with-source-url"></div> -</body> -</html> -
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/dynamic-style-tag.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/dynamic-style-tag.js new file mode 100644 index 0000000..f79866c --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/dynamic-style-tag.js
@@ -0,0 +1,29 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult( + `Tests that different types of inline styles are correctly disambiguated and their sourceURL is correct.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.navigatePromise('resources/dynamic-style-tag.html'); + + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); + + async function step1() { + var styleSheets = TestRunner.cssModel.allStyleSheets(); + styleSheets.sort(); + for (var header of styleSheets) { + var content = await TestRunner.CSSAgent.getStyleSheetText(header.id); + + TestRunner.addResult('Stylesheet added:'); + TestRunner.addResult(' - isInline: ' + header.isInline); + TestRunner.addResult(' - sourceURL: ' + header.sourceURL.substring(header.sourceURL.lastIndexOf('/') + 1)); + TestRunner.addResult(' - hasSourceURL: ' + header.hasSourceURL); + TestRunner.addResult(' - contents: ' + content); + } + ElementsTestRunner.dumpSelectedElementStyles(true, false, true); + TestRunner.completeTest(); + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-inspector-stylesheet-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-inspector-stylesheet-expected.txt index 0579f500..38eee3c0 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-inspector-stylesheet-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-inspector-stylesheet-expected.txt
@@ -1,6 +1,5 @@ Tests that adding a new rule creates inspector stylesheet resource and allows its live editing. -Text Inspector stylesheet URL: inspector-stylesheet Inspector stylesheet content: #inspected {}
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-inspector-stylesheet.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-inspector-stylesheet.js similarity index 73% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-inspector-stylesheet.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-inspector-stylesheet.js index 02f03e8..2cd347f 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-inspector-stylesheet.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-inspector-stylesheet.js
@@ -1,11 +1,17 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script src="../../../inspector/debugger-test.js"></script> -<script> +// 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. -function test() { +(async function() { + TestRunner.addResult( + `Tests that adding a new rule creates inspector stylesheet resource and allows its live editing.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.loadModule('sources_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <div id="inspected">Text</div> + `); + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', onStylesSelected); function onStylesSelected(node) { @@ -48,16 +54,4 @@ } return result; } -} -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that adding a new rule creates inspector stylesheet resource and allows its live editing. -</p> - -<div id="inspected">Text</div> - -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-media-text-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-media-text-expected.txt index dfc4c355..46bb6c3 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-media-text-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-media-text-expected.txt
@@ -1,6 +1,5 @@ Tests that editing media text updates element styles. -Text === Before media text modification === [expanded] element.style { () @@ -8,12 +7,12 @@ [expanded] @media screen and (max-device-width: 100000px) -#inspected { (edit-media-text.html:8 -> edit-media-text.html:8:17) +#inspected { (<style>…</style>) /-- overloaded --/ color: blue; [expanded] @media screen and (max-device-width: 100000px) -#inspected { (edit-media-text.html:5 -> edit-media-text.html:5:17) +#inspected { (<style>…</style>) /-- overloaded --/ color: green; [expanded] @@ -27,12 +26,12 @@ [expanded] @media screen and (max-device-width: 99999px) -#inspected { (edit-media-text.html:8 -> edit-media-text.html:8:17) +#inspected { (<style>…</style>) /-- overloaded --/ color: blue; [expanded] @media screen and (max-device-width: 99999px) -#inspected { (edit-media-text.html:5 -> edit-media-text.html:5:17) +#inspected { (<style>…</style>) /-- overloaded --/ color: green; [expanded] @@ -45,11 +44,11 @@ color: red; [expanded] -#inspected { (edit-media-text.html:8 -> edit-media-text.html:8:17) +#inspected { (<style>…</style>) /-- overloaded --/ color: blue; [expanded] -#inspected { (edit-media-text.html:5 -> edit-media-text.html:5:17) +#inspected { (<style>…</style>) /-- overloaded --/ color: green; [expanded]
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-media-text.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-media-text.js similarity index 61% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-media-text.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-media-text.js index 02a80f3..bc1b27a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-media-text.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-media-text.js
@@ -1,25 +1,31 @@ -<html> -<head> -<style> -@media screen and (max-device-width: 100000px) { - #inspected { - color: green; - } - #inspected { - color: blue; - } -} -@media screen and (max-device-width: 200000px) { - #other { - color: green; - } -} -</style> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> +// 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. -function test() { +(async function() { + TestRunner.addResult(`Tests that editing media text updates element styles.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <style> + @media screen and (max-device-width: 100000px) { + #inspected { + color: green; + } + #inspected { + color: blue; + } + } + @media screen and (max-device-width: 200000px) { + #other { + color: green; + } + } + </style> + <div id="inspected" style="color: red">Text</div> + <div id="other"></div> + `); + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); function step1() { @@ -49,18 +55,4 @@ ElementsTestRunner.dumpSelectedElementStyles(true); TestRunner.completeTest(); } -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that editing media text updates element styles. -</p> - -<div id="inspected" style="color: red">Text</div> -<div id="other"></div> - -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-name-with-trimmed-value.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-name-with-trimmed-value.html deleted file mode 100644 index 5ad7762e..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-name-with-trimmed-value.html +++ /dev/null
@@ -1,40 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> - -function test() { - ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); - - function step1() { - var treeElement = ElementsTestRunner.getElementStylePropertyTreeItem('background'); - TestRunner.addResult('Viewing \'background\' value in Styles:'); - TestRunner.addResult(treeElement.valueElement.textContent); - - treeElement.startEditing(treeElement.nameElement); - treeElement.nameElement.textContent = 'background-image'; - treeElement.nameElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); - ElementsTestRunner.waitForStyleApplied(step2); - } - - function step2() { - var treeElement = ElementsTestRunner.getElementStylePropertyTreeItem('background-image'); - TestRunner.addResult('Renamed \'background\' to \'background-image\' (edited value):'); - TestRunner.addResult(treeElement.valueElement.textContent); - TestRunner.completeTest(); - } -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that editing a CSS property name in the Styles pane retains its original, non-trimmed value text. -</p> - -<div id="inspected" style="background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC)" /> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-name-with-trimmed-value.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-name-with-trimmed-value.js new file mode 100644 index 0000000..5eda2d91 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-name-with-trimmed-value.js
@@ -0,0 +1,37 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult( + `Tests that editing a CSS property name in the Styles pane retains its original, non-trimmed value text.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <div id="inspected" style="background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC)"> + + + + </div> + `); + + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); + + function step1() { + var treeElement = ElementsTestRunner.getElementStylePropertyTreeItem('background'); + TestRunner.addResult('Viewing \'background\' value in Styles:'); + TestRunner.addResult(treeElement.valueElement.textContent); + + treeElement.startEditing(treeElement.nameElement); + treeElement.nameElement.textContent = 'background-image'; + treeElement.nameElement.dispatchEvent(TestRunner.createKeyEvent('Enter')); + ElementsTestRunner.waitForStyleApplied(step2); + } + + function step2() { + var treeElement = ElementsTestRunner.getElementStylePropertyTreeItem('background-image'); + TestRunner.addResult('Renamed \'background\' to \'background-image\' (edited value):'); + TestRunner.addResult(treeElement.valueElement.textContent); + TestRunner.completeTest(); + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-resource-referred-by-multiple-styletags-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-resource-referred-by-multiple-styletags-expected.txt index 392ad45..bfe3e72 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-resource-referred-by-multiple-styletags-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-resource-referred-by-multiple-styletags-expected.txt
@@ -1,13 +1,11 @@ Tests that editing sourcecode which is referred by multiple stylesheets (via sourceURL comment) updates all stylesheets. -Inspected node - Headers count: 3 Running: Make edits with Sources Panel Both headers and uiSourceCode content: div{color:EDITED;} - + Running: Make edits via css model Both headers and uiSourceCode content:
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-resource-referred-by-multiple-styletags.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-resource-referred-by-multiple-styletags.js similarity index 63% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-resource-referred-by-multiple-styletags.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-resource-referred-by-multiple-styletags.js index eda1c30..6c58765 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-resource-referred-by-multiple-styletags.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-resource-referred-by-multiple-styletags.js
@@ -1,18 +1,29 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script src="../../../inspector/debugger-test.js"></script> -<script src="../../../inspector/live-edit-test.js"></script> -<script src="../../../inspector/bindings/bindings-test.js"></script> -<script> +// 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. -function prepareTest() -{ - runTest(); -} +(async function() { + TestRunner.addResult( + `Tests that editing sourcecode which is referred by multiple stylesheets (via sourceURL comment) updates all stylesheets.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.loadModule('sources_test_runner'); + await TestRunner.loadModule('bindings_test_runner'); + await TestRunner.showPanel('sources'); + await TestRunner.loadHTML(` + <div id="inspected">Inspected node</div> -async function test() { + <style>div{color:red;} + /*# sourceURL=stylesheet.css */ + </style> + + <template id="template"> + <style>div{color:red;} + /*# sourceURL=stylesheet.css */ + </style> + <p>Hi! I'm ShadowDOM v1!</p> + </template> + `); + await BindingsTestRunner.attachShadowDOM('shadow1', '#template'), await BindingsTestRunner.attachFrame('frame', './resources/frame.html'); var uiSourceCode = await TestRunner.waitForUISourceCode('stylesheet.css'); @@ -46,26 +57,4 @@ TestRunner.addResult('Both headers and uiSourceCode content:'); TestRunner.addResult(dedup.firstValue()); } -} -</script> -</head> -<body onload="prepareTest()"> -<p> -Tests that editing sourcecode which is referred by multiple stylesheets (via sourceURL comment) updates all stylesheets. -</p> - -<div id="inspected">Inspected node</div> - -<style>div{color:red;} -/*# sourceURL=stylesheet.css */ -</style> - -<template id='template'> -<style>div{color:red;} -/*# sourceURL=stylesheet.css */ -</style> -<p>Hi! I'm ShadowDOM v1!</p> -</template> - -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-inside-property.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-inside-property.js similarity index 72% rename from third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-inside-property.html rename to third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-inside-property.js index 56b63902..0a602cb 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-inside-property.html +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-inside-property.js
@@ -1,10 +1,15 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> +// 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. -function test() { +(async function() { + TestRunner.addResult(`Verifies that property value editing triggers style update in rendering engine.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <div id="inspected" style="font-size: 19px"></div> + `); + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', testEmulateKeypress); function testEmulateKeypress() { @@ -38,17 +43,4 @@ TestRunner.addResult('font-size: ' + inlineStyleResult.inlineStyle.getPropertyValue('font-size')); TestRunner.completeTest(); } -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Verifies that property value editing triggers style update in rendering engine. -</p> - -<div id="inspected" style="font-size: 19px"></div> - -</body> -</html> +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-url-with-color-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-url-with-color-expected.txt index ab08c0f22..c8968819 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-url-with-color-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-url-with-color-expected.txt
@@ -1,16 +1,5 @@ Tests that colors are not re-formatted inside url(...) when editing property values. -"white" background -"url( white )" background -"url(white.png)" background -"url(../foo/white.png)" background -"green url(white)" background -"url(white) green" background -"url(white) green, url(green)" background -"url(white), url(green)" background -"hsl(0, 50%, 50%) url(white)" background -"url(white) hsl(0, 50%, 50%)" background -"url(../black/white.png)" background rgb(255, 255, 255) url( white ) url(white.png)
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-url-with-color.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-url-with-color.html deleted file mode 100644 index 472b1de5..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-url-with-color.html +++ /dev/null
@@ -1,53 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> - -function test() { - var maxIndex = 11; - var idIndex = 1; - - Common.Color.detectColorFormat = function() { - return Common.Color.Format.RGB; - }; - - selectDivAndEditValue(); - - function selectDivAndEditValue() { - ElementsTestRunner.selectNodeAndWaitForStyles('inspected' + idIndex++, editCallback); - } - - function editCallback() { - var treeElement = ElementsTestRunner.getMatchedStylePropertyTreeItem('background'); - treeElement.startEditing(treeElement.valueElement); - TestRunner.addResult(treeElement.valueElement.textContent); - if (idIndex <= maxIndex) - selectDivAndEditValue(); - else - TestRunner.completeTest(); - } -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that colors are not re-formatted inside url(...) when editing property values. -</p> - -<div id="inspected1" style="background: white">"white" background</div> -<div id="inspected2" style="background: url( white )">"url( white )" background</div> -<div id="inspected3" style="background: url(white.png)">"url(white.png)" background</div> -<div id="inspected4" style="background: url(../foo/white.png)">"url(../foo/white.png)" background</div> -<div id="inspected5" style="background: green url(white)">"green url(white)" background</div> -<div id="inspected6" style="background: url(white) green">"url(white) green" background</div> -<div id="inspected7" style="background: url(white) green, url(green)">"url(white) green, url(green)" background</div> -<div id="inspected8" style="background: url(white), url(green)">"url(white), url(green)" background</div> -<div id="inspected9" style="background: hsl(0, 50%, 50%) url(white)">"hsl(0, 50%, 50%) url(white)" background</div> -<div id="inspected10" style="background: url(white) hsl(0, 50%, 50%)">"url(white) hsl(0, 50%, 50%)" background</div> -<div id="inspected11" style="background: url(../black/white.png)">"url(../black/white.png)" background</div> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-url-with-color.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-url-with-color.js new file mode 100644 index 0000000..1740ebb --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-url-with-color.js
@@ -0,0 +1,45 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Tests that colors are not re-formatted inside url(...) when editing property values.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <div id="inspected1" style="background: white">"white" background</div> + <div id="inspected2" style="background: url( white )">"url( white )" background</div> + <div id="inspected3" style="background: url(white.png)">"url(white.png)" background</div> + <div id="inspected4" style="background: url(../foo/white.png)">"url(../foo/white.png)" background</div> + <div id="inspected5" style="background: green url(white)">"green url(white)" background</div> + <div id="inspected6" style="background: url(white) green">"url(white) green" background</div> + <div id="inspected7" style="background: url(white) green, url(green)">"url(white) green, url(green)" background</div> + <div id="inspected8" style="background: url(white), url(green)">"url(white), url(green)" background</div> + <div id="inspected9" style="background: hsl(0, 50%, 50%) url(white)">"hsl(0, 50%, 50%) url(white)" background</div> + <div id="inspected10" style="background: url(white) hsl(0, 50%, 50%)">"url(white) hsl(0, 50%, 50%)" background</div> + <div id="inspected11" style="background: url(../black/white.png)">"url(../black/white.png)" background</div> + `); + + var maxIndex = 11; + var idIndex = 1; + + Common.Color.detectColorFormat = function() { + return Common.Color.Format.RGB; + }; + + selectDivAndEditValue(); + + function selectDivAndEditValue() { + ElementsTestRunner.selectNodeAndWaitForStyles('inspected' + idIndex++, editCallback); + } + + function editCallback() { + var treeElement = ElementsTestRunner.getMatchedStylePropertyTreeItem('background'); + treeElement.startEditing(treeElement.valueElement); + TestRunner.addResult(treeElement.valueElement.textContent); + if (idIndex <= maxIndex) + selectDivAndEditValue(); + else + TestRunner.completeTest(); + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url-expected.txt index 9d4a9e7f..23141aa 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url-expected.txt
@@ -1,4 +1,4 @@ -Tests that editing a CSS property value in the Styles pane restores the original, non-trimmed value text. Bug 107936. +Tests that editing a CSS property value in the Styles pane restores the original, non-trimmed value text. Bug 107936. https://bugs.webkit.org/show_bug.cgi?id=107936 Viewing 'background' value in Styles: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFW…9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC) repeat-y 50% top
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url.html deleted file mode 100644 index d96806897..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url.html +++ /dev/null
@@ -1,33 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<script> - -function test() { - ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); - - function step1() { - var treeElement = ElementsTestRunner.getElementStylePropertyTreeItem('background'); - TestRunner.addResult('Viewing \'background\' value in Styles:'); - TestRunner.addResult(treeElement.valueElement.textContent); - - treeElement.startEditing(treeElement.valueElement); - TestRunner.addResult('Editing \'background\' value in Styles:'); - TestRunner.addResult(treeElement.valueElement.textContent); - TestRunner.completeTest(); - } -} - -</script> -</head> - -<body onload="runTest()"> -<p> -Tests that editing a CSS property value in the Styles pane restores the original, non-trimmed value text. <a href="https://bugs.webkit.org/show_bug.cgi?id=107936">Bug 107936</a>. -</p> - -<div id="inspected" style="background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC) repeat-y 50% top" /> - -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url.js new file mode 100644 index 0000000..9f549b71 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/edit-value-with-trimmed-url.js
@@ -0,0 +1,34 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult( + `Tests that editing a CSS property value in the Styles pane restores the original, non-trimmed value text. Bug 107936. https://bugs.webkit.org/show_bug.cgi?id=107936\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <p> + Tests that editing a CSS property value in the Styles pane restores the original, non-trimmed value text. <a href="https://bugs.webkit.org/show_bug.cgi?id=107936">Bug 107936</a>. + </p> + + <div id="inspected" style="background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC) repeat-y 50% top"> + + + + </div> + `); + + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', step1); + + function step1() { + var treeElement = ElementsTestRunner.getElementStylePropertyTreeItem('background'); + TestRunner.addResult('Viewing \'background\' value in Styles:'); + TestRunner.addResult(treeElement.valueElement.textContent); + + treeElement.startEditing(treeElement.valueElement); + TestRunner.addResult('Editing \'background\' value in Styles:'); + TestRunner.addResult(treeElement.valueElement.textContent); + TestRunner.completeTest(); + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/empty-background-url-expected.txt b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/empty-background-url-expected.txt index 22812eb..440b5d3a 100644 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/empty-background-url-expected.txt +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/empty-background-url-expected.txt
@@ -4,7 +4,7 @@ element.style { () [expanded] -#inspected { (empty-background-url.css:1 -> empty-background-url.css:1:13) +#inspected { (<style>…</style>) background-image: url(); [expanded]
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/empty-background-url.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/empty-background-url.html deleted file mode 100644 index 173bddc3..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/empty-background-url.html +++ /dev/null
@@ -1,21 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<link rel="stylesheet" href="../styles/resources/empty-background-url.css"> -<script> -function test() { - ElementsTestRunner.selectNodeAndWaitForStylesWithComputed('inspected', step1); - - function step1() { - ElementsTestRunner.dumpSelectedElementStyles(true, false); - TestRunner.completeTest(); - } -} -</script> -</head> -<body onload="runTest()"> -<p>Tests that empty url in the property value does not break inspector.</p> -<div id="inspected"></div> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/empty-background-url.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/empty-background-url.js new file mode 100644 index 0000000..2711a26 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/empty-background-url.js
@@ -0,0 +1,24 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Tests that empty url in the property value does not break inspector.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <style> + #inspected { + background-image: url(); + } + </style> + <div id="inspected"></div> + `); + + ElementsTestRunner.selectNodeAndWaitForStylesWithComputed('inspected', step1); + + function step1() { + ElementsTestRunner.dumpSelectedElementStyles(true, false); + TestRunner.completeTest(); + } +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/filter-matched-styles.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/filter-matched-styles.html deleted file mode 100644 index 2b78ae5..0000000 --- a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/filter-matched-styles.html +++ /dev/null
@@ -1,48 +0,0 @@ -<html> -<head> -<script src="../../../inspector/inspector-test.js"></script> -<script src="../../../inspector/elements-test.js"></script> -<style> -.mydiv { - border: 1px solid black; - padding: 10px 10px 10px 10px; -} - -#inspected { - border-size: 2px; -} - -</style> -<script> -function test() { - TestRunner.runTestSuite([ - function selectInitialNode(next) { - ElementsTestRunner.selectNodeAndWaitForStyles('inspected', next); - }, - - function testSimpleFiltering(next) { - ElementsTestRunner.filterMatchedStyles('padding'); - ElementsTestRunner.dumpRenderedMatchedStyles(); - next(); - }, - - function testLonghandsAreAutoExpanded(next) { - ElementsTestRunner.filterMatchedStyles('-top'); - ElementsTestRunner.dumpRenderedMatchedStyles(); - next(); - }, - - function testAutoExpandedLonghandsAreCollapsed(next) { - ElementsTestRunner.filterMatchedStyles(null); - ElementsTestRunner.dumpRenderedMatchedStyles(); - next(); - } - ]); -} -</script> -</head> -<body onload="runTest()"> -<p>Verifies that filtering in StylesSidebarPane works as expected.</p> -<div style="margin: 1px;" class="mydiv" id="inspected"></div> -</body> -</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/filter-matched-styles.js b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/filter-matched-styles.js new file mode 100644 index 0000000..27223746 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/filter-matched-styles.js
@@ -0,0 +1,47 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +(async function() { + TestRunner.addResult(`Verifies that filtering in StylesSidebarPane works as expected.\n`); + await TestRunner.loadModule('elements_test_runner'); + await TestRunner.showPanel('elements'); + await TestRunner.loadHTML(` + <style> + .mydiv { + border: 1px solid black; + padding: 10px 10px 10px 10px; + } + + #inspected { + border-size: 2px; + } + + </style> + <div style="margin: 1px;" class="mydiv" id="inspected"></div> + `); + + TestRunner.runTestSuite([ + function selectInitialNode(next) { + ElementsTestRunner.selectNodeAndWaitForStyles('inspected', next); + }, + + function testSimpleFiltering(next) { + ElementsTestRunner.filterMatchedStyles('padding'); + ElementsTestRunner.dumpRenderedMatchedStyles(); + next(); + }, + + function testLonghandsAreAutoExpanded(next) { + ElementsTestRunner.filterMatchedStyles('-top'); + ElementsTestRunner.dumpRenderedMatchedStyles(); + next(); + }, + + function testAutoExpandedLonghandsAreCollapsed(next) { + ElementsTestRunner.filterMatchedStyles(null); + ElementsTestRunner.dumpRenderedMatchedStyles(); + next(); + } + ]); +})();
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/resources/dynamic-style-tag.html b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/resources/dynamic-style-tag.html new file mode 100644 index 0000000..4e47863 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/elements/styles-1/resources/dynamic-style-tag.html
@@ -0,0 +1,27 @@ +<head> +<style> +/* comment */.inline-style-added-by-parser { + color: red; +} +</style> +<style> +.inline-style-added-by-parser-with-source-url { + color: green; +} +/*# sourceURL=inlineStyleAddedByParser.css*/ +</style> +<script> + document.write("<style>\n.inline-style-added-by-parser-in-document-write {\n color: blue;\n}\n</style>"); + document.write("<style>\n.inline-style-added-by-document-write-with-source-url {\n color: yellow;\n}\n/*# sourceURL=inlineStyleAddedByDocumentWrite.css*/\n</style>"); + addStyleElement(".inline-style-created-by-script {\n color: orange;\n}"); + addStyleElement(".inline-style-created-by-script-with-source-url {\n color: grey;\n}\n/*# sourceURL=inlineStyleCreatedByScript.css*/"); + + function addStyleElement(styleContent) + { + var styleElement = document.createElement("style"); + styleElement.textContent = styleContent; + document.head.appendChild(styleElement); + } +</script> +</head> +<div id="inspected" style="color:red" class="inline-style-added-by-parser inline-style-added-by-parser-with-source-url inline-style-added-by-parser-in-document-write inline-style-added-by-document-write-with-source-url inline-style-created-by-script inline-style-created-by-script-with-source-url"></div> \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/devtools/network/resources/redirect-cross-origin-empty-html.php b/third_party/WebKit/LayoutTests/http/tests/devtools/network/resources/redirect-cross-origin-empty-html.php new file mode 100644 index 0000000..1cffe015 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/devtools/network/resources/redirect-cross-origin-empty-html.php
@@ -0,0 +1,2 @@ +<?php + header("Location: http://localhost:8000/devtools/network/resources/empty.html"); \ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/response-interception-main-resource-cross-origin-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/response-interception-main-resource-cross-origin-expected.txt new file mode 100644 index 0000000..48db5bf --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/response-interception-main-resource-cross-origin-expected.txt
@@ -0,0 +1,10 @@ +Tests to ensure response interception works with cross origin redirects. +Network agent enabled +Setting interception patterns to intercept: http://127.0.0.1:8000/devtools/network/resources/redirect-cross-origin-empty-html.php + +Navigating to: http://127.0.0.1:8000/devtools/network/resources/redirect-cross-origin-empty-html.php +--- This url should redirect to: http://localhost:8000/devtools/network/resources/empty.html --- + +Request Intercepted: http://localhost:8000/devtools/network/resources/empty.html + +
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/response-interception-main-resource-cross-origin.js b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/response-interception-main-resource-cross-origin.js new file mode 100644 index 0000000..b6ff167 --- /dev/null +++ b/third_party/WebKit/LayoutTests/http/tests/inspector-protocol/network/response-interception-main-resource-cross-origin.js
@@ -0,0 +1,22 @@ +(async function(testRunner) { + var {page, session, dp} = await testRunner.startBlank(`Tests to ensure response interception works with cross origin redirects.`); + dp.Network.onRequestIntercepted(event => { + testRunner.log('Request Intercepted: ' + event.params.request.url); + testRunner.log(''); + testRunner.completeTest(); + }); + + await dp.Network.clearBrowserCookies(); + await dp.Network.clearBrowserCache(); + await dp.Network.setCacheDisabled({cacheDisabled: true}); + await session.protocol.Network.enable(); + testRunner.log('Network agent enabled'); + testRunner.log('Setting interception patterns to intercept: http://127.0.0.1:8000/devtools/network/resources/redirect-cross-origin-empty-html.php'); + await dp.Network.setRequestInterception({patterns: [{urlPattern: "http://localhost:8000/devtools/network/resources/empty.html", interceptionStage: 'HeadersReceived'}]}); + testRunner.log(''); + + testRunner.log('Navigating to: http://127.0.0.1:8000/devtools/network/resources/redirect-cross-origin-empty-html.php'); + testRunner.log('--- This url should redirect to: http://localhost:8000/devtools/network/resources/empty.html ---'); + dp.Page.navigate({url: 'http://127.0.0.1:8000/devtools/network/resources/redirect-cross-origin-empty-html.php'}); + testRunner.log(''); +})
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp index 50b12b0..adfb391 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.cpp
@@ -23,9 +23,6 @@ url_.RemoveFragmentIdentifier(); } -ScriptSourceCode::ScriptSourceCode(ScriptResource* resource) - : ScriptSourceCode(nullptr, resource) {} - ScriptSourceCode::ScriptSourceCode(ScriptStreamer* streamer, ScriptResource* resource) : source_(resource->SourceText()),
diff --git a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h index 3fd58b0c..52bb2bfd 100644 --- a/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h +++ b/third_party/WebKit/Source/bindings/core/v8/ScriptSourceCode.h
@@ -46,14 +46,17 @@ DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); public: - // We lose the encoding information from ScriptResource. - // Not sure if that matters. - explicit ScriptSourceCode(ScriptResource*); + // For inline scripts. ScriptSourceCode( const String& source, ScriptSourceLocationType = ScriptSourceLocationType::kUnknown, const KURL& = KURL(), const TextPosition& start_position = TextPosition::MinimumPosition()); + + // For external scripts. + // + // We lose the encoding information from ScriptResource. + // Not sure if that matters. ScriptSourceCode(ScriptStreamer*, ScriptResource*); ~ScriptSourceCode();
diff --git a/third_party/WebKit/Source/core/layout/LayoutInline.cpp b/third_party/WebKit/Source/core/layout/LayoutInline.cpp index 7a4209fc..30d3fd5c 100644 --- a/third_party/WebKit/Source/core/layout/LayoutInline.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutInline.cpp
@@ -34,6 +34,7 @@ #include "core/layout/LayoutView.h" #include "core/layout/api/LineLayoutBoxModel.h" #include "core/layout/line/InlineTextBox.h" +#include "core/layout/ng/inline/ng_inline_fragment_iterator.h" #include "core/layout/ng/layout_ng_block_flow.h" #include "core/paint/BoxPainter.h" #include "core/paint/InlinePainter.h" @@ -45,6 +46,19 @@ namespace blink { +namespace { + +// TODO(layout-dev): Once we generate fragment for all inline element, we should +// use |LayoutObject::EnclosingBlockFlowFragment()|. +const NGPhysicalBoxFragment* EnclosingBlockFlowFragmentOf( + const LayoutInline& node) { + if (!RuntimeEnabledFeatures::LayoutNGPaintFragmentsEnabled()) + return nullptr; + return node.EnclosingBlockFlowFragment(); +} + +} // anonymous namespace + struct SameSizeAsLayoutInline : public LayoutBoxModelObject { ~SameSizeAsLayoutInline() override {} LayoutObjectChildList children_; @@ -953,6 +967,19 @@ } // unnamed namespace LayoutRect LayoutInline::LinesBoundingBox() const { + if (const NGPhysicalBoxFragment* box_fragment = + EnclosingBlockFlowFragmentOf(*this)) { + LayoutRect result; + NGInlineFragmentIterator children(*box_fragment, this); + for (const auto& child : children) { + NGPhysicalOffset left_top = + child.fragment->Offset() + child.offset_to_container_box; + result.Unite(LayoutRect(LayoutPoint(left_top.left, left_top.top), + child.fragment->Size().ToLayoutSize())); + } + return result; + } + if (!AlwaysCreateLineBoxes()) { DCHECK(!FirstLineBox()); FloatRect float_result;
diff --git a/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp b/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp index ef11b4cd..8683a54 100644 --- a/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp +++ b/third_party/WebKit/Source/core/layout/LayoutInlineTest.cpp
@@ -6,12 +6,63 @@ #include "core/layout/LayoutBlockFlow.h" #include "core/layout/LayoutTestHelper.h" +#include "platform/runtime_enabled_features.h" +#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" #include "testing/gtest/include/gtest/gtest.h" namespace blink { class LayoutInlineTest : public RenderingTest {}; +// Helper class to run the same test code with and without LayoutNG +class ParameterizedLayoutInlineTest + : public ::testing::WithParamInterface<bool>, + private ScopedLayoutNGForTest, + private ScopedLayoutNGPaintFragmentsForTest, + public LayoutInlineTest { + public: + ParameterizedLayoutInlineTest() + : ScopedLayoutNGForTest(GetParam()), + ScopedLayoutNGPaintFragmentsForTest(GetParam()) {} + + protected: + bool LayoutNGEnabled() const { return GetParam(); } +}; + +INSTANTIATE_TEST_CASE_P(All, ParameterizedLayoutInlineTest, ::testing::Bool()); + +TEST_P(ParameterizedLayoutInlineTest, LinesBoundingBox) { + LoadAhem(); + SetBodyInnerHTML( + "<style>" + "* { font-family: Ahem; font-size: 13px; }" + ".vertical { writing-mode: vertical-rl; }" + "</style>" + "<p><span id=ltr1>abc<br>xyz</span></p>" + "<p><span id=ltr2>12 345 6789</span></p>" + "<p dir=rtl><span id=rtl1>abc<br>xyz</span></p>" + "<p dir=rtl><span id=rtl2>12 345 6789</span></p>" + "<p class=vertical><span id=vertical>abc<br>xyz</span></p>"); + EXPECT_EQ( + LayoutRect(LayoutPoint(0, 0), LayoutSize(39, 26)), + ToLayoutInline(GetLayoutObjectByElementId("ltr1"))->LinesBoundingBox()); + EXPECT_EQ( + LayoutRect(LayoutPoint(0, 0), LayoutSize(143, 13)), + ToLayoutInline(GetLayoutObjectByElementId("ltr2"))->LinesBoundingBox()); + EXPECT_EQ( + LayoutRect(LayoutPoint(745, 0), LayoutSize(39, 26)), + ToLayoutInline(GetLayoutObjectByElementId("rtl1"))->LinesBoundingBox()); + // TODO(layout-dev): LayoutNG should have same LayoutRect of legacy. + // See http://crbug.com/785687 + EXPECT_EQ( + LayoutNGEnabled() ? LayoutRect(LayoutPoint(745, 0), LayoutSize(65, 13)) + : LayoutRect(LayoutPoint(641, 0), LayoutSize(143, 13)), + ToLayoutInline(GetLayoutObjectByElementId("rtl2"))->LinesBoundingBox()); + EXPECT_EQ(LayoutRect(LayoutPoint(0, 0), LayoutSize(26, 39)), + ToLayoutInline(GetLayoutObjectByElementId("vertical")) + ->LinesBoundingBox()); +} + TEST_F(LayoutInlineTest, SimpleContinuation) { SetBodyInnerHTML( "<span id='splitInline'><i id='before'></i><h1 id='blockChild'></h1><i "
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/mediumIcons.png b/third_party/WebKit/Source/devtools/front_end/Images/mediumIcons.png index 34beef0..0114d7e 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/mediumIcons.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/mediumIcons.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/mediumIcons_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/mediumIcons_2x.png index 1964000b..d445127 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/mediumIcons_2x.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/mediumIcons_2x.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png index ddd12a5..baec937a 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png index 1d25e31..04372bb8 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png +++ b/third_party/WebKit/Source/devtools/front_end/Images/smallIcons_2x.png Binary files differ
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/mediumIcons.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/mediumIcons.svg index 198e83df..0a2250d 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/mediumIcons.svg +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/mediumIcons.svg
@@ -12,7 +12,7 @@ height="80" id="svg4775" version="1.1" - inkscape:version="0.48.0 r9654" + inkscape:version="0.48.4 r9939" sodipodi:docname="mediumIcons.svg" inkscape:export-filename="/Users/pfeldman/code/chromium/src/third_party/WebKit/Source/devtools/front_end/Images/mediumIcons.png" inkscape:export-xdpi="90" @@ -25,7 +25,7 @@ <dc:format>image/svg+xml</dc:format> <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> + <dc:title /> </cc:Work> </rdf:RDF> </metadata> @@ -715,4 +715,21 @@ d="M 20,8 H 17.19 C 16.74,7.22 16.12,6.55 15.37,6.04 L 17,4.41 15.59,3 13.42,5.17 C 12.96,5.06 12.49,5 12,5 11.51,5 11.04,5.06 10.59,5.17 L 8.41,3 7,4.41 8.62,6.04 C 7.88,6.55 7.26,7.22 6.81,8 H 4 v 2 H 6.09 C 6.04,10.33 6,10.66 6,11 v 1 H 4 v 2 h 2 v 1 c 0,0.34 0.04,0.67 0.09,1 H 4 v 2 h 2.81 c 1.04,1.79 2.97,3 5.19,3 2.22,0 4.15,-1.21 5.19,-3 H 20 V 16 H 17.91 C 17.96,15.67 18,15.34 18,15 v -1 h 2 v -2 h -2 v -1 c 0,-0.34 -0.04,-0.67 -0.09,-1 H 20 V 8 z m -6,8 h -4 v -2 h 4 v 2 z m 0,-4 h -4 v -2 h 4 v 2 z" inkscape:connector-curvature="0" /> </g> + <g + style="fill:none;stroke:none" + id="g6340" + transform="translate(48,0)"> + <rect + style="opacity:0.2" + height="16" + width="16" + y="0" + x="0" + id="rect6342" /> + <path + style="fill:#000000" + inkscape:connector-curvature="0" + id="path6344" + d="m 0.5,14 15,0 L 8,1 0.5,14 l 0,0 z m 8.5,-2 -2,0 0,-2 2,0 0,2 0,0 z M 9,9 7,9 7,6 9,6 9,9 9,9 z" /> + </g> </svg>
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes index ddcd6d8..1e8a0aae 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/optimize_png.hashes
@@ -4,8 +4,8 @@ "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", - "smallIcons.svg": "354f1686454c0605c0616f2ea45c426b", - "mediumIcons.svg": "06ad4148a1c881f25c07e27dc80aa1f6", + "smallIcons.svg": "beee6da075d6de8ef77fdf430ee798e5", + "mediumIcons.svg": "5ecf5731037057c627e6a222e9b24350", "breakpoint.svg": "69cd92d807259c022791112809b97799", "treeoutlineTriangles.svg": "017d2f89437df0afc6b9cd5ff43735d9", "chevrons.svg": "79b4b527771e30b6388ce664077b3409"
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg b/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg index ede94e8..2139a32 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/smallIcons.svg
@@ -12,7 +12,7 @@ height="110" id="svg4185" version="1.1" - inkscape:version="0.48.0 r9654" + inkscape:version="0.48.4 r9939" sodipodi:docname="smallIcons.svg"> <metadata id="metadata4459"> @@ -78,14 +78,13 @@ inkscape:window-height="1006" id="namedview4455" showgrid="true" - inkscape:zoom="7.4167645" - inkscape:cx="64.063483" - inkscape:cy="73.026233" - inkscape:window-x="508" + inkscape:zoom="3.7083823" + inkscape:cx="29.009401" + inkscape:cy="135.34201" + inkscape:window-x="980" inkscape:window-y="0" inkscape:window-maximized="0" - inkscape:current-layer="svg4185" - inkscape:snap-global="true"> + inkscape:current-layer="svg4185"> <inkscape:grid type="xygrid" id="grid4461" @@ -1026,4 +1025,19 @@ inkscape:connector-curvature="0" style="fill:none" /> </g> + <path + style="fill:#000000" + inkscape:connector-curvature="0" + d="M 105,22.528009 101,26.958771 101.94,28 105,24.617852 108.06,28 109,26.958771 z" + id="path3942" /> + <path + style="fill:none" + inkscape:connector-curvature="0" + d="M 76.448271,14.990123 H 93.976446 V 34.405914 H 76.448271 z" + id="path3944" /> + <path + style="fill:#000000" + inkscape:connector-curvature="0" + d="M 88.06,3.059999 85,6.113332 81.94,3.059999 l -0.94,0.94 4,4 4,-4 z" + id="path3974" /> </svg>
diff --git a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes index ddcd6d8..1e8a0aae 100644 --- a/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes +++ b/third_party/WebKit/Source/devtools/front_end/Images/src/svg2png.hashes
@@ -4,8 +4,8 @@ "breakpointConditional.svg": "4cf90210b2af2ed84db2f60b07bcde28", "checkboxCheckmark.svg": "f039bf85cee42ad5c30ca3bfdce7912a", "errorWave.svg": "e183fa242a22ed4784a92f6becbc2c45", - "smallIcons.svg": "354f1686454c0605c0616f2ea45c426b", - "mediumIcons.svg": "06ad4148a1c881f25c07e27dc80aa1f6", + "smallIcons.svg": "beee6da075d6de8ef77fdf430ee798e5", + "mediumIcons.svg": "5ecf5731037057c627e6a222e9b24350", "breakpoint.svg": "69cd92d807259c022791112809b97799", "treeoutlineTriangles.svg": "017d2f89437df0afc6b9cd5ff43735d9", "chevrons.svg": "79b4b527771e30b6388ce664077b3409"
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/Icon.js b/third_party/WebKit/Source/devtools/front_end/ui/Icon.js index f71bddc..3c65e20 100644 --- a/third_party/WebKit/Source/devtools/front_end/ui/Icon.js +++ b/third_party/WebKit/Source/devtools/front_end/ui/Icon.js
@@ -126,6 +126,8 @@ 'smallicon-cross': {position: 'b4', spritesheet: 'smallicons'}, 'smallicon-device': {position: 'c5', spritesheet: 'smallicons'}, 'smallicon-error': {position: 'c4', spritesheet: 'smallicons'}, + 'smallicon-expand-less': {position: 'f5', spritesheet: 'smallicons', isMask: true}, + 'smallicon-expand-more': {position: 'e6', spritesheet: 'smallicons', isMask: true}, 'smallicon-green-arrow': {position: 'a3', spritesheet: 'smallicons'}, 'smallicon-green-ball': {position: 'b3', spritesheet: 'smallicons'}, 'smallicon-info': {position: 'c3', spritesheet: 'smallicons'}, @@ -172,6 +174,7 @@ 'mediumicon-info-circle': {position: 'e2', spritesheet: 'mediumicons'}, 'mediumicon-bug': {position: 'd1', spritesheet: 'mediumicons'}, 'mediumicon-list': {position: 'e5', spritesheet: 'mediumicons'}, + 'mediumicon-warning': {position: 'd5', spritesheet: 'mediumicons', isMask: true}, 'badge-navigator-file-sync': {position: 'a9', spritesheet: 'largeicons'}, 'largeicon-activate-breakpoints': {position: 'b9', spritesheet: 'largeicons', isMask: true},
diff --git a/tools/gn/filesystem_utils.cc b/tools/gn/filesystem_utils.cc index 44fa0eb..f97edf6 100644 --- a/tools/gn/filesystem_utils.cc +++ b/tools/gn/filesystem_utils.cc
@@ -412,6 +412,37 @@ #endif } +base::FilePath MakeAbsoluteFilePathRelativeIfPossible( + const base::FilePath& base, + const base::FilePath& target) { + DCHECK(base.IsAbsolute()); + DCHECK(target.IsAbsolute()); + std::vector<base::FilePath::StringType> base_components; + std::vector<base::FilePath::StringType> target_components; + base.GetComponents(&base_components); + target.GetComponents(&target_components); +#if defined(OS_WIN) + // On Windows, it's impossible to have a relative path from C:\foo to D:\bar, + // so return the target as an aboslute path instead. + if (base_components[0] != target_components[0]) + return target; +#endif + size_t i; + for (i = 0; i < base_components.size() && i < target_components.size(); i++) { + if (base_components[i] != target_components[i]) + break; + } + std::vector<base::FilePath::StringType> relative_components; + for (size_t j = i; j < base_components.size(); j++) + relative_components.push_back(base::FilePath::kParentDirectory); + for (size_t j = i; j < target_components.size(); j++) + relative_components.push_back(target_components[j]); + base::FilePath relative(base::FilePath::kCurrentDirectory); + for (const auto& component : relative_components) + relative = relative.Append(component); + return relative; +} + void NormalizePath(std::string* path, const base::StringPiece& source_root) { char* pathbuf = path->empty() ? nullptr : &(*path)[0];
diff --git a/tools/gn/filesystem_utils.h b/tools/gn/filesystem_utils.h index bc14eb92..0396283 100644 --- a/tools/gn/filesystem_utils.h +++ b/tools/gn/filesystem_utils.h
@@ -116,6 +116,16 @@ const base::StringPiece& path, std::string* dest); +// Given two absolute paths |base| and |target|, returns a relative path to +// |target| as if the current directory was |base|. The relative path returned +// is minimal. For example, if "../../a/b/" and "../b" are both valid, then the +// latter will be returned. On Windows, it's impossible to have a relative path +// from C:\foo to D:\bar, so the absolute path |target| is returned instead for +// this case. +base::FilePath MakeAbsoluteFilePathRelativeIfPossible( + const base::FilePath& base, + const base::FilePath& target); + // Collapses "." and sequential "/"s and evaluates "..". |path| may be // system-absolute, source-absolute, or relative. If |path| is source-absolute // and |source_root| is non-empty, |path| may be system absolute after this
diff --git a/tools/gn/filesystem_utils_unittest.cc b/tools/gn/filesystem_utils_unittest.cc index f5724c43..03ec7809 100644 --- a/tools/gn/filesystem_utils_unittest.cc +++ b/tools/gn/filesystem_utils_unittest.cc
@@ -173,6 +173,43 @@ #endif } +TEST(FilesystemUtils, MakeAbsoluteFilePathRelativeIfPossible) { +#if defined(OS_WIN) + EXPECT_EQ( + base::FilePath(L"out\\Debug"), + MakeAbsoluteFilePathRelativeIfPossible( + base::FilePath(L"C:\\src"), base::FilePath(L"C:\\src\\out\\Debug"))); + EXPECT_EQ( + base::FilePath(L"..\\.."), + MakeAbsoluteFilePathRelativeIfPossible( + base::FilePath(L"C:\\src\\out\\Debug"), base::FilePath(L"C:\\src"))); + EXPECT_EQ(base::FilePath(L"."), + MakeAbsoluteFilePathRelativeIfPossible(base::FilePath(L"C:\\src"), + base::FilePath(L"C:\\src"))); + EXPECT_EQ(base::FilePath(L"..\\..\\..\\u\\v\\w"), + MakeAbsoluteFilePathRelativeIfPossible( + base::FilePath(L"C:\\a\\b\\c\\x\\y\\z"), + base::FilePath(L"C:\\a\\b\\c\\u\\v\\w"))); + EXPECT_EQ(base::FilePath(L"D:\\bar"), + MakeAbsoluteFilePathRelativeIfPossible(base::FilePath(L"C:\\foo"), + base::FilePath(L"D:\\bar"))); +#else + EXPECT_EQ(base::FilePath("out/Debug"), + MakeAbsoluteFilePathRelativeIfPossible( + base::FilePath("/src"), base::FilePath("/src/out/Debug"))); + EXPECT_EQ(base::FilePath("../.."), + MakeAbsoluteFilePathRelativeIfPossible( + base::FilePath("/src/out/Debug"), base::FilePath("/src"))); + EXPECT_EQ(base::FilePath("."), + MakeAbsoluteFilePathRelativeIfPossible(base::FilePath("/src"), + base::FilePath("/src"))); + EXPECT_EQ( + base::FilePath("../../../u/v/w"), + MakeAbsoluteFilePathRelativeIfPossible(base::FilePath("/a/b/c/x/y/z"), + base::FilePath("/a/b/c/u/v/w"))); +#endif +} + TEST(FilesystemUtils, NormalizePath) { std::string input;
diff --git a/tools/gn/ninja_build_writer.cc b/tools/gn/ninja_build_writer.cc index 4ee3f6043..334071a6 100644 --- a/tools/gn/ninja_build_writer.cc +++ b/tools/gn/ninja_build_writer.cc
@@ -48,10 +48,15 @@ }; std::string GetSelfInvocationCommand(const BuildSettings* build_settings) { - base::FilePath executable; - PathService::Get(base::FILE_EXE, &executable); + const base::FilePath build_path = + build_settings->build_dir().Resolve(build_settings->root_path()); - base::CommandLine cmdline(executable.NormalizePathSeparatorsTo('/')); + base::FilePath exe_path; + PathService::Get(base::FILE_EXE, &exe_path); + if (build_path.IsAbsolute()) + exe_path = MakeAbsoluteFilePathRelativeIfPossible(build_path, exe_path); + + base::CommandLine cmdline(exe_path.NormalizePathSeparatorsTo('/')); // Use "." for the directory to generate. When Ninja runs the command it // will have the build directory as the current one. Coding it explicitly @@ -59,8 +64,12 @@ cmdline.AppendArg("gen"); cmdline.AppendArg("."); + base::FilePath root_path = build_settings->root_path(); + if (build_path.IsAbsolute()) + root_path = MakeAbsoluteFilePathRelativeIfPossible(build_path, root_path); + cmdline.AppendSwitchPath(std::string("--") + switches::kRoot, - build_settings->root_path()); + root_path.NormalizePathSeparatorsTo('/')); // Successful automatic invocations shouldn't print output. cmdline.AppendSwitch(std::string("-") + switches::kQuiet); @@ -267,8 +276,13 @@ std::set<base::FilePath> fileset(input_files.begin(), input_files.end()); fileset.insert(other_files.begin(), other_files.end()); - for (const auto& other_file : fileset) - dep_out_ << " " << FilePathToUTF8(other_file); + const base::FilePath build_path = + build_settings_->build_dir().Resolve(build_settings_->root_path()); + for (const auto& other_file : fileset) { + const base::FilePath file = + MakeAbsoluteFilePathRelativeIfPossible(build_path, other_file); + dep_out_ << " " << FilePathToUTF8(file.NormalizePathSeparatorsTo('/')); + } out_ << std::endl; }
diff --git a/tools/grit/grit/format/data_pack.py b/tools/grit/grit/format/data_pack.py index 075899c..6037dc60 100755 --- a/tools/grit/grit/format/data_pack.py +++ b/tools/grit/grit/format/data_pack.py
@@ -73,17 +73,19 @@ def Format(root, lang='en', output_dir='.'): """Writes out the data pack file format (platform agnostic resource file).""" + id_map = root.GetIdMap() data = {} root.info = [] for node in root.ActiveDescendants(): with node: if isinstance(node, (include.IncludeNode, message.MessageNode, structure.StructureNode)): - id, value = node.GetDataPackPair(lang, UTF8) + value = node.GetDataPackValue(lang, UTF8) if value is not None: - data[id] = value - root.info.append( - '{},{},{}'.format(node.attrs.get('name'), id, node.source)) + resource_id = id_map[node.GetTextualIds()[0]] + data[resource_id] = value + root.info.append('{},{},{}'.format( + node.attrs.get('name'), resource_id, node.source)) return WriteDataPackToString(data, UTF8)
diff --git a/tools/grit/grit/format/gzip_string_unittest.py b/tools/grit/grit/format/gzip_string_unittest.py old mode 100644 new mode 100755 index 8df8b3b..a920693 --- a/tools/grit/grit/format/gzip_string_unittest.py +++ b/tools/grit/grit/format/gzip_string_unittest.py
@@ -1,3 +1,4 @@ +#!/usr/bin/env python # Copyright (c) 2016 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/grit/grit/format/rc.py b/tools/grit/grit/format/rc.py index bd3de1a..5dfeb03 100755 --- a/tools/grit/grit/format/rc.py +++ b/tools/grit/grit/format/rc.py
@@ -12,7 +12,6 @@ from functools import partial from grit import util -from grit.format import rc_header from grit.node import misc @@ -442,7 +441,7 @@ return '' name = item.attrs['name'] - item_id = rc_header.GetIds(item.GetRoot())[name] + item_id = item.GetRoot().GetIdMap()[name] return '// ID: %d\n%-18s %-18s "%s"\n' % (item_id, name, type, filename)
diff --git a/tools/grit/grit/format/rc_header.py b/tools/grit/grit/format/rc_header.py index 7b02122..cea0cad 100755 --- a/tools/grit/grit/format/rc_header.py +++ b/tools/grit/grit/format/rc_header.py
@@ -6,9 +6,7 @@ '''Item formatters for RC headers. ''' -from grit import exception -from grit import util -from grit.extern import FP +from grit.node import message def Format(root, lang='en', output_dir='.'): @@ -44,13 +42,11 @@ output_all_resource_defines: If False, output only the symbols used in the current output configuration. ''' - from grit.node import message - tids = GetIds(root) - if output_all_resource_defines: items = root.Preorder() else: items = root.ActiveDescendants() + tids = root.GetIdMap() if not rc_header_format: rc_header_format = "#define {textual_id} {numeric_id}" @@ -74,164 +70,3 @@ if tid in tids and tid not in seen: seen.add(tid) yield rc_header_format.format(textual_id=tid,numeric_id=tids[tid]) - - -_cached_ids = {} - - -_predetermined_tids = {} - - -def SetPredeterminedIdsFile(predetermined_ids_file): - global _predetermined_tids - if predetermined_ids_file: - _predetermined_tids = _ReadIdsFromFile(predetermined_ids_file) - else: - _predetermined_tids = {} - - -def _ReadIdsFromFile(path): - with open(path, "r") as f: - content = f.readlines() - tids = {} # Maps textual id to numeric id - for line in content: - tid, id = line.split() - tids[tid] = int(id) - return tids - - -def GetIds(root): - '''Return a dictionary mapping textual ids to numeric ids for the given tree. - - Args: - root: A GritNode. - ''' - global _cached_ids - global _predetermined_tids - # TODO(benrg): Since other formatters use this, it might make sense to move it - # and _ComputeIds to GritNode and store the cached ids as an attribute. On the - # other hand, GritNode has too much random stuff already. - if root not in _cached_ids: - _cached_ids[root] = _ComputeIds(root, _predetermined_tids) - return _cached_ids[root] - - -def _ComputeIds(root, predetermined_tids): - from grit.node import empty, include, message, misc, structure - - ids = {} # Maps numeric id to textual id - tids = {} # Maps textual id to numeric id - id_reasons = {} # Maps numeric id to text id and a human-readable explanation - group = None - last_id = None - predetermined_ids = {value: key - for key, value in predetermined_tids.iteritems()} - - for item in root: - if isinstance(item, empty.GroupingNode): - # Note: this won't work if any GroupingNode can be contained inside - # another. - group = item - last_id = None - continue - - assert not item.GetTextualIds() or isinstance(item, - (include.IncludeNode, message.MessageNode, - misc.IdentifierNode, structure.StructureNode)) - - # Resources that use the RES protocol don't need - # any numerical ids generated, so we skip them altogether. - # This is accomplished by setting the flag 'generateid' to false - # in the GRD file. - if item.attrs.get('generateid', 'true') == 'false': - continue - - for tid in item.GetTextualIds(): - if util.SYSTEM_IDENTIFIERS.match(tid): - # Don't emit a new ID for predefined IDs - continue - - if tid in tids: - continue - - if predetermined_tids and tid in predetermined_tids: - id = predetermined_tids[tid] - reason = "from predetermined_tids map" - - # Some identifier nodes can provide their own id, - # and we use that id in the generated header in that case. - elif hasattr(item, 'GetId') and item.GetId(): - id = long(item.GetId()) - reason = 'returned by GetId() method' - - elif ('offset' in item.attrs and group and - group.attrs.get('first_id', '') != ''): - offset_text = item.attrs['offset'] - parent_text = group.attrs['first_id'] - - try: - offset_id = long(offset_text) - except ValueError: - offset_id = tids[offset_text] - - try: - parent_id = long(parent_text) - except ValueError: - parent_id = tids[parent_text] - - id = parent_id + offset_id - reason = 'first_id %d + offset %d' % (parent_id, offset_id) - - # We try to allocate IDs sequentially for blocks of items that might - # be related, for instance strings in a stringtable (as their IDs might be - # used e.g. as IDs for some radio buttons, in which case the IDs must - # be sequential). - # - # We do this by having the first item in a section store its computed ID - # (computed from a fingerprint) in its parent object. Subsequent children - # of the same parent will then try to get IDs that sequentially follow - # the currently stored ID (on the parent) and increment it. - elif last_id is None: - # First check if the starting ID is explicitly specified by the parent. - if group and group.attrs.get('first_id', '') != '': - id = long(group.attrs['first_id']) - reason = "from parent's first_id attribute" - else: - # Automatically generate the ID based on the first clique from the - # first child of the first child node of our parent (i.e. when we - # first get to this location in the code). - - # According to - # http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx - # the safe usable range for resource IDs in Windows is from decimal - # 101 to 0x7FFF. - - id = FP.UnsignedFingerPrint(tid) - id = id % (0x7FFF - 101) + 101 - reason = 'chosen by random fingerprint -- use first_id to override' - - last_id = id - else: - id = last_id = last_id + 1 - reason = 'sequentially assigned' - - reason = "%s (%s)" % (tid, reason) - # Don't fail when 'offset' is specified, as the base and the 0th - # offset will have the same ID. - if id in id_reasons and not 'offset' in item.attrs: - raise exception.IdRangeOverlap('ID %d was assigned to both %s and %s.' - % (id, id_reasons[id], reason)) - - if id < 101: - print ('WARNING: Numeric resource IDs should be greater than 100 to\n' - 'avoid conflicts with system-defined resource IDs.') - - if tid not in predetermined_tids and id in predetermined_ids: - raise exception.IdRangeOverlap('ID %d overlaps between %s and %s' - % (id, tid, predetermined_ids[tid])) - - ids[id] = tid - tids[tid] = id - id_reasons[id] = reason - - return tids
diff --git a/tools/grit/grit/format/rc_header_unittest.py b/tools/grit/grit/format/rc_header_unittest.py index 22c5f38..3cba963 100755 --- a/tools/grit/grit/format/rc_header_unittest.py +++ b/tools/grit/grit/format/rc_header_unittest.py
@@ -10,13 +10,11 @@ import os import sys -import tempfile +import unittest + if __name__ == '__main__': sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) -import StringIO -import unittest - from grit import exception from grit import grd_reader from grit import util @@ -28,71 +26,55 @@ output = rc_header.FormatDefines(grd, grd.ShouldOutputAllResourceDefines()) return ''.join(output).replace(' ', '') - def _MakeTempPredeterminedIdsFile(self, content): - tmp_dir = tempfile.gettempdir() - predetermined_ids_file = tmp_dir + "/predetermined_ids.txt" - with open(predetermined_ids_file, 'w') as f: - f.write(content) - return predetermined_ids_file - def testFormatter(self): - grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> - <release seq="3"> - <includes first_id="300" comment="bingo"> - <include type="gif" name="ID_LOGO" file="images/logo.gif" /> - </includes> - <messages first_id="10000"> - <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> - Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? - </message> - <message name="IDS_BONGO"> - Bongo! - </message> - </messages> - <structures> - <structure type="dialog" name="IDD_NARROW_DIALOG" file="rc_files/dialogs.rc" /> - <structure type="version" name="VS_VERSION_INFO" file="rc_files/version.rc" /> - </structures> - </release> - </grit>'''), '.') + grd = util.ParseGrdForUnittest(''' + <includes first_id="300" comment="bingo"> + <include type="gif" name="ID_LOGO" file="images/logo.gif" /> + </includes> + <messages first_id="10000"> + <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> + Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? + </message> + <message name="IDS_BONGO"> + Bongo! + </message> + </messages> + <structures> + <structure type="dialog" name="IDD_NARROW_DIALOG" file="rc_files/dialogs.rc" /> + <structure type="version" name="VS_VERSION_INFO" file="rc_files/version.rc" /> + </structures>''') output = self.FormatAll(grd) self.failUnless(output.count('IDS_GREETING10000')) self.failUnless(output.count('ID_LOGO300')) def testOnlyDefineResourcesThatSatisfyOutputCondition(self): - grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" - base_dir="." output_all_resource_defines="false"> - <release seq="3"> - <includes first_id="300" comment="bingo"> - <include type="gif" name="ID_LOGO" file="images/logo.gif" /> - </includes> - <messages first_id="10000"> - <message name="IDS_FIRSTPRESENTSTRING" desc="Present in .rc file."> - I will appear in the .rc file. + grd = util.ParseGrdForUnittest(''' + <includes first_id="300" comment="bingo"> + <include type="gif" name="ID_LOGO" file="images/logo.gif" /> + </includes> + <messages first_id="10000"> + <message name="IDS_FIRSTPRESENTSTRING" desc="Present in .rc file."> + I will appear in the .rc file. + </message> + <if expr="False"> <!--Do not include in the .rc files until used.--> + <message name="IDS_MISSINGSTRING" desc="Not present in .rc file."> + I will not appear in the .rc file. </message> - <if expr="False"> <!--Do not include in the .rc files until used.--> - <message name="IDS_MISSINGSTRING" desc="Not present in .rc file."> - I will not appear in the .rc file. - </message> - </if> - <if expr="lang != 'es'"> - <message name="IDS_LANGUAGESPECIFICSTRING" desc="Present in .rc file."> - Hello. - </message> - </if> - <if expr="lang == 'es'"> - <message name="IDS_LANGUAGESPECIFICSTRING" desc="Present in .rc file."> - Hola. - </message> - </if> - <message name="IDS_THIRDPRESENTSTRING" desc="Present in .rc file."> - I will also appear in the .rc file. + </if> + <if expr="lang != 'es'"> + <message name="IDS_LANGUAGESPECIFICSTRING" desc="Present in .rc file."> + Hello. </message> - </messages> - </release> - </grit>'''), '.') + </if> + <if expr="lang == 'es'"> + <message name="IDS_LANGUAGESPECIFICSTRING" desc="Present in .rc file."> + Hola. + </message> + </if> + <message name="IDS_THIRDPRESENTSTRING" desc="Present in .rc file."> + I will also appear in the .rc file. + </message> + </messages>''') output = self.FormatAll(grd) self.failUnless(output.count('IDS_FIRSTPRESENTSTRING10000')) self.failIf(output.count('IDS_MISSINGSTRING')) @@ -100,47 +82,8 @@ self.failUnless(output.count('IDS_LANGUAGESPECIFICSTRING10002')) self.failUnless(output.count('IDS_THIRDPRESENTSTRING10003')) - def testExplicitFirstIdOverlaps(self): - # second first_id will overlap preexisting range - grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> - <release seq="3"> - <includes first_id="300" comment="bingo"> - <include type="gif" name="ID_LOGO" file="images/logo.gif" /> - <include type="gif" name="ID_LOGO2" file="images/logo2.gif" /> - </includes> - <messages first_id="301"> - <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> - Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? - </message> - <message name="IDS_SMURFGEBURF">Frubegfrums</message> - </messages> - </release> - </grit>'''), '.') - self.assertRaises(exception.IdRangeOverlap, self.FormatAll, grd) - - def testImplicitOverlapsPreexisting(self): - # second message in <messages> will overlap preexisting range - grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> - <release seq="3"> - <includes first_id="301" comment="bingo"> - <include type="gif" name="ID_LOGO" file="images/logo.gif" /> - <include type="gif" name="ID_LOGO2" file="images/logo2.gif" /> - </includes> - <messages first_id="300"> - <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> - Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? - </message> - <message name="IDS_SMURFGEBURF">Frubegfrums</message> - </messages> - </release> - </grit>'''), '.') - self.assertRaises(exception.IdRangeOverlap, self.FormatAll, grd) - def testEmit(self): - grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> + grd = util.ParseGrdForUnittest(''' <outputs> <output type="rc_all" filename="dummy"> <emit emit_type="prepend">Wrong</emit> @@ -156,29 +99,24 @@ <output type="rc_header" filename="dummy"> <emit emit_type="prepend">Bingo</emit> </output> - </outputs> - </grit>'''), '.') + </outputs>''') output = ''.join(rc_header.Format(grd, 'en', '.')) output = util.StripBlankLinesAndComments(output) self.assertEqual('#pragma once\nBingo', output) def testRcHeaderFormat(self): - grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> - <release seq="3"> - <includes first_id="300" comment="bingo"> - <include type="gif" name="IDR_LOGO" file="images/logo.gif" /> - </includes> - <messages first_id="10000"> - <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> - Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? - </message> - <message name="IDS_BONGO"> - Bongo! - </message> - </messages> - </release> - </grit>'''), '.') + grd = util.ParseGrdForUnittest(''' + <includes first_id="300" comment="bingo"> + <include type="gif" name="IDR_LOGO" file="images/logo.gif" /> + </includes> + <messages first_id="10000"> + <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> + Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? + </message> + <message name="IDS_BONGO"> + Bongo! + </message> + </messages>''') # Using the default rc_header format string. output = rc_header.FormatDefines(grd, grd.ShouldOutputAllResourceDefines(), @@ -197,53 +135,5 @@ '#define IDS_BONGO _Pragma("IDS_BONGO") 10001\n'), ''.join(output)) - def testPredeterminedIds(self): - predetermined_ids_file = self._MakeTempPredeterminedIdsFile( - 'IDS_BONGO 101\nID_LOGO 102\n') - grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> - <release seq="3"> - <includes first_id="300" comment="bingo"> - <include type="gif" name="ID_LOGO" file="images/logo.gif" /> - </includes> - <messages first_id="10000"> - <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> - Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? - </message> - <message name="IDS_BONGO"> - Bongo! - </message> - </messages> - </release> - </grit>'''), '.', predetermined_ids_file=predetermined_ids_file) - output = rc_header.FormatDefines(grd, grd.ShouldOutputAllResourceDefines(), - grd.GetRcHeaderFormat()) - self.assertEqual(('#define ID_LOGO 102\n' - '#define IDS_GREETING 10000\n' - '#define IDS_BONGO 101\n'), ''.join(output)) - - def testPredeterminedIdsOverlap(self): - predetermined_ids_file = self._MakeTempPredeterminedIdsFile( - 'ID_LOGO 10000\n') - grd = grd_reader.Parse(StringIO.StringIO('''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" base_dir="."> - <release seq="3"> - <includes first_id="300" comment="bingo"> - <include type="gif" name="ID_LOGO" file="images/logo.gif" /> - </includes> - <messages first_id="10000"> - <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> - Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? - </message> - <message name="IDS_BONGO"> - Bongo! - </message> - </messages> - </release> - </grit>'''), '.', predetermined_ids_file=predetermined_ids_file) - output = rc_header.FormatDefines(grd, grd.ShouldOutputAllResourceDefines(), - grd.GetRcHeaderFormat()) - self.assertRaises(exception.IdRangeOverlap, self.FormatAll, grd) - if __name__ == '__main__': unittest.main()
diff --git a/tools/grit/grit/format/resource_map.py b/tools/grit/grit/format/resource_map.py index f1e3132..eb163ed 100755 --- a/tools/grit/grit/format/resource_map.py +++ b/tools/grit/grit/format/resource_map.py
@@ -108,10 +108,9 @@ def _FormatSource(get_key, root, lang, output_dir): - from grit.format import rc_header from grit.node import include, structure, message + id_map = root.GetIdMap() yield _FormatSourceHeader(root, output_dir) - tids = rc_header.GetIds(root) seen = set() active_descendants = [item for item in root.ActiveDescendants()] output_all_resource_defines = root.ShouldOutputAllResourceDefines() @@ -120,7 +119,7 @@ continue key = get_key(item) tid = item.attrs['name'] - if tid not in tids or key in seen: + if tid not in id_map or key in seen: continue if item.GeneratesResourceMapEntry(output_all_resource_defines, item in active_descendants):
diff --git a/tools/grit/grit/format/resource_map_unittest.py b/tools/grit/grit/format/resource_map_unittest.py index 31d481e..939341c 100755 --- a/tools/grit/grit/format/resource_map_unittest.py +++ b/tools/grit/grit/format/resource_map_unittest.py
@@ -10,7 +10,6 @@ if __name__ == '__main__': sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) -import StringIO import unittest from grit import grd_reader @@ -20,10 +19,7 @@ class FormatResourceMapUnittest(unittest.TestCase): def testFormatResourceMap(self): - grd = grd_reader.Parse(StringIO.StringIO( - '''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" - base_dir="."> + grd = util.ParseGrdForUnittest(''' <outputs> <output type="rc_header" filename="the_rc_header.h" /> <output type="resource_map_header" @@ -47,10 +43,7 @@ </if> <include type="foo" file="mno" name="IDS_THIRDPRESENT" /> </includes> - </release> - </grit>'''), util.PathFromRoot('.')) - grd.SetOutputLanguage('en') - grd.RunGatherers() + </release>''', run_gatherers=True) output = util.StripBlankLinesAndComments(''.join( resource_map.GetFormatter('resource_map_header')(grd, 'en', '.'))) self.assertEqual('''\ @@ -97,10 +90,7 @@ const size_t kTheRcHeaderSize = arraysize(kTheRcHeader);''', output) def testFormatResourceMapWithOutputAllEqualsFalseForStructures(self): - grd = grd_reader.Parse(StringIO.StringIO( - '''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" - base_dir="." output_all_resource_defines="false"> + grd = util.ParseGrdForUnittest(''' <outputs> <output type="rc_header" filename="the_rc_header.h" /> <output type="resource_map_header" @@ -139,10 +129,7 @@ file="xyz.png" /> </if> </structures> - </release> - </grit>'''), util.PathFromRoot('.')) - grd.SetOutputLanguage('en') - grd.RunGatherers() + </release>''', run_gatherers=True, output_all_resource_defines=False) output = util.StripBlankLinesAndComments(''.join( resource_map.GetFormatter('resource_map_header')(grd, 'en', '.'))) self.assertEqual('''\ @@ -186,10 +173,7 @@ const size_t kTheRcHeaderSize = arraysize(kTheRcHeader);''', output) def testFormatResourceMapWithOutputAllEqualsFalseForIncludes(self): - grd = grd_reader.Parse(StringIO.StringIO( - '''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" - base_dir="." output_all_resource_defines="false"> + grd = util.ParseGrdForUnittest(''' <outputs> <output type="rc_header" filename="the_rc_header.h" /> <output type="resource_map_header" @@ -224,10 +208,7 @@ <include type="foo" file="xyz" name="IDS_LAST" /> </if> </includes> - </release> - </grit>'''), util.PathFromRoot('.')) - grd.SetOutputLanguage('en') - grd.RunGatherers() + </release>''', run_gatherers=True, output_all_resource_defines=False) output = util.StripBlankLinesAndComments(''.join( resource_map.GetFormatter('resource_map_header')(grd, 'en', '.'))) self.assertEqual('''\ @@ -275,10 +256,7 @@ const size_t kTheRcHeaderSize = arraysize(kTheRcHeader);''', output) def testFormatStringResourceMap(self): - grd = grd_reader.Parse(StringIO.StringIO( - '''<?xml version="1.0" encoding="UTF-8"?> - <grit latest_public_release="2" source_lang_id="en" current_release="3" - base_dir="."> + grd = util.ParseGrdForUnittest(''' <outputs> <output type="rc_header" filename="the_rc_header.h" /> <output type="resource_map_header" filename="the_rc_map_header.h" /> @@ -302,10 +280,7 @@ </message> </if> </messages> - </release> - </grit>'''), util.PathFromRoot('.')) - grd.SetOutputLanguage('en') - grd.RunGatherers() + </release>''', run_gatherers=True, output_all_resource_defines=False) output = util.StripBlankLinesAndComments(''.join( resource_map.GetFormatter('resource_map_header')(grd, 'en', '.'))) self.assertEqual('''\
diff --git a/tools/grit/grit/grd_reader.py b/tools/grit/grit/grd_reader.py index fb33e9c7..733dc23 100755 --- a/tools/grit/grit/grd_reader.py +++ b/tools/grit/grit/grd_reader.py
@@ -13,7 +13,6 @@ from grit import exception from grit import util -from grit.format import rc_header from grit.node import base from grit.node import mapping from grit.node import misc @@ -192,7 +191,6 @@ else: source = None - rc_header.SetPredeterminedIdsFile(predetermined_ids_file) handler = GrdContentHandler(stop_after=stop_after, debug=debug, dir=dir, defines=defines, tags_to_ignore=tags_to_ignore, target_platform=target_platform, source=source) @@ -215,6 +213,7 @@ handler.root.SetOwnDir(dir) if isinstance(handler.root, misc.GritNode): + handler.root.SetPredeterminedIdsFile(predetermined_ids_file) if first_ids_file: # Make the path to the first_ids_file relative to the grd file, # unless it begins with GRIT_DIR.
diff --git a/tools/grit/grit/node/include.py b/tools/grit/grit/node/include.py index 5787e6e1..3ebdcf61 100755 --- a/tools/grit/grit/node/include.py +++ b/tools/grit/grit/node/include.py
@@ -12,7 +12,6 @@ from grit import util import grit.format.html_inline import grit.format.rc -import grit.format.rc_header from grit.format import minifier from grit.node import base @@ -77,15 +76,8 @@ return self.ToRealPath(input_path) - def GetDataPackPair(self, lang, encoding): - """Returns a (id, string) pair that represents the resource id and raw - bytes of the data. This is used to generate the data pack data file. - """ - # TODO(benrg/joi): Move this and other implementations of GetDataPackPair - # to grit.format.data_pack? - from grit.format import rc_header - id_map = rc_header.GetIds(self.GetRoot()) - id = id_map[self.GetTextualIds()[0]] + def GetDataPackValue(self, lang, encoding): + '''Returns a str represenation for a data_pack entry.''' filename = self.ToRealPath(self.GetInputPath()) if self.attrs['flattenhtml'] == 'true': allow_external_script = self.attrs['allowexternalscript'] == 'true' @@ -98,7 +90,7 @@ # Include does not care about the encoding, because it only returns binary # data. - return id, self.CompressDataIfNeeded(data) + return self.CompressDataIfNeeded(data) def Process(self, output_dir): """Rewrite file references to be base64 encoded data URLs. The new file
diff --git a/tools/grit/grit/node/include_unittest.py b/tools/grit/grit/node/include_unittest.py index 031c1bfa..3bf1a6891 100755 --- a/tools/grit/grit/node/include_unittest.py +++ b/tools/grit/grit/node/include_unittest.py
@@ -76,7 +76,7 @@ compress="gzip" type="BINDATA"/> </includes>''', base_dir = util.PathFromRoot('grit/testdata')) inc, = root.GetChildrenOfType(include.IncludeNode) - throwaway, compressed = inc.GetDataPackPair(lang='en', encoding=1) + compressed = inc.GetDataPackValue(lang='en', encoding=1) decompressed_data = zlib.decompress(compressed, 16 + zlib.MAX_WBITS) self.assertEqual(util.ReadFile(util.PathFromRoot('grit/testdata')
diff --git a/tools/grit/grit/node/message.py b/tools/grit/grit/node/message.py index e3024fb..b8eca3e 100755 --- a/tools/grit/grit/node/message.py +++ b/tools/grit/grit/node/message.py
@@ -223,17 +223,10 @@ '''We always expand variables on Messages.''' return True - def GetDataPackPair(self, lang, encoding): - '''Returns a (id, string) pair that represents the string id and the string - in the specified encoding, where |encoding| is one of the encoding values - accepted by util.Encode. This is used to generate the data pack data file. - ''' - from grit.format import rc_header - id_map = rc_header.GetIds(self.GetRoot()) - id = id_map[self.GetTextualIds()[0]] - + def GetDataPackValue(self, lang, encoding): + '''Returns a str represenation for a data_pack entry.''' message = self.ws_at_start + self.Translate(lang) + self.ws_at_end - return id, util.Encode(message, encoding) + return util.Encode(message, encoding) def IsResourceMapSource(self): return True
diff --git a/tools/grit/grit/node/misc.py b/tools/grit/grit/node/misc.py index bd999709b..7cff4930 100755 --- a/tools/grit/grit/node/misc.py +++ b/tools/grit/grit/node/misc.py
@@ -13,6 +13,7 @@ from grit import constants from grit import exception from grit import util +from grit.extern import FP import grit.format.rc_header from grit.node import base from grit.node import io @@ -72,6 +73,138 @@ return (src_root_dir, first_ids_dict) +def _ComputeIds(root, predetermined_tids): + """Returns a dict of textual id -> numeric id for all nodes in root. + + IDs are mostly assigned sequentially, but will vary based on: + * first_id node attribute (from first_ids_file) + * hash of textual id (if not first_id is defined) + * offset node attribute + * whether the textual id matches a system id + * whether the node generates its own ID via GetId() + + Args: + predetermined_tids: Dict of textual id -> numeric id to use in return dict. + """ + from grit.node import empty, include, message, misc, structure + + ids = {} # Maps numeric id to textual id + tids = {} # Maps textual id to numeric id + id_reasons = {} # Maps numeric id to text id and a human-readable explanation + group = None + last_id = None + predetermined_ids = {value: key + for key, value in predetermined_tids.iteritems()} + + for item in root: + if isinstance(item, empty.GroupingNode): + # Note: this won't work if any GroupingNode can be contained inside + # another. + group = item + last_id = None + continue + + assert not item.GetTextualIds() or isinstance(item, + (include.IncludeNode, message.MessageNode, + misc.IdentifierNode, structure.StructureNode)) + + # Resources that use the RES protocol don't need + # any numerical ids generated, so we skip them altogether. + # This is accomplished by setting the flag 'generateid' to false + # in the GRD file. + if item.attrs.get('generateid', 'true') == 'false': + continue + + for tid in item.GetTextualIds(): + if util.SYSTEM_IDENTIFIERS.match(tid): + # Don't emit a new ID for predefined IDs + continue + + if tid in tids: + continue + + if predetermined_tids and tid in predetermined_tids: + id = predetermined_tids[tid] + reason = "from predetermined_tids map" + + # Some identifier nodes can provide their own id, + # and we use that id in the generated header in that case. + elif hasattr(item, 'GetId') and item.GetId(): + id = long(item.GetId()) + reason = 'returned by GetId() method' + + elif ('offset' in item.attrs and group and + group.attrs.get('first_id', '') != ''): + offset_text = item.attrs['offset'] + parent_text = group.attrs['first_id'] + + try: + offset_id = long(offset_text) + except ValueError: + offset_id = tids[offset_text] + + try: + parent_id = long(parent_text) + except ValueError: + parent_id = tids[parent_text] + + id = parent_id + offset_id + reason = 'first_id %d + offset %d' % (parent_id, offset_id) + + # We try to allocate IDs sequentially for blocks of items that might + # be related, for instance strings in a stringtable (as their IDs might be + # used e.g. as IDs for some radio buttons, in which case the IDs must + # be sequential). + # + # We do this by having the first item in a section store its computed ID + # (computed from a fingerprint) in its parent object. Subsequent children + # of the same parent will then try to get IDs that sequentially follow + # the currently stored ID (on the parent) and increment it. + elif last_id is None: + # First check if the starting ID is explicitly specified by the parent. + if group and group.attrs.get('first_id', '') != '': + id = long(group.attrs['first_id']) + reason = "from parent's first_id attribute" + else: + # Automatically generate the ID based on the first clique from the + # first child of the first child node of our parent (i.e. when we + # first get to this location in the code). + + # According to + # http://msdn.microsoft.com/en-us/library/t2zechd4(VS.71).aspx + # the safe usable range for resource IDs in Windows is from decimal + # 101 to 0x7FFF. + + id = FP.UnsignedFingerPrint(tid) + id = id % (0x7FFF - 101) + 101 + reason = 'chosen by random fingerprint -- use first_id to override' + + last_id = id + else: + id = last_id = last_id + 1 + reason = 'sequentially assigned' + + reason = "%s (%s)" % (tid, reason) + # Don't fail when 'offset' is specified, as the base and the 0th + # offset will have the same ID. + if id in id_reasons and not 'offset' in item.attrs: + raise exception.IdRangeOverlap('ID %d was assigned to both %s and %s.' + % (id, id_reasons[id], reason)) + + if id < 101: + print ('WARNING: Numeric resource IDs should be greater than 100 to\n' + 'avoid conflicts with system-defined resource IDs.') + + if tid not in predetermined_tids and id in predetermined_ids: + raise exception.IdRangeOverlap('ID %d overlaps between %s and %s' + % (id, tid, predetermined_ids[tid])) + + ids[id] = tid + tids[tid] = id + id_reasons[id] = reason + + return tids + class SplicingNode(base.Node): """A node whose children should be considered to be at the same level as its siblings for most purposes. This includes <if> and <part> nodes. @@ -172,6 +305,8 @@ self.defines = {} self.substituter = None self.target_platform = sys.platform + self._predetermined_ids_file = None + self._id_map = None # Dict of textual_id -> numeric_id. def _IsValidChild(self, child): from grit.node import empty @@ -442,6 +577,7 @@ """Assign first ids to each grouping node based on values from the first_ids file (if specified on the <grit> node). """ + assert self._id_map is None, 'AssignFirstIds() after InitializeIds()' # If the input is a stream, then we're probably in a unit test and # should skip this step. if type(filename_or_stream) not in (str, unicode): @@ -487,6 +623,25 @@ raise Exception('Please update %s and add a first id for %s (%s).' % (first_ids_filename, filename, node.name)) + def GetIdMap(self): + '''Return a dictionary mapping textual ids to numeric ids.''' + return self._id_map + + def SetPredeterminedIdsFile(self, predetermined_ids_file): + assert self._id_map is None, ( + 'SetPredeterminedIdsFile() after InitializeIds()') + self._predetermined_ids_file = predetermined_ids_file + + def InitializeIds(self): + '''Initializes the text ID -> numeric ID mapping.''' + predetermined_id_map = {} + if self._predetermined_ids_file: + with open(self._predetermined_ids_file) as f: + for line in f: + tid, nid = line.split() + predetermined_id_map[tid] = int(nid) + self._id_map = _ComputeIds(self, predetermined_id_map) + def RunGatherers(self, debug=False): '''Call RunPreSubstitutionGatherer() on every node of the tree, then apply substitutions, then call RunPostSubstitutionGatherer() on every node.
diff --git a/tools/grit/grit/node/misc_unittest.py b/tools/grit/grit/node/misc_unittest.py index 005cbf6..0589631 100755 --- a/tools/grit/grit/node/misc_unittest.py +++ b/tools/grit/grit/node/misc_unittest.py
@@ -6,21 +6,32 @@ '''Unit tests for misc.GritNode''' +import StringIO +import contextlib import os import sys +import tempfile +import unittest + if __name__ == '__main__': sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) -import unittest -import StringIO - from grit import grd_reader import grit.exception from grit import util from grit.format import rc +from grit.format import rc_header from grit.node import misc +@contextlib.contextmanager +def _MakeTempPredeterminedIdsFile(content): + with tempfile.NamedTemporaryFile() as f: + f.write(content) + f.flush() + yield f.name + + class GritNodeUnittest(unittest.TestCase): def testUniqueNameAttribute(self): try: @@ -106,6 +117,83 @@ actual = [path.replace('\\', '/') for path in actual] self.assertEquals(expected, actual) + def testNonDefaultEntry(self): + grd = util.ParseGrdForUnittest(''' + <messages> + <message name="IDS_A" desc="foo">bar</message> + <if expr="lang == 'fr'"> + <message name="IDS_B" desc="foo">bar</message> + </if> + </messages>''') + grd.SetOutputLanguage('fr') + output = ''.join(rc_header.Format(grd, 'fr', '.')) + self.assertIn('#define IDS_A 2378\n#define IDS_B 2379', output) + + def testExplicitFirstIdOverlaps(self): + # second first_id will overlap preexisting range + self.assertRaises(grit.exception.IdRangeOverlap, + util.ParseGrdForUnittest, ''' + <includes first_id="300" comment="bingo"> + <include type="gif" name="ID_LOGO" file="images/logo.gif" /> + <include type="gif" name="ID_LOGO2" file="images/logo2.gif" /> + </includes> + <messages first_id="301"> + <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> + Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? + </message> + <message name="IDS_SMURFGEBURF">Frubegfrums</message> + </messages>''') + + def testImplicitOverlapsPreexisting(self): + # second message in <messages> will overlap preexisting range + self.assertRaises(grit.exception.IdRangeOverlap, + util.ParseGrdForUnittest, ''' + <includes first_id="301" comment="bingo"> + <include type="gif" name="ID_LOGO" file="images/logo.gif" /> + <include type="gif" name="ID_LOGO2" file="images/logo2.gif" /> + </includes> + <messages first_id="300"> + <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> + Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? + </message> + <message name="IDS_SMURFGEBURF">Frubegfrums</message> + </messages>''') + + def testPredeterminedIds(self): + with _MakeTempPredeterminedIdsFile('IDS_A 101\nIDS_B 102') as ids_file: + grd = util.ParseGrdForUnittest(''' + <includes first_id="300" comment="bingo"> + <include type="gif" name="IDS_B" file="images/logo.gif" /> + </includes> + <messages first_id="10000"> + <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> + Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? + </message> + <message name="IDS_A"> + Bongo! + </message> + </messages>''', predetermined_ids_file=ids_file) + output = rc_header.FormatDefines(grd, grd.GetRcHeaderFormat()) + self.assertEqual(('#define IDS_B 102\n' + '#define IDS_GREETING 10000\n' + '#define IDS_A 101\n'), ''.join(output)) + + def testPredeterminedIdsOverlap(self): + with _MakeTempPredeterminedIdsFile('ID_LOGO 10000') as ids_file: + self.assertRaises(grit.exception.IdRangeOverlap, + util.ParseGrdForUnittest, ''' + <includes first_id="300" comment="bingo"> + <include type="gif" name="ID_LOGO" file="images/logo.gif" /> + </includes> + <messages first_id="10000"> + <message name="IDS_GREETING" desc="Printed to greet the currently logged in user"> + Hello <ph name="USERNAME">%s<ex>Joi</ex></ph>, how are you doing today? + </message> + <message name="IDS_BONGO"> + Bongo! + </message> + </messages>''', predetermined_ids_file=ids_file) + class IfNodeUnittest(unittest.TestCase): def testIffyness(self):
diff --git a/tools/grit/grit/node/structure.py b/tools/grit/grit/node/structure.py index 4f0226f..cf7c1c7 100755 --- a/tools/grit/grit/node/structure.py +++ b/tools/grit/grit/node/structure.py
@@ -26,7 +26,6 @@ import grit.gather.txt import grit.format.rc -import grit.format.rc_header # Type of the gatherer to use for each type attribute _GATHERERS = { @@ -196,20 +195,14 @@ def GetCliques(self): return self.gatherer.GetCliques() - def GetDataPackPair(self, lang, encoding): - """Returns a (id, string|None) pair that represents the resource id and raw - bytes of the data (or None if no resource is generated). This is used to - generate the data pack data file. - """ - from grit.format import rc_header - id_map = rc_header.GetIds(self.GetRoot()) - id = id_map[self.GetTextualIds()[0]] + def GetDataPackValue(self, lang, encoding): + """Returns a str represenation for a data_pack entry.""" if self.ExpandVariables(): text = self.gatherer.GetText() data = util.Encode(self._Substitute(text), encoding) else: data = self.gatherer.GetData(lang, encoding) - return id, self.CompressDataIfNeeded(data) + return self.CompressDataIfNeeded(data) def GetHtmlResourceFilenames(self): """Returns a set of all filenames inlined by this node."""
diff --git a/tools/grit/grit/node/structure_unittest.py b/tools/grit/grit/node/structure_unittest.py index 03d63baa..2da15ed9 100755 --- a/tools/grit/grit/node/structure_unittest.py +++ b/tools/grit/grit/node/structure_unittest.py
@@ -74,7 +74,7 @@ </structures>''', base_dir=test_data_root) struct, = root.GetChildrenOfType(structure.StructureNode) struct.RunPreSubstitutionGatherer() - _, compressed = struct.GetDataPackPair(lang='en', encoding=1) + compressed = struct.GetDataPackValue(lang='en', encoding=1) decompressed_data = zlib.decompress(compressed, 16 + zlib.MAX_WBITS) self.assertEqual(util.ReadFile( @@ -89,7 +89,7 @@ </structures>''', base_dir=test_data_root) struct, = root.GetChildrenOfType(structure.StructureNode) struct.RunPreSubstitutionGatherer() - _, data = struct.GetDataPackPair(lang='en', encoding=1) + data = struct.GetDataPackValue(lang='en', encoding=1) self.assertEqual(util.ReadFile( os.path.join(test_data_root, "test_text.txt"), util.BINARY), data)
diff --git a/tools/grit/grit/tool/build.py b/tools/grit/grit/tool/build.py index f409c95..8b14854 100755 --- a/tools/grit/grit/tool/build.py +++ b/tools/grit/grit/tool/build.py
@@ -387,6 +387,10 @@ self.res.SetFallbackToDefaultLayout(output.GetFallbackToDefaultLayout()) self.res.SetDefines(self.defines) + # Assign IDs only once to ensure that all outputs use the same IDs. + if self.res.GetIdMap() is None: + self.res.InitializeIds() + # Make the output directory if it doesn't exist. self.MakeDirectoriesTo(output.GetOutputFilename())
diff --git a/tools/grit/grit/util.py b/tools/grit/grit/util.py index 93dce261..4a710b7 100755 --- a/tools/grit/grit/util.py +++ b/tools/grit/grit/util.py
@@ -319,7 +319,8 @@ return os.path.normpath(os.path.join(_root_dir, path)) -def ParseGrdForUnittest(body, base_dir=None): +def ParseGrdForUnittest(body, base_dir=None, predetermined_ids_file=None, + run_gatherers=False, output_all_resource_defines=True): '''Parse a skeleton .grd file and return it, for use in unit tests. Args: @@ -332,15 +333,26 @@ body = body.encode('utf-8') if base_dir is None: base_dir = PathFromRoot('.') - body = '''<?xml version="1.0" encoding="UTF-8"?> -<grit latest_public_release="2" current_release="3" source_lang_id="en" base_dir="%s"> - <outputs> - </outputs> - <release seq="3"> - %s - </release> -</grit>''' % (base_dir, body) - return grd_reader.Parse(StringIO.StringIO(body), dir=".") + lines = ['<?xml version="1.0" encoding="UTF-8"?>'] + lines.append(('<grit latest_public_release="2" current_release="3" ' + 'source_lang_id="en" base_dir="{}" ' + 'output_all_resource_defines="{}">').format( + base_dir, str(output_all_resource_defines).lower())) + if '<outputs>' in body: + lines.append(body) + else: + lines.append(' <outputs></outputs>') + lines.append(' <release seq="3">') + lines.append(body) + lines.append(' </release>') + lines.append('</grit>') + ret = grd_reader.Parse(StringIO.StringIO('\n'.join(lines)), dir=".") + ret.SetOutputLanguage('en') + if run_gatherers: + ret.RunGatherers() + ret.SetPredeterminedIdsFile(predetermined_ids_file) + ret.InitializeIds() + return ret def StripBlankLinesAndComments(text):
diff --git a/ui/accelerated_widget_mac/accelerated_widget_mac.h b/ui/accelerated_widget_mac/accelerated_widget_mac.h index 4e80950..cff0f38 100644 --- a/ui/accelerated_widget_mac/accelerated_widget_mac.h +++ b/ui/accelerated_widget_mac/accelerated_widget_mac.h
@@ -54,6 +54,12 @@ base::TimeTicks* timebase, base::TimeDelta* interval) const; static AcceleratedWidgetMac* Get(gfx::AcceleratedWidget widget); + + // Translate from a gfx::AcceleratedWidget to the NSView in which it will + // appear. This may return nil if |widget| is invalid or is not currently + // attached to an NSView. + static NSView* GetNSView(gfx::AcceleratedWidget widget); + void GotCALayerFrame(base::scoped_nsobject<CALayer> content_layer, const gfx::Size& pixel_size, float scale_factor);
diff --git a/ui/accelerated_widget_mac/accelerated_widget_mac.mm b/ui/accelerated_widget_mac/accelerated_widget_mac.mm index 754cbfd7..7f9d0b6 100644 --- a/ui/accelerated_widget_mac/accelerated_widget_mac.mm +++ b/ui/accelerated_widget_mac/accelerated_widget_mac.mm
@@ -48,10 +48,8 @@ // Use a sequence number as the accelerated widget handle that we can use // to look up the internals structure. - static intptr_t last_sequence_number = 0; - last_sequence_number += 1; - native_widget_ = reinterpret_cast<gfx::AcceleratedWidget>( - last_sequence_number); + static uint64_t last_sequence_number = 0; + native_widget_ = ++last_sequence_number; g_widget_to_helper_map.Pointer()->insert( std::make_pair(native_widget_, this)); } @@ -106,6 +104,7 @@ } } +// static AcceleratedWidgetMac* AcceleratedWidgetMac::Get(gfx::AcceleratedWidget widget) { WidgetToHelperMap::const_iterator found = g_widget_to_helper_map.Pointer()->find(widget); @@ -117,6 +116,14 @@ return found->second; } +// static +NSView* AcceleratedWidgetMac::GetNSView(gfx::AcceleratedWidget widget) { + AcceleratedWidgetMac* widget_mac = Get(widget); + if (!widget_mac || !widget_mac->view_) + return nil; + return widget_mac->view_->AcceleratedWidgetGetNSView(); +} + void AcceleratedWidgetMac::GotCALayerFrame( base::scoped_nsobject<CALayer> content_layer, const gfx::Size& pixel_size,
diff --git a/ui/arc/notification/arc_notification_manager_unittest.cc b/ui/arc/notification/arc_notification_manager_unittest.cc index dca1379..6a03147 100644 --- a/ui/arc/notification/arc_notification_manager_unittest.cc +++ b/ui/arc/notification/arc_notification_manager_unittest.cc
@@ -13,6 +13,7 @@ #include "base/run_loop.h" #include "components/arc/arc_bridge_service.h" #include "components/arc/connection_holder.h" +#include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_notifications_instance.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/arc/notification/arc_notification_manager.h" @@ -59,20 +60,6 @@ DISALLOW_COPY_AND_ASSIGN(MockMessageCenter); }; -class NotificationsObserver - : public ConnectionObserver<mojom::NotificationsInstance> { - public: - NotificationsObserver() = default; - void OnConnectionReady() override { ready_ = true; } - - bool IsReady() { return ready_; } - - private: - bool ready_ = false; - - DISALLOW_COPY_AND_ASSIGN(NotificationsObserver); -}; - } // anonymous namespace class ArcNotificationManagerTest : public testing::Test { @@ -122,14 +109,8 @@ arc_notification_manager_ = ArcNotificationManager::CreateForTesting( service_.get(), EmptyAccountId(), message_center_.get()); - NotificationsObserver observer; - service_->notifications()->AddObserver(&observer); service_->notifications()->SetInstance(arc_notifications_instance_.get()); - - while (!observer.IsReady()) - base::RunLoop().RunUntilIdle(); - - service_->notifications()->RemoveObserver(&observer); + WaitForInstanceReady(service_->notifications()); } void TearDown() override {
diff --git a/ui/compositor/test/test_compositor_host_mac.mm b/ui/compositor/test/test_compositor_host_mac.mm index 722edc6..376b1e0 100644 --- a/ui/compositor/test/test_compositor_host_mac.mm +++ b/ui/compositor/test/test_compositor_host_mac.mm
@@ -44,6 +44,10 @@ DCHECK(compositor_) << "Drawing with no compositor set."; compositor_->ScheduleFullRedraw(); } + +- (gfx::AcceleratedWidget)widget { + return compositor_->widget(); +} @end namespace ui { @@ -142,7 +146,7 @@ defer:NO]; base::scoped_nsobject<AcceleratedTestView> view( [[AcceleratedTestView alloc] init]); - compositor_.SetAcceleratedWidget(view); + compositor_.SetAcceleratedWidget([view widget]); compositor_.SetScaleAndSize(1.0f, bounds_.size()); [view setCompositor:&compositor_]; [window_ setContentView:view];
diff --git a/ui/gfx/mojo/struct_traits_unittest.cc b/ui/gfx/mojo/struct_traits_unittest.cc index 81b0b0c7..5841585d 100644 --- a/ui/gfx/mojo/struct_traits_unittest.cc +++ b/ui/gfx/mojo/struct_traits_unittest.cc
@@ -5,6 +5,7 @@ #include <utility> #include "base/message_loop/message_loop.h" +#include "build/build_config.h" #include "mojo/public/cpp/bindings/binding_set.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/mojo/buffer_types_struct_traits.h" @@ -18,7 +19,7 @@ namespace { gfx::AcceleratedWidget castToAcceleratedWidget(int i) { -#if defined(USE_OZONE) || defined(USE_X11) +#if defined(USE_OZONE) || defined(USE_X11) || defined(OS_MACOSX) return static_cast<gfx::AcceleratedWidget>(i); #else return reinterpret_cast<gfx::AcceleratedWidget>(i);
diff --git a/ui/gfx/native_widget_types.h b/ui/gfx/native_widget_types.h index 58c5e60..1252ad1 100644 --- a/ui/gfx/native_widget_types.h +++ b/ui/gfx/native_widget_types.h
@@ -187,7 +187,7 @@ typedef UIView* AcceleratedWidget; constexpr AcceleratedWidget kNullAcceleratedWidget = 0; #elif defined(OS_MACOSX) -typedef NSView* AcceleratedWidget; +typedef uint64_t AcceleratedWidget; constexpr AcceleratedWidget kNullAcceleratedWidget = 0; #elif defined(OS_ANDROID) typedef ANativeWindow* AcceleratedWidget;
diff --git a/ui/views/cocoa/bridged_native_widget.mm b/ui/views/cocoa/bridged_native_widget.mm index c6384ed..520e006 100644 --- a/ui/views/cocoa/bridged_native_widget.mm +++ b/ui/views/cocoa/bridged_native_widget.mm
@@ -1063,7 +1063,7 @@ ui::InputMethod* BridgedNativeWidget::GetInputMethod() { if (!input_method_) { - input_method_ = ui::CreateInputMethod(this, nil); + input_method_ = ui::CreateInputMethod(this, gfx::kNullAcceleratedWidget); // For now, use always-focused mode on Mac for the input method. // TODO(tapted): Move this to OnWindowKeyStatusChangedTo() and balance. input_method_->OnFocus();
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index 57e2b0a..d4c0c6f9 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc
@@ -207,9 +207,7 @@ size.set_height(std::max(preferred_label_size.height() + GetInsets().height(), size.height())); - // Increase the minimum size monotonically with the preferred size. size.SetToMax(min_size_); - min_size_ = size; // Clamp size to max size (if valid). if (max_size_.width() > 0)
diff --git a/ui/views/controls/button/label_button.h b/ui/views/controls/button/label_button.h index 259c355b..b2323da 100644 --- a/ui/views/controls/button/label_button.h +++ b/ui/views/controls/button/label_button.h
@@ -69,7 +69,6 @@ // optional image will lead the text, unless the button is right-aligned. void SetHorizontalAlignment(gfx::HorizontalAlignment alignment); - // Call SetMinSize(gfx::Size()) to clear the monotonically increasing size. void SetMinSize(const gfx::Size& min_size); void SetMaxSize(const gfx::Size& max_size); @@ -83,9 +82,7 @@ ButtonStyle style() const { return style_; } void SetStyleDeprecated(ButtonStyle style); - // Sets the spacing between the image and the text. Shrinking the spacing - // will not shrink the overall button size, as it is monotonically increasing. - // Call SetMinSize(gfx::Size()) to clear the size if needed. + // Sets the spacing between the image and the text. void SetImageLabelSpacing(int spacing); // Creates the default border for this button. This can be overridden by @@ -214,9 +211,8 @@ // Used to track whether SetTextColor() has been invoked. std::array<bool, STATE_COUNT> explicitly_set_colors_; - // |min_size_| increases monotonically with the preferred size. - mutable gfx::Size min_size_; - // |max_size_| may be set to clamp the preferred size. + // |min_size_| and |max_size_| may be set to clamp the preferred size. + gfx::Size min_size_; gfx::Size max_size_; // Cache the last computed preferred size.
diff --git a/ui/views/controls/button/label_button_unittest.cc b/ui/views/controls/button/label_button_unittest.cc index 94acc4b3..466b9cc 100644 --- a/ui/views/controls/button/label_button_unittest.cc +++ b/ui/views/controls/button/label_button_unittest.cc
@@ -154,7 +154,6 @@ const int short_text_width = gfx::GetStringWidth(short_text, font_list); const int long_text_width = gfx::GetStringWidth(long_text, font_list); - // The width increases monotonically with string size (it does not shrink). EXPECT_LT(button_->GetPreferredSize().width(), short_text_width); button_->SetText(short_text); EXPECT_GT(button_->GetPreferredSize().height(), font_list.GetHeight()); @@ -163,16 +162,20 @@ button_->SetText(long_text); EXPECT_GT(button_->GetPreferredSize().width(), long_text_width); button_->SetText(short_text); - EXPECT_GT(button_->GetPreferredSize().width(), long_text_width); - - // Clamp the size to a maximum value. - button_->SetMaxSize(gfx::Size(long_text_width, 1)); - EXPECT_EQ(button_->GetPreferredSize(), gfx::Size(long_text_width, 1)); - - // Clear the monotonically increasing minimum size. - button_->SetMinSize(gfx::Size()); EXPECT_GT(button_->GetPreferredSize().width(), short_text_width); EXPECT_LT(button_->GetPreferredSize().width(), long_text_width); + + // Clamp the size to a maximum value. + button_->SetText(long_text); + button_->SetMaxSize(gfx::Size(short_text_width, 1)); + EXPECT_EQ(button_->GetPreferredSize(), gfx::Size(short_text_width, 1)); + + // Clamp the size to a minimum value. + button_->SetText(short_text); + button_->SetMaxSize(gfx::Size()); + button_->SetMinSize(gfx::Size(long_text_width, font_list.GetHeight() * 2)); + EXPECT_EQ(button_->GetPreferredSize(), + gfx::Size(long_text_width, font_list.GetHeight() * 2)); } // Test behavior of View::GetAccessibleNodeData() for buttons when setting a @@ -212,7 +215,6 @@ const gfx::ImageSkia small_image = CreateTestImage(small_size, small_size); const gfx::ImageSkia large_image = CreateTestImage(large_size, large_size); - // The width increases monotonically with image size (it does not shrink). EXPECT_LT(button_->GetPreferredSize().width(), small_size); EXPECT_LT(button_->GetPreferredSize().height(), small_size); button_->SetImage(Button::STATE_NORMAL, small_image); @@ -224,17 +226,21 @@ EXPECT_GT(button_->GetPreferredSize().width(), large_size); EXPECT_GT(button_->GetPreferredSize().height(), large_size); button_->SetImage(Button::STATE_NORMAL, small_image); - EXPECT_GT(button_->GetPreferredSize().width(), large_size); - EXPECT_GT(button_->GetPreferredSize().height(), large_size); + EXPECT_GT(button_->GetPreferredSize().width(), small_size); + EXPECT_GT(button_->GetPreferredSize().height(), small_size); + EXPECT_LT(button_->GetPreferredSize().width(), large_size); + EXPECT_LT(button_->GetPreferredSize().height(), large_size); // Clamp the size to a maximum value. + button_->SetImage(Button::STATE_NORMAL, large_image); button_->SetMaxSize(gfx::Size(large_size, 1)); EXPECT_EQ(button_->GetPreferredSize(), gfx::Size(large_size, 1)); - // Clear the monotonically increasing minimum size. - button_->SetMinSize(gfx::Size()); - EXPECT_GT(button_->GetPreferredSize().width(), small_size); - EXPECT_LT(button_->GetPreferredSize().width(), large_size); + // Clamp the size to a minimum value. + button_->SetImage(Button::STATE_NORMAL, small_image); + button_->SetMaxSize(gfx::Size()); + button_->SetMinSize(gfx::Size(large_size, large_size)); + EXPECT_EQ(button_->GetPreferredSize(), gfx::Size(large_size, large_size)); } TEST_F(LabelButtonTest, LabelAndImage) { @@ -246,7 +252,6 @@ const gfx::ImageSkia image = CreateTestImage(image_size, image_size); ASSERT_LT(font_list.GetHeight(), image_size); - // The width increases monotonically with content size (it does not shrink). EXPECT_LT(button_->GetPreferredSize().width(), text_width); EXPECT_LT(button_->GetPreferredSize().width(), image_size); EXPECT_LT(button_->GetPreferredSize().height(), image_size); @@ -279,21 +284,24 @@ EXPECT_LT(button_->label()->bounds().right(), button_->image()->bounds().x()); button_->SetText(base::string16()); - EXPECT_GT(button_->GetPreferredSize().width(), text_width + image_size); + EXPECT_LT(button_->GetPreferredSize().width(), text_width + image_size); + EXPECT_GT(button_->GetPreferredSize().width(), image_size); EXPECT_GT(button_->GetPreferredSize().height(), image_size); button_->SetImage(Button::STATE_NORMAL, gfx::ImageSkia()); - EXPECT_GT(button_->GetPreferredSize().width(), text_width + image_size); - EXPECT_GT(button_->GetPreferredSize().height(), image_size); - - // Clamp the size to a maximum value. - button_->SetMaxSize(gfx::Size(image_size, 1)); - EXPECT_EQ(button_->GetPreferredSize(), gfx::Size(image_size, 1)); - - // Clear the monotonically increasing minimum size. - button_->SetMinSize(gfx::Size()); - EXPECT_LT(button_->GetPreferredSize().width(), text_width); EXPECT_LT(button_->GetPreferredSize().width(), image_size); EXPECT_LT(button_->GetPreferredSize().height(), image_size); + + // Clamp the size to a minimum value. + button_->SetText(text); + button_->SetImage(Button::STATE_NORMAL, image); + button_->SetMinSize(gfx::Size((text_width + image_size) * 2, image_size * 2)); + EXPECT_EQ(button_->GetPreferredSize().width(), (text_width + image_size) * 2); + EXPECT_EQ(button_->GetPreferredSize().height(), image_size * 2); + + // Clamp the size to a maximum value. + button_->SetMinSize(gfx::Size()); + button_->SetMaxSize(gfx::Size(1, 1)); + EXPECT_EQ(button_->GetPreferredSize(), gfx::Size(1, 1)); } // This test was added because GetHeightForWidth and GetPreferredSize were @@ -326,10 +334,6 @@ EXPECT_EQ(std::max(image_size, font_height) + button_->GetInsets().height(), preferred_button_size.height()); - // Clear min size, this ensures that GetHeightForWidth() is consistent on - // its own and not because min_size_ is set to the preferred size. - button_->SetMinSize(gfx::Size()); - // Make sure this preferred height is consistent with GetHeightForWidth(). EXPECT_EQ(preferred_button_size.height(), button_->GetHeightForWidth(preferred_button_size.width())); @@ -399,7 +403,6 @@ // The button and the label view return to its original size when the original // text is restored. - button_->SetMinSize(gfx::Size()); button_->SetText(text); EXPECT_EQ(original_label_width, button_->label()->bounds().width()); EXPECT_EQ(original_width, button_->GetPreferredSize().width()); @@ -418,7 +421,6 @@ EXPECT_GT(button_->GetPreferredSize().width(), original_width); // The button shrinks if the original spacing is restored. - button_->SetMinSize(gfx::Size()); button_->SetImageLabelSpacing(kOriginalSpacing); EXPECT_EQ(original_width, button_->GetPreferredSize().width()); }
diff --git a/ui/views/examples/button_example.cc b/ui/views/examples/button_example.cc index 5a0f969..048ef485 100644 --- a/ui/views/examples/button_example.cc +++ b/ui/views/examples/button_example.cc
@@ -113,8 +113,6 @@ } } else if (event.IsAltDown()) { label_button->SetIsDefault(!label_button->is_default()); - } else { - label_button->SetMinSize(gfx::Size()); } example_view()->GetLayoutManager()->Layout(example_view()); }