summaryrefslogtreecommitdiff
path: root/chromium/components
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2018-02-15 14:18:00 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2018-02-15 14:00:37 +0000
commit66a2147d838e293f4a5db7711c8eba4e6faaaf0f (patch)
tree61ad99912355f5b6cc603d9b1dfadd77b950ce98 /chromium/components
parentda51f56cc21233c2d30f0fe0d171727c3102b2e0 (diff)
downloadqtwebengine-chromium-66a2147d838e293f4a5db7711c8eba4e6faaaf0f.tar.gz
BASELINE: Update Chromium to 65.0.3325.75
Change-Id: I5485bc5c111539356276457516584fa5737f07d8 Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Diffstat (limited to 'chromium/components')
-rw-r--r--chromium/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc2
-rw-r--r--chromium/components/autofill/content/renderer/page_passwords_analyser.cc3
-rw-r--r--chromium/components/data_use_measurement/core/data_use_ascriber.h1
-rw-r--r--chromium/components/exo/client_controlled_shell_surface.cc20
-rw-r--r--chromium/components/exo/client_controlled_shell_surface.h2
-rw-r--r--chromium/components/exo/client_controlled_shell_surface_unittest.cc47
-rw-r--r--chromium/components/exo/pointer.cc18
-rw-r--r--chromium/components/exo/shell_surface.cc7
-rw-r--r--chromium/components/exo/shell_surface.h3
-rw-r--r--chromium/components/exo/shell_surface_base.cc13
-rw-r--r--chromium/components/exo/shell_surface_base.h5
-rw-r--r--chromium/components/exo/sub_surface.cc4
-rw-r--r--chromium/components/exo/sub_surface.h2
-rw-r--r--chromium/components/exo/surface.cc9
-rw-r--r--chromium/components/exo/surface.h4
-rw-r--r--chromium/components/exo/surface_delegate.h6
-rw-r--r--chromium/components/exo/surface_tree_host.cc6
-rw-r--r--chromium/components/exo/surface_tree_host.h6
-rw-r--r--chromium/components/exo/wayland/server.cc4
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc16
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h9
-rw-r--r--chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc36
-rw-r--r--chromium/components/password_manager/core/browser/password_syncable_service.cc406
-rw-r--r--chromium/components/password_manager/core/browser/password_syncable_service.h29
-rw-r--r--chromium/components/password_manager/core/browser/password_syncable_service_unittest.cc567
-rw-r--r--chromium/components/safe_browsing/proto/csd.proto15
-rw-r--r--chromium/components/strings/components_strings_mr.xtb2
-rw-r--r--chromium/components/strings/components_strings_no.xtb2
-rw-r--r--chromium/components/viz/service/display/gl_renderer.cc4
29 files changed, 221 insertions, 1027 deletions
diff --git a/chromium/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc b/chromium/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc
index 4347194e254..3319035130c 100644
--- a/chromium/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc
+++ b/chromium/components/arc/video_accelerator/gpu_arc_video_decode_accelerator.cc
@@ -610,7 +610,7 @@ void GpuArcVideoDecodeAccelerator::ImportBufferForPicture(
base::FileDescriptor(handle_fd.release(), true));
for (const auto& plane : planes) {
gmb_handle.native_pixmap_handle.planes.emplace_back(plane.stride,
- plane.offset, 0, 0);
+ plane.offset, 0);
}
}
diff --git a/chromium/components/autofill/content/renderer/page_passwords_analyser.cc b/chromium/components/autofill/content/renderer/page_passwords_analyser.cc
index 141d40e521c..f45a6caa4ad 100644
--- a/chromium/components/autofill/content/renderer/page_passwords_analyser.cc
+++ b/chromium/components/autofill/content/renderer/page_passwords_analyser.cc
@@ -371,8 +371,9 @@ void AnalyseForm(const FormInputCollection& form_input_collection,
} else {
// By default (if the other heuristics fail), the first text field
// preceding a password field will be considered the username field.
- for (username_field_guess = password_inputs[0] - 1;;
+ for (username_field_guess = explicit_password_inputs[0] - 1;;
--username_field_guess) {
+ DCHECK(username_field_guess < signature.size());
if (signature[username_field_guess] == kTextFieldSignature)
break;
}
diff --git a/chromium/components/data_use_measurement/core/data_use_ascriber.h b/chromium/components/data_use_measurement/core/data_use_ascriber.h
index 9d903aea015..5ead8d7d0f8 100644
--- a/chromium/components/data_use_measurement/core/data_use_ascriber.h
+++ b/chromium/components/data_use_measurement/core/data_use_ascriber.h
@@ -102,6 +102,7 @@ class DataUseAscriber {
}
// Methods called by DataUseNetworkDelegate to propagate data use information:
+ // OnBeforeUrlRequest may be called twice. e.g., in case of redirects.
virtual void OnBeforeUrlRequest(net::URLRequest* request);
virtual void OnNetworkBytesSent(net::URLRequest* request, int64_t bytes_sent);
virtual void OnNetworkBytesReceived(net::URLRequest* request,
diff --git a/chromium/components/exo/client_controlled_shell_surface.cc b/chromium/components/exo/client_controlled_shell_surface.cc
index 348a3168631..7139392ef6e 100644
--- a/chromium/components/exo/client_controlled_shell_surface.cc
+++ b/chromium/components/exo/client_controlled_shell_surface.cc
@@ -474,14 +474,15 @@ void ClientControlledShellSurface::OnSurfaceCommit() {
orientation_compositor_lock_.reset();
}
-bool ClientControlledShellSurface::IsTouchEnabled(Surface* surface) const {
- // The target for input events is selected by recursively hit-testing surfaces
- // in the surface tree. During client-driven dragging/resizing, capture is set
- // on the root surface. When capture is reset to a different target, mouse
- // events are redirected from the old to the new target, but touch/gesture
- // events are cancelled. To avoid prematurely ending the drag/resize, ensure
- // that the target and capture windows are the same by disabling touch input
- // for all but the root surface.
+bool ClientControlledShellSurface::IsInputEnabled(Surface* surface) const {
+ // Client-driven dragging/resizing relies on implicit grab, which ensures that
+ // mouse/touch events are delivered to the focused surface until release, even
+ // if they fall outside surface bounds. However, if the client destroys the
+ // surface with implicit grab, the drag/resize is prematurely ended. Prevent
+ // this by delivering all input events to the root surface, which shares the
+ // lifetime of the shell surface.
+ // TODO(domlaskowski): Remove once the client is provided with an API to hook
+ // into server-driven dragging/resizing.
return surface == root_surface();
}
@@ -670,8 +671,9 @@ void ClientControlledShellSurface::InitializeWindowState(
// Allow the client to request bounds that do not fill the entire work area
// when maximized, or the entire display when fullscreen.
window_state->set_allow_set_bounds_direct(true);
- widget_->set_movement_disabled(true);
window_state->set_ignore_keyboard_bounds_change(true);
+ if (container_ == ash::kShellWindowId_SystemModalContainer)
+ DisableMovement();
}
float ClientControlledShellSurface::GetScale() const {
diff --git a/chromium/components/exo/client_controlled_shell_surface.h b/chromium/components/exo/client_controlled_shell_surface.h
index 7c9349db058..3fda1e29f85 100644
--- a/chromium/components/exo/client_controlled_shell_surface.h
+++ b/chromium/components/exo/client_controlled_shell_surface.h
@@ -150,7 +150,7 @@ class ClientControlledShellSurface
// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
- bool IsTouchEnabled(Surface* surface) const override;
+ bool IsInputEnabled(Surface* surface) const override;
// Overridden from views::WidgetDelegate:
bool CanMaximize() const override;
diff --git a/chromium/components/exo/client_controlled_shell_surface_unittest.cc b/chromium/components/exo/client_controlled_shell_surface_unittest.cc
index 78da5c0e8af..68ff31e7c4b 100644
--- a/chromium/components/exo/client_controlled_shell_surface_unittest.cc
+++ b/chromium/components/exo/client_controlled_shell_surface_unittest.cc
@@ -754,4 +754,51 @@ TEST_F(ClientControlledShellSurfaceTest, MouseAndTouchTarget) {
targeter->FindTargetForEvent(root, &no_touch))));
}
+// The shell surface in SystemModal container should be unresizable.
+TEST_F(ClientControlledShellSurfaceTest,
+ ShellSurfaceInSystemModalIsUnresizable) {
+ gfx::Size buffer_size(256, 256);
+ std::unique_ptr<Buffer> buffer(
+ new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)));
+ std::unique_ptr<Surface> surface(new Surface);
+ auto shell_surface =
+ exo_test_helper()->CreateClientControlledShellSurface(surface.get(),
+ /*is_modal=*/true);
+ surface->Attach(buffer.get());
+ surface->Commit();
+
+ EXPECT_FALSE(shell_surface->GetWidget()->widget_delegate()->CanResize());
+}
+
+// The shell surface in SystemModal container should not become target
+// at the edge.
+TEST_F(ClientControlledShellSurfaceTest, ShellSurfaceInSystemModalHitTest) {
+ std::unique_ptr<Surface> surface(new Surface);
+ auto shell_surface =
+ exo_test_helper()->CreateClientControlledShellSurface(surface.get(),
+ /*is_modal=*/true);
+ shell_surface->set_client_controlled_move_resize(false);
+
+ display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
+
+ gfx::Size desktop_size(640, 480);
+ std::unique_ptr<Buffer> desktop_buffer(
+ new Buffer(exo_test_helper()->CreateGpuMemoryBuffer(desktop_size)));
+ surface->Attach(desktop_buffer.get());
+ surface->SetInputRegion(gfx::Rect(0, 0, 0, 0));
+ shell_surface->SetGeometry(display.bounds());
+ surface->Commit();
+
+ EXPECT_FALSE(shell_surface->GetWidget()->widget_delegate()->CanResize());
+ aura::Window* window = shell_surface->GetWidget()->GetNativeWindow();
+ aura::Window* root = window->GetRootWindow();
+
+ ui::MouseEvent event(ui::ET_MOUSE_MOVED, gfx::Point(100, 0),
+ gfx::Point(100, 0), ui::EventTimeForNow(), 0, 0);
+ aura::WindowTargeter targeter;
+ aura::Window* found =
+ static_cast<aura::Window*>(targeter.FindTargetForEvent(root, &event));
+ EXPECT_FALSE(window->Contains(found));
+}
+
} // namespace exo
diff --git a/chromium/components/exo/pointer.cc b/chromium/components/exo/pointer.cc
index 5d278bbe7b9..62ccbe27047 100644
--- a/chromium/components/exo/pointer.cc
+++ b/chromium/components/exo/pointer.cc
@@ -23,6 +23,7 @@
#include "ui/events/event.h"
#include "ui/gfx/geometry/vector2d_conversions.h"
#include "ui/gfx/transform_util.h"
+#include "ui/views/widget/widget.h"
#if defined(USE_OZONE)
#include "ui/ozone/public/cursor_factory_ozone.h"
@@ -478,7 +479,22 @@ void Pointer::UpdateCursor() {
#endif
}
- cursor_client->SetCursor(cursor_);
+ // If there is a focused surface, update its widget as the views framework
+ // expect that Widget knows the current cursor. Otherwise update the
+ // cursor directly on CursorClient.
+ if (focus_surface_) {
+ aura::Window* window = focus_surface_->window();
+ do {
+ views::Widget* widget = views::Widget::GetWidgetForNativeView(window);
+ if (widget) {
+ widget->SetCursor(cursor_);
+ return;
+ }
+ window = window->parent();
+ } while (window);
+ } else {
+ cursor_client->SetCursor(cursor_);
+ }
}
} // namespace exo
diff --git a/chromium/components/exo/shell_surface.cc b/chromium/components/exo/shell_surface.cc
index 1bcfad83e97..b14d7aafd1f 100644
--- a/chromium/components/exo/shell_surface.cc
+++ b/chromium/components/exo/shell_surface.cc
@@ -140,13 +140,6 @@ void ShellSurface::SetFullscreen(bool fullscreen) {
widget_->SetFullscreen(fullscreen);
}
-void ShellSurface::DisableMovement() {
- movement_disabled_ = true;
-
- if (widget_)
- widget_->set_movement_disabled(true);
-}
-
void ShellSurface::Resize(int component) {
TRACE_EVENT1("exo", "ShellSurface::Resize", "component", component);
diff --git a/chromium/components/exo/shell_surface.h b/chromium/components/exo/shell_surface.h
index 589e27bf2f1..10e753899f0 100644
--- a/chromium/components/exo/shell_surface.h
+++ b/chromium/components/exo/shell_surface.h
@@ -43,9 +43,6 @@ class ShellSurface : public ShellSurfaceBase,
// Set fullscreen state for shell surface.
void SetFullscreen(bool fullscreen);
- // Prevents shell surface from being moved.
- void DisableMovement();
-
// Start an interactive resize of surface. |component| is one of the windows
// HT constants (see ui/base/hit_test.h) and describes in what direction the
// surface should be resized.
diff --git a/chromium/components/exo/shell_surface_base.cc b/chromium/components/exo/shell_surface_base.cc
index 3a189d58e7c..7023369b1d4 100644
--- a/chromium/components/exo/shell_surface_base.cc
+++ b/chromium/components/exo/shell_surface_base.cc
@@ -210,8 +210,10 @@ class CustomWindowTargeter : public aura::WindowTargeter {
return false;
int component = widget_->non_client_view()->NonClientHitTest(local_point);
- if (component != HTNOWHERE && component != HTCLIENT)
+ if (component != HTNOWHERE && component != HTCLIENT &&
+ component != HTBORDER) {
return true;
+ }
aura::Window::ConvertPointToTarget(window, surface->window(), &local_point);
return surface->HitTest(local_point);
@@ -567,6 +569,13 @@ void ShellSurfaceBase::SetCanMinimize(bool can_minimize) {
can_minimize_ = can_minimize;
}
+void ShellSurfaceBase::DisableMovement() {
+ movement_disabled_ = true;
+
+ if (widget_)
+ widget_->set_movement_disabled(true);
+}
+
// static
void ShellSurfaceBase::SetMainSurface(aura::Window* window, Surface* surface) {
window->SetProperty(kMainSurfaceKey, surface);
@@ -675,7 +684,7 @@ void ShellSurfaceBase::OnSurfaceCommit() {
widget_->OnSizeConstraintsChanged();
}
-bool ShellSurfaceBase::IsTouchEnabled(Surface*) const {
+bool ShellSurfaceBase::IsInputEnabled(Surface*) const {
return true;
}
diff --git a/chromium/components/exo/shell_surface_base.h b/chromium/components/exo/shell_surface_base.h
index 58d91216f18..defeb662aba 100644
--- a/chromium/components/exo/shell_surface_base.h
+++ b/chromium/components/exo/shell_surface_base.h
@@ -146,6 +146,9 @@ class ShellSurfaceBase : public SurfaceTreeHost,
void SetCanMinimize(bool can_minimize);
+ // Prevents shell surface from being moved.
+ void DisableMovement();
+
// Sets the main surface for the window.
static void SetMainSurface(aura::Window* window, Surface* surface);
@@ -158,7 +161,7 @@ class ShellSurfaceBase : public SurfaceTreeHost,
// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
- bool IsTouchEnabled(Surface* surface) const override;
+ bool IsInputEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) override;
void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override;
void OnSetParent(Surface* parent, const gfx::Point& position) override;
diff --git a/chromium/components/exo/sub_surface.cc b/chromium/components/exo/sub_surface.cc
index 871899143c9..27592e55850 100644
--- a/chromium/components/exo/sub_surface.cc
+++ b/chromium/components/exo/sub_surface.cc
@@ -109,8 +109,8 @@ bool SubSurface::IsSurfaceSynchronized() const {
return parent_ && parent_->IsSynchronized();
}
-bool SubSurface::IsTouchEnabled(Surface* surface) const {
- return !parent_ || parent_->IsTouchEnabled(surface);
+bool SubSurface::IsInputEnabled(Surface* surface) const {
+ return !parent_ || parent_->IsInputEnabled(surface);
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/chromium/components/exo/sub_surface.h b/chromium/components/exo/sub_surface.h
index e0a11185c20..acd775eac0e 100644
--- a/chromium/components/exo/sub_surface.h
+++ b/chromium/components/exo/sub_surface.h
@@ -51,7 +51,7 @@ class SubSurface : public SurfaceDelegate, public SurfaceObserver {
// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
bool IsSurfaceSynchronized() const override;
- bool IsTouchEnabled(Surface* surface) const override;
+ bool IsInputEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) override {}
void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override {
}
diff --git a/chromium/components/exo/surface.cc b/chromium/components/exo/surface.cc
index 6b9d48ab3f4..be321c416bf 100644
--- a/chromium/components/exo/surface.cc
+++ b/chromium/components/exo/surface.cc
@@ -163,10 +163,7 @@ class CustomWindowTargeter : public aura::WindowTargeter {
bool EventLocationInsideBounds(aura::Window* window,
const ui::LocatedEvent& event) const override {
Surface* surface = Surface::AsSurface(window);
- if (!surface)
- return false;
-
- if (event.IsTouchEvent() && !surface->IsTouchEnabled(surface))
+ if (!surface || !surface->IsInputEnabled(surface))
return false;
gfx::Point local_point = event.location();
@@ -629,8 +626,8 @@ bool Surface::IsSynchronized() const {
return delegate_ && delegate_->IsSurfaceSynchronized();
}
-bool Surface::IsTouchEnabled(Surface* surface) const {
- return !delegate_ || delegate_->IsTouchEnabled(surface);
+bool Surface::IsInputEnabled(Surface* surface) const {
+ return !delegate_ || delegate_->IsInputEnabled(surface);
}
bool Surface::HasHitTestRegion() const {
diff --git a/chromium/components/exo/surface.h b/chromium/components/exo/surface.h
index 888a518a9b9..efac96f8a68 100644
--- a/chromium/components/exo/surface.h
+++ b/chromium/components/exo/surface.h
@@ -181,8 +181,8 @@ class Surface final : public ui::PropertyHandler {
// Returns true if surface is in synchronized mode.
bool IsSynchronized() const;
- // Returns true if surface should receive touch events.
- bool IsTouchEnabled(Surface* surface) const;
+ // Returns true if surface should receive input events.
+ bool IsInputEnabled(Surface* surface) const;
// Returns false if the hit test region is empty.
bool HasHitTestRegion() const;
diff --git a/chromium/components/exo/surface_delegate.h b/chromium/components/exo/surface_delegate.h
index a1895815d07..4b5ed492e2f 100644
--- a/chromium/components/exo/surface_delegate.h
+++ b/chromium/components/exo/surface_delegate.h
@@ -24,10 +24,8 @@ class SurfaceDelegate {
// double-buffered state should be synchronized with parent surface.
virtual bool IsSurfaceSynchronized() const = 0;
- // Returns true if surface should receive touch events.
- // TODO(domlaskowski): Remove once client-driven dragging/resizing is removed
- // in crbug.com/795119.
- virtual bool IsTouchEnabled(Surface* surface) const = 0;
+ // Returns true if surface should receive input events.
+ virtual bool IsInputEnabled(Surface* surface) const = 0;
// Called when surface was requested to use a specific frame type.
virtual void OnSetFrame(SurfaceFrameType type) = 0;
diff --git a/chromium/components/exo/surface_tree_host.cc b/chromium/components/exo/surface_tree_host.cc
index 23b8131f6fa..f796cf48285 100644
--- a/chromium/components/exo/surface_tree_host.cc
+++ b/chromium/components/exo/surface_tree_host.cc
@@ -152,10 +152,6 @@ void SurfaceTreeHost::GetHitTestMask(gfx::Path* mask) const {
root_surface_->GetHitTestMask(mask);
}
-gfx::NativeCursor SurfaceTreeHost::GetCursor(const gfx::Point& point) const {
- return root_surface_ ? root_surface_->GetCursor() : ui::CursorType::kNull;
-}
-
void SurfaceTreeHost::DidReceiveCompositorFrameAck() {
active_frame_callbacks_.splice(active_frame_callbacks_.end(),
frame_callbacks_);
@@ -217,7 +213,7 @@ bool SurfaceTreeHost::IsSurfaceSynchronized() const {
return false;
}
-bool SurfaceTreeHost::IsTouchEnabled(Surface*) const {
+bool SurfaceTreeHost::IsInputEnabled(Surface*) const {
return true;
}
diff --git a/chromium/components/exo/surface_tree_host.h b/chromium/components/exo/surface_tree_host.h
index 0cfff8f0dd5..51c0dad364c 100644
--- a/chromium/components/exo/surface_tree_host.h
+++ b/chromium/components/exo/surface_tree_host.h
@@ -49,10 +49,6 @@ class SurfaceTreeHost : public SurfaceDelegate,
// surface tree.
void GetHitTestMask(gfx::Path* mask) const;
- // Returns the cursor for the given position. If no cursor provider is
- // registered then CursorType::kNull is returned.
- gfx::NativeCursor GetCursor(const gfx::Point& point) const;
-
// Call this to indicate that the previous CompositorFrame is processed and
// the surface is being scheduled for a draw.
void DidReceiveCompositorFrameAck();
@@ -90,7 +86,7 @@ class SurfaceTreeHost : public SurfaceDelegate,
// Overridden from SurfaceDelegate:
void OnSurfaceCommit() override;
bool IsSurfaceSynchronized() const override;
- bool IsTouchEnabled(Surface* surface) const override;
+ bool IsInputEnabled(Surface* surface) const override;
void OnSetFrame(SurfaceFrameType type) override {}
void OnSetFrameColors(SkColor active_color, SkColor inactive_color) override {
}
diff --git a/chromium/components/exo/wayland/server.cc b/chromium/components/exo/wayland/server.cc
index c60295e8c97..d9feec46565 100644
--- a/chromium/components/exo/wayland/server.cc
+++ b/chromium/components/exo/wayland/server.cc
@@ -745,7 +745,7 @@ void linux_buffer_params_create(wl_client* client,
for (uint32_t i = 0; i < num_planes; ++i) {
auto plane_it = linux_buffer_params->planes.find(i);
LinuxBufferParams::Plane& plane = plane_it->second;
- planes.emplace_back(plane.stride, plane.offset, 0, 0);
+ planes.emplace_back(plane.stride, plane.offset, 0);
fds.push_back(std::move(plane.fd));
}
@@ -804,7 +804,7 @@ void linux_buffer_params_create_immed(wl_client* client,
for (uint32_t i = 0; i < num_planes; ++i) {
auto plane_it = linux_buffer_params->planes.find(i);
LinuxBufferParams::Plane& plane = plane_it->second;
- planes.emplace_back(plane.stride, plane.offset, 0, 0);
+ planes.emplace_back(plane.stride, plane.offset, 0);
fds.push_back(std::move(plane.fd));
}
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc
index d33d3f03224..1150c058052 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.cc
@@ -15,9 +15,9 @@
#include "components/ntp_snippets/category.h"
#include "components/ntp_snippets/ntp_snippets_constants.h"
#include "components/ntp_snippets/user_classifier.h"
+#include "components/signin/core/browser/signin_manager_base.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_status.h"
-#include "services/identity/public/cpp/identity_manager.h"
#include "services/identity/public/cpp/primary_account_access_token_fetcher.h"
using language::UrlLanguageHistogram;
@@ -124,7 +124,8 @@ void FilterCategories(FetchedCategoriesVector* categories,
} // namespace
RemoteSuggestionsFetcherImpl::RemoteSuggestionsFetcherImpl(
- identity::IdentityManager* identity_manager,
+ SigninManagerBase* signin_manager,
+ OAuth2TokenService* token_service,
scoped_refptr<URLRequestContextGetter> url_request_context_getter,
PrefService* pref_service,
UrlLanguageHistogram* language_histogram,
@@ -132,7 +133,8 @@ RemoteSuggestionsFetcherImpl::RemoteSuggestionsFetcherImpl(
const GURL& api_endpoint,
const std::string& api_key,
const UserClassifier* user_classifier)
- : identity_manager_(identity_manager),
+ : signin_manager_(signin_manager),
+ token_service_(token_service),
url_request_context_getter_(std::move(url_request_context_getter)),
language_histogram_(language_histogram),
parse_json_callback_(parse_json_callback),
@@ -177,7 +179,7 @@ void RemoteSuggestionsFetcherImpl::FetchSnippets(
.SetUrlRequestContextGetter(url_request_context_getter_)
.SetUserClassifier(*user_classifier_);
- if (identity_manager_->HasPrimaryAccount()) {
+ if (signin_manager_->IsAuthenticated()) {
// Signed-in: get OAuth token --> fetch suggestions.
pending_requests_.emplace(std::move(builder), std::move(callback));
StartTokenRequest();
@@ -209,7 +211,7 @@ void RemoteSuggestionsFetcherImpl::FetchSnippetsAuthenticated(
const std::string& oauth_access_token) {
// TODO(jkrcal, treib): Add unit-tests for authenticated fetches.
builder.SetUrl(fetch_url_)
- .SetAuthentication(identity_manager_->GetPrimaryAccountInfo().account_id,
+ .SetAuthentication(signin_manager_->GetAuthenticatedAccountId(),
base::StringPrintf(kAuthorizationRequestHeaderFormat,
oauth_access_token.c_str()));
StartRequest(std::move(builder), std::move(callback));
@@ -232,8 +234,8 @@ void RemoteSuggestionsFetcherImpl::StartTokenRequest() {
}
OAuth2TokenService::ScopeSet scopes{kContentSuggestionsApiScope};
- token_fetcher_ = identity_manager_->CreateAccessTokenFetcherForPrimaryAccount(
- "ntp_snippets", scopes,
+ token_fetcher_ = std::make_unique<identity::PrimaryAccountAccessTokenFetcher>(
+ "ntp_snippets", signin_manager_, token_service_, scopes,
base::BindOnce(&RemoteSuggestionsFetcherImpl::AccessTokenFetchFinished,
base::Unretained(this)),
identity::PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable);
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h
index f5a33841bb3..0d95ca461e0 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl.h
@@ -20,14 +20,15 @@
#include "components/ntp_snippets/remote/request_params.h"
#include "net/url_request/url_request_context_getter.h"
+class OAuth2TokenService;
class PrefService;
+class SigninManagerBase;
namespace base {
class Value;
} // namespace base
namespace identity {
-class IdentityManager;
class PrimaryAccountAccessTokenFetcher;
}
@@ -42,7 +43,8 @@ class UserClassifier;
class RemoteSuggestionsFetcherImpl : public RemoteSuggestionsFetcher {
public:
RemoteSuggestionsFetcherImpl(
- identity::IdentityManager* identity_manager,
+ SigninManagerBase* signin_manager,
+ OAuth2TokenService* token_service,
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
PrefService* pref_service,
language::UrlLanguageHistogram* language_histogram,
@@ -88,7 +90,8 @@ class RemoteSuggestionsFetcherImpl : public RemoteSuggestionsFetcher {
const std::string& error_details);
// Authentication for signed-in users.
- identity::IdentityManager* identity_manager_;
+ SigninManagerBase* signin_manager_;
+ OAuth2TokenService* token_service_;
std::unique_ptr<identity::PrimaryAccountAccessTokenFetcher> token_fetcher_;
diff --git a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
index 3df8a732140..67d205ba0a5 100644
--- a/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
+++ b/chromium/components/ntp_snippets/remote/remote_suggestions_fetcher_impl_unittest.cc
@@ -10,7 +10,6 @@
#include "base/containers/circular_deque.h"
#include "base/json/json_reader.h"
-#include "base/message_loop/message_loop.h"
#include "base/optional.h"
#include "base/test/histogram_tester.h"
#include "base/test/test_mock_time_task_runner.h"
@@ -35,7 +34,6 @@
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "net/url_request/url_request_test_util.h"
-#include "services/identity/public/cpp/identity_manager.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -61,7 +59,7 @@ const char kTestChromeContentSuggestionsSignedOutUrl[] =
const char kTestChromeContentSuggestionsSignedInUrl[] =
"https://chromecontentsuggestions-pa.googleapis.com/v1/suggestions/fetch";
-const char kTestAccount[] = "foo@bar.com";
+const char kTestEmail[] = "foo@bar.com";
// Artificial time delay for JSON parsing.
const int64_t kTestJsonParsingLatencyMs = 20;
@@ -293,25 +291,18 @@ class RemoteSuggestionsFetcherImplTestBase
scoped_refptr<net::TestURLRequestContextGetter> request_context_getter =
new net::TestURLRequestContextGetter(mock_task_runner_.get());
- if (fake_token_service_) {
+ if (fake_token_service_)
fake_token_service_->RemoveDiagnosticsObserver(this);
- identity_manager_.reset();
- }
-
fake_token_service_ = std::make_unique<FakeProfileOAuth2TokenService>(
std::make_unique<FakeOAuth2TokenServiceDelegate>(
request_context_getter.get()));
fake_token_service_->AddDiagnosticsObserver(this);
- // TODO(blundell): Convert this test to use IdentityTestEnvironment once
- // that infrastructure lands in the codebase.
- identity_manager_ = std::make_unique<identity::IdentityManager>(
- utils_.fake_signin_manager(), fake_token_service_.get());
-
fetcher_ = std::make_unique<RemoteSuggestionsFetcherImpl>(
- identity_manager_.get(), std::move(request_context_getter),
- utils_.pref_service(), nullptr, base::BindRepeating(&ParseJsonDelayed),
+ utils_.fake_signin_manager(), fake_token_service_.get(),
+ std::move(request_context_getter), utils_.pref_service(), nullptr,
+ base::BindRepeating(&ParseJsonDelayed),
GetFetchEndpoint(version_info::Channel::STABLE), api_key,
user_classifier_.get());
@@ -320,24 +311,26 @@ class RemoteSuggestionsFetcherImplTestBase
}
void SignIn() {
- identity_manager_->SetPrimaryAccountSynchronouslyForTests(kTestAccount,
- kTestAccount, "");
+#if defined(OS_CHROMEOS)
+ utils_.fake_signin_manager()->SignIn(kTestEmail);
+#else
+ utils_.fake_signin_manager()->SignIn(kTestEmail, "user", "password");
+#endif
}
void IssueRefreshToken() {
- fake_token_service_->GetDelegate()->UpdateCredentials(kTestAccount,
- "token");
+ fake_token_service_->GetDelegate()->UpdateCredentials(kTestEmail, "token");
}
void IssueOAuth2Token() {
- fake_token_service_->IssueAllTokensForAccount(kTestAccount, "access_token",
+ fake_token_service_->IssueAllTokensForAccount(kTestEmail, "access_token",
base::Time::Max());
}
void CancelOAuth2TokenRequests() {
fake_token_service_->IssueErrorForAllPendingRequestsForAccount(
- kTestAccount, GoogleServiceAuthError(
- GoogleServiceAuthError::State::REQUEST_CANCELED));
+ kTestEmail, GoogleServiceAuthError(
+ GoogleServiceAuthError::State::REQUEST_CANCELED));
}
RemoteSuggestionsFetcher::SnippetsAvailableCallback
@@ -415,7 +408,6 @@ class RemoteSuggestionsFetcherImplTestBase
// Initialized lazily in SetFakeResponse().
std::unique_ptr<net::FakeURLFetcherFactory> fake_url_fetcher_factory_;
std::unique_ptr<FakeProfileOAuth2TokenService> fake_token_service_;
- std::unique_ptr<identity::IdentityManager> identity_manager_;
std::unique_ptr<RemoteSuggestionsFetcherImpl> fetcher_;
std::unique_ptr<UserClassifier> user_classifier_;
MockSnippetsAvailableCallback mock_callback_;
diff --git a/chromium/components/password_manager/core/browser/password_syncable_service.cc b/chromium/components/password_manager/core/browser/password_syncable_service.cc
index 4653ac0cf8b..4f959a6ba44 100644
--- a/chromium/components/password_manager/core/browser/password_syncable_service.cc
+++ b/chromium/components/password_manager/core/browser/password_syncable_service.cc
@@ -12,12 +12,8 @@
#include "base/auto_reset.h"
#include "base/location.h"
#include "base/metrics/histogram_macros.h"
-#include "base/optional.h"
-#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/time/default_clock.h"
#include "components/autofill/core/common/password_form.h"
-#include "components/password_manager/core/browser/android_affiliation/affiliation_utils.h"
#include "components/password_manager/core/browser/password_manager_metrics_util.h"
#include "components/password_manager/core/browser/password_store_sync.h"
#include "components/sync/model/sync_error_factory.h"
@@ -40,12 +36,20 @@ std::string MakePasswordSyncTag(const autofill::PasswordForm& password);
namespace {
// Returns true iff |password_specifics| and |password_specifics| are equal
-// in the fields which don't comprise the sync tag.
-bool AreLocalAndSyncPasswordsNonSyncTagEqual(
+// memberwise.
+bool AreLocalAndSyncPasswordsEqual(
const sync_pb::PasswordSpecificsData& password_specifics,
const autofill::PasswordForm& password_form) {
return (password_form.scheme == password_specifics.scheme() &&
+ password_form.signon_realm == password_specifics.signon_realm() &&
+ password_form.origin.spec() == password_specifics.origin() &&
password_form.action.spec() == password_specifics.action() &&
+ base::UTF16ToUTF8(password_form.username_element) ==
+ password_specifics.username_element() &&
+ base::UTF16ToUTF8(password_form.password_element) ==
+ password_specifics.password_element() &&
+ base::UTF16ToUTF8(password_form.username_value) ==
+ password_specifics.username_value() &&
base::UTF16ToUTF8(password_form.password_value) ==
password_specifics.password_value() &&
password_form.preferred == password_specifics.preferred() &&
@@ -62,38 +66,6 @@ bool AreLocalAndSyncPasswordsNonSyncTagEqual(
.Serialize() == password_form.federation_origin.Serialize());
}
-// Returns true iff |password_specifics| and |password_specifics| are equal
-// memberwise.
-bool AreLocalAndSyncPasswordsEqual(
- const sync_pb::PasswordSpecificsData& password_specifics,
- const autofill::PasswordForm& password_form) {
- return (password_form.signon_realm == password_specifics.signon_realm() &&
- password_form.origin.spec() == password_specifics.origin() &&
- base::UTF16ToUTF8(password_form.username_element) ==
- password_specifics.username_element() &&
- base::UTF16ToUTF8(password_form.password_element) ==
- password_specifics.password_element() &&
- base::UTF16ToUTF8(password_form.username_value) ==
- password_specifics.username_value() &&
- AreLocalAndSyncPasswordsNonSyncTagEqual(password_specifics,
- password_form));
-}
-
-// Compares the fields which are not part of the sync tag.
-bool AreNonSyncTagFieldsEqual(const sync_pb::PasswordSpecificsData& left,
- const sync_pb::PasswordSpecificsData& right) {
- return (left.scheme() == right.scheme() && left.action() == right.action() &&
- left.password_value() == right.password_value() &&
- left.preferred() == right.preferred() &&
- left.date_created() == right.date_created() &&
- left.blacklisted() == right.blacklisted() &&
- left.type() == right.type() &&
- left.times_used() == right.times_used() &&
- left.display_name() == right.display_name() &&
- left.avatar_url() == right.avatar_url() &&
- left.federation_url() == right.federation_url());
-}
-
syncer::SyncChange::SyncChangeType GetSyncChangeType(
PasswordStoreChange::Type type) {
switch (type) {
@@ -119,190 +91,6 @@ void AppendPasswordFromSpecifics(
entries->back()->date_synced = sync_time;
}
-// Android autofill saves credential in a different format without trailing '/'.
-std::string GetIncorrectAndroidSignonRealm(std::string android_autofill_realm) {
- if (base::EndsWith(android_autofill_realm, "/", base::CompareCase::SENSITIVE))
- android_autofill_realm.erase(android_autofill_realm.size() - 1);
- return android_autofill_realm;
-}
-
-// The correct Android signon_realm should have a trailing '/'.
-std::string GetCorrectAndroidSignonRealm(std::string android_realm) {
- if (!base::EndsWith(android_realm, "/", base::CompareCase::SENSITIVE))
- android_realm += '/';
- return android_realm;
-}
-
-// Android autofill saves credentials in a different format without trailing
-// '/'. Return a sync tag for the style used by Android Autofill in GMS Core
-// v12.
-std::string AndroidAutofillSyncTag(
- const sync_pb::PasswordSpecificsData& password) {
- // realm has the same value as the origin.
- std::string origin = GetIncorrectAndroidSignonRealm(password.origin());
- std::string signon_realm =
- GetIncorrectAndroidSignonRealm(password.signon_realm());
- return (net::EscapePath(origin) + "|" +
- net::EscapePath(password.username_element()) + "|" +
- net::EscapePath(password.username_value()) + "|" +
- net::EscapePath(password.password_element()) + "|" +
- net::EscapePath(signon_realm));
-}
-
-// Return a sync tag for the correct format used by Android.
-std::string AndroidCorrectSyncTag(
- const sync_pb::PasswordSpecificsData& password) {
- // realm has the same value as the origin.
- std::string origin = GetCorrectAndroidSignonRealm(password.origin());
- std::string signon_realm =
- GetCorrectAndroidSignonRealm(password.signon_realm());
- return (net::EscapePath(origin) + "|" +
- net::EscapePath(password.username_element()) + "|" +
- net::EscapePath(password.username_value()) + "|" +
- net::EscapePath(password.password_element()) + "|" +
- net::EscapePath(signon_realm));
-}
-
-void PasswordSpecificsFromPassword(
- const autofill::PasswordForm& password_form,
- sync_pb::PasswordSpecificsData* password_specifics) {
-#define CopyField(field) password_specifics->set_##field(password_form.field)
-#define CopyStringField(field) \
- password_specifics->set_##field(base::UTF16ToUTF8(password_form.field))
- CopyField(scheme);
- CopyField(signon_realm);
- password_specifics->set_origin(password_form.origin.spec());
- password_specifics->set_action(password_form.action.spec());
- CopyStringField(username_element);
- CopyStringField(password_element);
- CopyStringField(username_value);
- CopyStringField(password_value);
- CopyField(preferred);
- password_specifics->set_date_created(
- password_form.date_created.ToInternalValue());
- password_specifics->set_blacklisted(password_form.blacklisted_by_user);
- CopyField(type);
- CopyField(times_used);
- CopyStringField(display_name);
- password_specifics->set_avatar_url(password_form.icon_url.spec());
- password_specifics->set_federation_url(
- password_form.federation_origin.unique()
- ? std::string()
- : password_form.federation_origin.Serialize());
-#undef CopyStringField
-#undef CopyField
-}
-
-struct AndroidMergeResult {
- // New value for Android entry in the correct format.
- base::Optional<syncer::SyncData> new_android_correct;
- // New value for Android autofill entry.
- base::Optional<syncer::SyncData> new_android_incorrect;
- // New value for local entry in the correct format.
- base::Optional<autofill::PasswordForm> new_local_correct;
- // New value for local entry in the Android autofill format.
- base::Optional<autofill::PasswordForm> new_local_incorrect;
-};
-
-// Perform deduplication of Android credentials saved in the wrong format. As
-// the result all the four entries should be created and have the same value.
-AndroidMergeResult Perform4WayMergeAndroidCredentials(
- const sync_pb::PasswordSpecificsData* correct_android,
- const sync_pb::PasswordSpecificsData* incorrect_android,
- const autofill::PasswordForm* correct_local,
- const autofill::PasswordForm* incorrect_local) {
- AndroidMergeResult result;
-
- base::Optional<sync_pb::PasswordSpecificsData> local_correct_ps;
- if (correct_local) {
- local_correct_ps = sync_pb::PasswordSpecificsData();
- PasswordSpecificsFromPassword(*correct_local, &local_correct_ps.value());
- }
-
- base::Optional<sync_pb::PasswordSpecificsData> local_incorrect_ps;
- if (incorrect_local) {
- local_incorrect_ps = sync_pb::PasswordSpecificsData();
- PasswordSpecificsFromPassword(*incorrect_local,
- &local_incorrect_ps.value());
- }
-
- const sync_pb::PasswordSpecificsData* all_data[4] = {
- correct_android, incorrect_android,
- local_correct_ps ? &local_correct_ps.value() : nullptr,
- local_incorrect_ps ? &local_incorrect_ps.value() : nullptr};
-
- // |newest_data| will point to the newest entry out of all 4.
- const sync_pb::PasswordSpecificsData* newest_data = nullptr;
- for (int i = 0; i < 4; ++i) {
- if (newest_data && all_data[i]) {
- if (all_data[i]->date_created() > newest_data->date_created())
- newest_data = all_data[i];
- } else if (all_data[i]) {
- newest_data = all_data[i];
- }
- }
- DCHECK(newest_data);
-
- const std::string correct_tag = AndroidCorrectSyncTag(*newest_data);
- const std::string incorrect_tag = AndroidAutofillSyncTag(*newest_data);
- const std::string correct_signon_realm =
- GetCorrectAndroidSignonRealm(newest_data->signon_realm());
- const std::string incorrect_signon_realm =
- GetIncorrectAndroidSignonRealm(newest_data->signon_realm());
- const std::string correct_origin =
- GetCorrectAndroidSignonRealm(newest_data->origin());
- const std::string incorrect_origin =
- GetIncorrectAndroidSignonRealm(newest_data->origin());
- DCHECK_EQ(GURL(incorrect_origin).spec(), incorrect_origin);
-
- // Set the correct Sync entry if needed.
- if (newest_data != correct_android &&
- (!correct_android ||
- !AreNonSyncTagFieldsEqual(*correct_android, *newest_data))) {
- sync_pb::EntitySpecifics password_data;
- sync_pb::PasswordSpecificsData* password_specifics =
- password_data.mutable_password()->mutable_client_only_encrypted_data();
- *password_specifics = *newest_data;
- password_specifics->set_origin(correct_origin);
- password_specifics->set_signon_realm(correct_signon_realm);
- result.new_android_correct = syncer::SyncData::CreateLocalData(
- correct_tag, correct_tag, password_data);
- }
-
- // Set the Andoroid Autofill Sync entry if needed.
- if (newest_data != incorrect_android &&
- (!incorrect_android ||
- !AreNonSyncTagFieldsEqual(*incorrect_android, *newest_data))) {
- sync_pb::EntitySpecifics password_data;
- sync_pb::PasswordSpecificsData* password_specifics =
- password_data.mutable_password()->mutable_client_only_encrypted_data();
- *password_specifics = *newest_data;
- password_specifics->set_origin(incorrect_origin);
- password_specifics->set_signon_realm(incorrect_signon_realm);
- result.new_android_incorrect = syncer::SyncData::CreateLocalData(
- incorrect_tag, incorrect_tag, password_data);
- }
-
- // Set the correct local entry if needed.
- if (!local_correct_ps ||
- (newest_data != &local_correct_ps.value() &&
- !AreNonSyncTagFieldsEqual(local_correct_ps.value(), *newest_data))) {
- result.new_local_correct = PasswordFromSpecifics(*newest_data);
- result.new_local_correct.value().origin = GURL(correct_origin);
- result.new_local_correct.value().signon_realm = correct_signon_realm;
- }
-
- // Set the incorrect local entry if needed.
- if (!local_incorrect_ps ||
- (newest_data != &local_incorrect_ps.value() &&
- !AreNonSyncTagFieldsEqual(local_incorrect_ps.value(), *newest_data))) {
- result.new_local_incorrect = PasswordFromSpecifics(*newest_data);
- result.new_local_incorrect.value().origin = GURL(incorrect_origin);
- result.new_local_incorrect.value().signon_realm = incorrect_signon_realm;
- }
- return result;
-}
-
} // namespace
struct PasswordSyncableService::SyncEntries {
@@ -336,9 +124,8 @@ struct PasswordSyncableService::SyncEntries {
PasswordSyncableService::PasswordSyncableService(
PasswordStoreSync* password_store)
- : password_store_(password_store),
- clock_(new base::DefaultClock),
- is_processing_sync_changes_(false) {}
+ : password_store_(password_store), is_processing_sync_changes_(false) {
+}
PasswordSyncableService::~PasswordSyncableService() = default;
@@ -374,12 +161,17 @@ syncer::SyncMergeResult PasswordSyncableService::MergeDataAndStartSyncing(
}
merge_result.set_num_items_before_association(new_local_entries.size());
- // Changes from Sync to be applied locally.
SyncEntries sync_entries;
// Changes from password db that need to be propagated to sync.
syncer::SyncChangeList updated_db_entries;
- MergeSyncDataWithLocalData(initial_sync_data, &new_local_entries,
- &sync_entries, &updated_db_entries);
+ for (syncer::SyncDataList::const_iterator sync_iter =
+ initial_sync_data.begin();
+ sync_iter != initial_sync_data.end(); ++sync_iter) {
+ CreateOrUpdateEntry(*sync_iter,
+ &new_local_entries,
+ &sync_entries,
+ &updated_db_entries);
+ }
for (PasswordEntryMap::iterator it = new_local_entries.begin();
it != new_local_entries.end(); ++it) {
@@ -443,7 +235,7 @@ syncer::SyncError PasswordSyncableService::ProcessSyncChanges(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
base::AutoReset<bool> processing_changes(&is_processing_sync_changes_, true);
SyncEntries sync_entries;
- base::Time time_now = clock_->Now();
+ base::Time time_now = base::Time::Now();
for (syncer::SyncChangeList::const_iterator it = change_list.begin();
it != change_list.end(); ++it) {
@@ -456,13 +248,6 @@ syncer::SyncError PasswordSyncableService::ProcessSyncChanges(
}
AppendPasswordFromSpecifics(
specifics.password().client_only_encrypted_data(), time_now, entries);
- if (IsValidAndroidFacetURI(entries->back()->signon_realm)) {
- // Fix the Android Autofill credentials if needed.
- entries->back()->signon_realm =
- GetCorrectAndroidSignonRealm(entries->back()->signon_realm);
- entries->back()->origin =
- GURL(GetCorrectAndroidSignonRealm(entries->back()->origin.spec()));
- }
}
WriteToPasswordStore(sync_entries);
@@ -553,132 +338,21 @@ void PasswordSyncableService::WriteToPasswordStore(const SyncEntries& entries) {
password_store_->NotifyLoginsChanged(changes);
}
-void PasswordSyncableService::MergeSyncDataWithLocalData(
- const syncer::SyncDataList& sync_data,
- PasswordEntryMap* unmatched_data_from_password_db,
- SyncEntries* sync_entries,
- syncer::SyncChangeList* updated_db_entries) {
- std::map<std::string, const sync_pb::PasswordSpecificsData*> sync_data_map;
- for (const auto& data : sync_data) {
- const sync_pb::EntitySpecifics& specifics = data.GetSpecifics();
- const sync_pb::PasswordSpecificsData* password_specifics =
- &specifics.password().client_only_encrypted_data();
- sync_data_map[MakePasswordSyncTag(*password_specifics)] =
- password_specifics;
- }
- DCHECK_EQ(sync_data_map.size(), sync_data.size());
-
- for (auto it = sync_data_map.begin(); it != sync_data_map.end();) {
- if (IsValidAndroidFacetURI(it->second->signon_realm())) {
- // Perform deduplication of Android credentials saved in the wrong format.
- // For each incorrect entry, a duplicate of it is created in the correct
- // format, so Chrome can make use of it. The incorrect sync entries are
- // not deleted for now.
- std::string incorrect_tag = AndroidAutofillSyncTag(*it->second);
- std::string correct_tag = AndroidCorrectSyncTag(*it->second);
- auto it_sync_incorrect = sync_data_map.find(incorrect_tag);
- auto it_sync_correct = sync_data_map.find(correct_tag);
- auto it_local_data_correct =
- unmatched_data_from_password_db->find(correct_tag);
- auto it_local_data_incorrect =
- unmatched_data_from_password_db->find(incorrect_tag);
- if ((it != it_sync_incorrect && it != it_sync_correct) ||
- (it_sync_incorrect == sync_data_map.end() &&
- it_local_data_incorrect == unmatched_data_from_password_db->end())) {
- // The current credential is in an unexpected format or incorrect
- // credential don't exist. Just do what Sync would normally do.
- CreateOrUpdateEntry(*it->second, unmatched_data_from_password_db,
- sync_entries, updated_db_entries);
- ++it;
- } else {
- AndroidMergeResult result = Perform4WayMergeAndroidCredentials(
- it_sync_correct == sync_data_map.end() ? nullptr
- : it_sync_correct->second,
- it_sync_incorrect == sync_data_map.end()
- ? nullptr
- : it_sync_incorrect->second,
- it_local_data_correct == unmatched_data_from_password_db->end()
- ? nullptr
- : it_local_data_correct->second,
- it_local_data_incorrect == unmatched_data_from_password_db->end()
- ? nullptr
- : it_local_data_incorrect->second);
- // Add or update the correct local entry.
- if (result.new_local_correct) {
- auto* local_changes = sync_entries->EntriesForChangeType(
- it_local_data_correct == unmatched_data_from_password_db->end()
- ? syncer::SyncChange::ACTION_ADD
- : syncer::SyncChange::ACTION_UPDATE);
- local_changes->push_back(std::make_unique<autofill::PasswordForm>(
- result.new_local_correct.value()));
- local_changes->back()->date_synced = clock_->Now();
- }
- // Add or update the incorrect local entry.
- if (result.new_local_incorrect) {
- auto* local_changes = sync_entries->EntriesForChangeType(
- it_local_data_incorrect == unmatched_data_from_password_db->end()
- ? syncer::SyncChange::ACTION_ADD
- : syncer::SyncChange::ACTION_UPDATE);
- local_changes->push_back(std::make_unique<autofill::PasswordForm>(
- result.new_local_incorrect.value()));
- local_changes->back()->date_synced = clock_->Now();
- }
- if (it_local_data_correct != unmatched_data_from_password_db->end())
- unmatched_data_from_password_db->erase(it_local_data_correct);
- if (it_local_data_incorrect != unmatched_data_from_password_db->end())
- unmatched_data_from_password_db->erase(it_local_data_incorrect);
- // Add or update the correct sync entry.
- if (result.new_android_correct) {
- updated_db_entries->push_back(
- syncer::SyncChange(FROM_HERE,
- it_sync_correct == sync_data_map.end()
- ? syncer::SyncChange::ACTION_ADD
- : syncer::SyncChange::ACTION_UPDATE,
- result.new_android_correct.value()));
- }
- // Add or update the Android Autofill sync entry.
- if (result.new_android_incorrect) {
- updated_db_entries->push_back(
- syncer::SyncChange(FROM_HERE,
- it_sync_incorrect == sync_data_map.end()
- ? syncer::SyncChange::ACTION_ADD
- : syncer::SyncChange::ACTION_UPDATE,
- result.new_android_incorrect.value()));
- }
- bool increment = true;
- for (auto sync_data_it : {it_sync_incorrect, it_sync_correct}) {
- if (sync_data_it != sync_data_map.end()) {
- if (sync_data_it == it) {
- it = sync_data_map.erase(it);
- increment = false;
- } else {
- sync_data_map.erase(sync_data_it);
- }
- }
- }
- if (increment)
- ++it;
- }
- } else {
- // Not Android.
- CreateOrUpdateEntry(*it->second, unmatched_data_from_password_db,
- sync_entries, updated_db_entries);
- ++it;
- }
- }
-}
-
+// static
void PasswordSyncableService::CreateOrUpdateEntry(
- const sync_pb::PasswordSpecificsData& password_specifics,
+ const syncer::SyncData& data,
PasswordEntryMap* unmatched_data_from_password_db,
SyncEntries* sync_entries,
syncer::SyncChangeList* updated_db_entries) {
+ const sync_pb::EntitySpecifics& specifics = data.GetSpecifics();
+ const sync_pb::PasswordSpecificsData& password_specifics(
+ specifics.password().client_only_encrypted_data());
std::string tag = MakePasswordSyncTag(password_specifics);
// Check whether the data from sync is already in the password store.
PasswordEntryMap::iterator existing_local_entry_iter =
unmatched_data_from_password_db->find(tag);
- base::Time time_now = clock_->Now();
+ base::Time time_now = base::Time::Now();
if (existing_local_entry_iter == unmatched_data_from_password_db->end()) {
// The sync data is not in the password store, so we need to create it in
// the password store. Add the entry to the new_entries list.
@@ -726,7 +400,31 @@ syncer::SyncData SyncDataFromPassword(
sync_pb::EntitySpecifics password_data;
sync_pb::PasswordSpecificsData* password_specifics =
password_data.mutable_password()->mutable_client_only_encrypted_data();
- PasswordSpecificsFromPassword(password_form, password_specifics);
+#define CopyField(field) password_specifics->set_##field(password_form.field)
+#define CopyStringField(field) \
+ password_specifics->set_##field(base::UTF16ToUTF8(password_form.field))
+ CopyField(scheme);
+ CopyField(signon_realm);
+ password_specifics->set_origin(password_form.origin.spec());
+ password_specifics->set_action(password_form.action.spec());
+ CopyStringField(username_element);
+ CopyStringField(password_element);
+ CopyStringField(username_value);
+ CopyStringField(password_value);
+ CopyField(preferred);
+ password_specifics->set_date_created(
+ password_form.date_created.ToInternalValue());
+ password_specifics->set_blacklisted(password_form.blacklisted_by_user);
+ CopyField(type);
+ CopyField(times_used);
+ CopyStringField(display_name);
+ password_specifics->set_avatar_url(password_form.icon_url.spec());
+ password_specifics->set_federation_url(
+ password_form.federation_origin.unique()
+ ? std::string()
+ : password_form.federation_origin.Serialize());
+#undef CopyStringField
+#undef CopyField
std::string tag = MakePasswordSyncTag(*password_specifics);
return syncer::SyncData::CreateLocalData(tag, tag, password_data);
diff --git a/chromium/components/password_manager/core/browser/password_syncable_service.h b/chromium/components/password_manager/core/browser/password_syncable_service.h
index e2fd572c4fb..d86daac1974 100644
--- a/chromium/components/password_manager/core/browser/password_syncable_service.h
+++ b/chromium/components/password_manager/core/browser/password_syncable_service.h
@@ -11,7 +11,6 @@
#include "base/macros.h"
#include "base/sequence_checker.h"
-#include "base/time/clock.h"
#include "components/password_manager/core/browser/password_store_change.h"
#include "components/sync/model/sync_change.h"
#include "components/sync/model/sync_data.h"
@@ -61,12 +60,6 @@ class PasswordSyncableService : public syncer::SyncableService {
void InjectStartSyncFlare(
const syncer::SyncableService::StartSyncFlare& flare);
-#if defined(UNIT_TEST)
- void set_clock(std::unique_ptr<base::Clock> clock) {
- clock_ = std::move(clock);
- }
-#endif
-
private:
// Map from password sync tag to password form.
typedef std::map<std::string, autofill::PasswordForm*> PasswordEntryMap;
@@ -87,23 +80,14 @@ class PasswordSyncableService : public syncer::SyncableService {
// Uses the |PasswordStore| APIs to change entries.
void WriteToPasswordStore(const SyncEntries& entries);
- // Goes through |sync_data| and for each entry merges the data with
- // |unmatched_data_from_password_db|. The result of merge is recorded in
- // |sync_entries| or |updated_db_entries|. Successfully merged elements are
- // removed from |unmatched_data_from_password_db|.
- void MergeSyncDataWithLocalData(
- const syncer::SyncDataList& sync_data,
- PasswordEntryMap* unmatched_data_from_password_db,
- SyncEntries* sync_entries,
- syncer::SyncChangeList* updated_db_entries);
-
// Examines |data|, an entry in sync db, and updates |sync_entries| or
// |updated_db_entries| accordingly. An element is removed from
// |unmatched_data_from_password_db| if its tag is identical to |data|'s.
- void CreateOrUpdateEntry(const sync_pb::PasswordSpecificsData& data,
- PasswordEntryMap* unmatched_data_from_password_db,
- SyncEntries* sync_entries,
- syncer::SyncChangeList* updated_db_entries);
+ static void CreateOrUpdateEntry(
+ const syncer::SyncData& data,
+ PasswordEntryMap* unmatched_data_from_password_db,
+ SyncEntries* sync_entries,
+ syncer::SyncChangeList* updated_db_entries);
// Calls |operation| for each element in |entries| and appends the changes to
// |all_changes|.
@@ -125,9 +109,6 @@ class PasswordSyncableService : public syncer::SyncableService {
// A signal activated by this class to start sync as soon as possible.
syncer::SyncableService::StartSyncFlare flare_;
- // Clock for date_synced updates.
- std::unique_ptr<base::Clock> clock_;
-
// True if processing sync changes is in progress.
bool is_processing_sync_changes_;
diff --git a/chromium/components/password_manager/core/browser/password_syncable_service_unittest.cc b/chromium/components/password_manager/core/browser/password_syncable_service_unittest.cc
index 9f1975d0895..39c4499a730 100644
--- a/chromium/components/password_manager/core/browser/password_syncable_service_unittest.cc
+++ b/chromium/components/password_manager/core/browser/password_syncable_service_unittest.cc
@@ -15,9 +15,7 @@
#include "base/memory/ref_counted.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_task_environment.h"
-#include "base/test/simple_test_clock.h"
#include "components/password_manager/core/browser/mock_password_store.h"
-#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/sync/model/sync_change_processor.h"
#include "components/sync/model/sync_error.h"
#include "components/sync/model/sync_error_factory_mock.h"
@@ -54,8 +52,6 @@ namespace {
// PasswordForm values for tests.
constexpr autofill::PasswordForm::Type kArbitraryType =
autofill::PasswordForm::TYPE_GENERATED;
-constexpr char kAndroidAutofillRealm[] = "android://hash@com.magisto";
-constexpr char kAndroidCorrectRealm[] = "android://hash@com.magisto/";
constexpr char kIconUrl[] = "https://fb.com/Icon";
constexpr char kDisplayName[] = "Agent Smith";
constexpr char kFederationUrl[] = "https://fb.com/";
@@ -73,8 +69,8 @@ const sync_pb::PasswordSpecificsData& GetPasswordSpecifics(
return sync_data.GetSpecifics().password().client_only_encrypted_data();
}
-MATCHER_P(HasDateSynced, time, "") {
- return arg.date_synced == time;
+MATCHER(HasDateSynced, "") {
+ return !arg.date_synced.is_null() && !arg.date_synced.is_max();
}
MATCHER_P(PasswordIs, form, "") {
@@ -127,14 +123,6 @@ ACTION_P(AppendForm, form) {
return true;
}
-// The argument is std::vector<autofill::PasswordForm*>*. The caller is
-// responsible for the lifetime of all the password forms.
-ACTION_P(AppendForms, forms) {
- for (const autofill::PasswordForm& form : forms)
- arg0->push_back(std::make_unique<autofill::PasswordForm>(form));
- return true;
-}
-
// Creates a sync data consisting of password specifics. The sign on realm is
// set to |signon_realm|.
SyncData CreateSyncData(const std::string& signon_realm) {
@@ -185,14 +173,12 @@ class PasswordSyncableServiceWrapper {
password_store_->Init(syncer::SyncableService::StartSyncFlare(), nullptr);
service_.reset(
new PasswordSyncableService(password_store_->GetSyncInterface()));
- auto clock = std::make_unique<base::SimpleTestClock>();
- clock->SetNow(time());
- service_->set_clock(std::move(clock));
- ON_CALL(*password_store_, AddLoginImpl(HasDateSynced(time())))
+
+ ON_CALL(*password_store_, AddLoginImpl(HasDateSynced()))
.WillByDefault(Return(PasswordStoreChangeList()));
ON_CALL(*password_store_, RemoveLoginImpl(_))
.WillByDefault(Return(PasswordStoreChangeList()));
- ON_CALL(*password_store_, UpdateLoginImpl(HasDateSynced(time())))
+ ON_CALL(*password_store_, UpdateLoginImpl(HasDateSynced()))
.WillByDefault(Return(PasswordStoreChangeList()));
EXPECT_CALL(*password_store(), NotifyLoginsChanged(_)).Times(AnyNumber());
}
@@ -203,8 +189,6 @@ class PasswordSyncableServiceWrapper {
PasswordSyncableService* service() { return service_.get(); }
- static base::Time time() { return base::Time::FromInternalValue(100000); }
-
// Returnes the scoped_ptr to |service_| thus NULLing out it.
std::unique_ptr<syncer::SyncChangeProcessor> ReleaseSyncableService() {
return std::move(service_);
@@ -233,6 +217,7 @@ class PasswordSyncableServiceTest : public testing::Test {
std::unique_ptr<MockSyncChangeProcessor> processor_;
private:
+ // Used by the password store.
base::test::ScopedTaskEnvironment scoped_task_environment_;
PasswordSyncableServiceWrapper wrapper_;
};
@@ -677,546 +662,6 @@ TEST_F(PasswordSyncableServiceTest, SerializeNonEmptyPasswordForm) {
EXPECT_EQ("https://google.com", specifics.federation_url());
}
-// Tests for Android Autofill credentials. Those are saved in the wrong format
-// without trailing '/'. Nevertheless, password store should always contain the
-// correct values.
-class PasswordSyncableServiceAndroidAutofillTest : public testing::Test {
- public:
- PasswordSyncableServiceAndroidAutofillTest() = default;
-
- static PasswordFormData android_incorrect(double creation_time) {
- PasswordFormData data = {autofill::PasswordForm::SCHEME_HTML,
- kAndroidAutofillRealm,
- kAndroidAutofillRealm,
- "",
- L"",
- L"",
- L"",
- L"username_value_1",
- L"11111",
- true,
- creation_time};
- return data;
- }
-
- static PasswordFormData android_correct(double creation_time) {
- PasswordFormData data = {autofill::PasswordForm::SCHEME_HTML,
- kAndroidCorrectRealm,
- kAndroidCorrectRealm,
- "",
- L"",
- L"",
- L"",
- L"username_value_1",
- L"22222",
- true,
- creation_time};
- return data;
- }
-
- static PasswordFormData android_incorrect2(double creation_time) {
- PasswordFormData data = {autofill::PasswordForm::SCHEME_HTML,
- kAndroidAutofillRealm,
- kAndroidAutofillRealm,
- "",
- L"",
- L"",
- L"",
- L"username_value_1",
- L"33333",
- false,
- creation_time};
- return data;
- }
-
- static PasswordFormData android_correct2(double creation_time) {
- PasswordFormData data = {autofill::PasswordForm::SCHEME_HTML,
- kAndroidCorrectRealm,
- kAndroidCorrectRealm,
- "",
- L"",
- L"",
- L"",
- L"username_value_1",
- L"444444",
- false,
- creation_time};
- return data;
- }
-
- static autofill::PasswordForm FormWithCorrectTag(PasswordFormData data) {
- autofill::PasswordForm form = *FillPasswordFormWithData(data);
- form.signon_realm = kAndroidCorrectRealm;
- form.origin = GURL(kAndroidCorrectRealm);
- form.date_synced = PasswordSyncableServiceWrapper::time();
- return form;
- }
-
- static autofill::PasswordForm FormWithAndroidAutofillTag(
- PasswordFormData data) {
- autofill::PasswordForm form = *FillPasswordFormWithData(data);
- form.signon_realm = kAndroidAutofillRealm;
- form.origin = GURL(kAndroidAutofillRealm);
- form.date_synced = PasswordSyncableServiceWrapper::time();
- return form;
- }
-
- // Transforms |val| into |count| numbers from 1 to |count| inclusive.
- static std::vector<unsigned> ExtractTimestamps(unsigned val, unsigned count) {
- std::vector<unsigned> result;
- for (unsigned i = 0; i < count; ++i) {
- result.push_back(val % count + 1);
- val /= count;
- }
- return result;
- }
-
- static testing::Message FormDataMessage(const std::string& prefix,
- const PasswordFormData* data) {
- testing::Message message;
- message << prefix;
- if (data)
- message << *FillPasswordFormWithData(*data);
- else
- message << "NULL";
- return message;
- }
-
- protected:
- base::test::ScopedTaskEnvironment scoped_task_environment_;
-};
-
-TEST_F(PasswordSyncableServiceAndroidAutofillTest, FourWayMerge) {
- for (unsigned val = 0; val < 4 * 4 * 4 * 4; ++val) {
- // Generate 4 creation timestamps for all the entries.
- std::vector<unsigned> dates = ExtractTimestamps(val, 4);
- ASSERT_EQ(4u, dates.size());
- const unsigned latest = *std::max_element(dates.begin(), dates.end());
- // Sync correct, Sync Android autofill, local correct, local incorrect.
- const PasswordFormData data[4] = {
- android_correct(dates[0]), android_incorrect(dates[1]),
- android_correct2(dates[2]), android_incorrect2(dates[3])};
- const PasswordFormData* latest_data =
- std::find_if(data, data + 4, [latest](const PasswordFormData& data) {
- return data.creation_time == latest;
- });
- ASSERT_TRUE(latest_data);
- std::vector<autofill::PasswordForm> expected_sync_updates;
- if (latest_data != &data[0])
- expected_sync_updates.push_back(FormWithCorrectTag(*latest_data));
- if (latest_data != &data[1])
- expected_sync_updates.push_back(FormWithAndroidAutofillTag(*latest_data));
- autofill::PasswordForm local_correct = *FillPasswordFormWithData(data[2]);
- autofill::PasswordForm local_incorrect = *FillPasswordFormWithData(data[3]);
- syncer::SyncData sync_correct =
- SyncDataFromPassword(*FillPasswordFormWithData(data[0]));
- syncer::SyncData sync_incorrect =
- SyncDataFromPassword(*FillPasswordFormWithData(data[1]));
-
- SCOPED_TRACE(*FillPasswordFormWithData(data[0]));
- SCOPED_TRACE(*FillPasswordFormWithData(data[1]));
- SCOPED_TRACE(*FillPasswordFormWithData(data[2]));
- SCOPED_TRACE(*FillPasswordFormWithData(data[3]));
-
- for (bool correct_sync_first : {true, false}) {
- auto wrapper = std::make_unique<PasswordSyncableServiceWrapper>();
- auto processor =
- std::make_unique<testing::StrictMock<MockSyncChangeProcessor>>();
-
- std::vector<autofill::PasswordForm> stored_forms = {local_correct,
- local_incorrect};
- EXPECT_CALL(*wrapper->password_store(), FillAutofillableLogins(_))
- .WillOnce(AppendForms(stored_forms));
- EXPECT_CALL(*wrapper->password_store(), FillBlacklistLogins(_))
- .WillOnce(Return(true));
- if (latest_data != &data[2]) {
- EXPECT_CALL(*wrapper->password_store(),
- UpdateLoginImpl(FormWithCorrectTag(*latest_data)));
- }
- if (latest_data != &data[3]) {
- EXPECT_CALL(*wrapper->password_store(),
- UpdateLoginImpl(FormWithAndroidAutofillTag(*latest_data)));
- }
-
- if (expected_sync_updates.size() == 1) {
- EXPECT_CALL(*processor,
- ProcessSyncChanges(_, ElementsAre(SyncChangeIs(
- SyncChange::ACTION_UPDATE,
- expected_sync_updates[0]))));
- } else {
- EXPECT_CALL(
- *processor,
- ProcessSyncChanges(_, UnorderedElementsAre(
- SyncChangeIs(SyncChange::ACTION_UPDATE,
- expected_sync_updates[0]),
- SyncChangeIs(SyncChange::ACTION_UPDATE,
- expected_sync_updates[1]))));
- }
-
- SyncDataList sync_list = {sync_correct, sync_incorrect};
- if (!correct_sync_first)
- std::swap(sync_list[0], sync_list[1]);
- wrapper->service()->MergeDataAndStartSyncing(
- syncer::PASSWORDS, sync_list, std::move(processor),
- std::unique_ptr<syncer::SyncErrorFactory>());
- wrapper.reset();
- // Wait til PasswordStore is destroy end therefore all the expectations on
- // it are checked.
- scoped_task_environment_.RunUntilIdle();
- }
- }
-}
-
-TEST_F(PasswordSyncableServiceAndroidAutofillTest, ThreeWayMerge) {
- for (int j = 0; j < 4; ++j) {
- // Whether the entry exists: Sync correct, Sync Android autofill,
- // local correct, local incorrect.
- bool entry_present[4] = {true, true, true, true};
- entry_present[j] = false;
- for (unsigned val = 0; val < 3 * 3 * 3; ++val) {
- // Generate 3 creation timestamps for all the entries.
- std::vector<unsigned> dates = ExtractTimestamps(val, 3);
- ASSERT_EQ(3u, dates.size());
- const unsigned latest = *std::max_element(dates.begin(), dates.end());
-
- // Sync correct, Sync Android autofill, local correct, local incorrect.
- std::vector<std::unique_ptr<PasswordFormData>> data;
- int date_index = 0;
- data.push_back(entry_present[0]
- ? std::make_unique<PasswordFormData>(
- android_correct(dates[date_index++]))
- : nullptr);
- data.push_back(entry_present[1]
- ? std::make_unique<PasswordFormData>(
- android_incorrect(dates[date_index++]))
- : nullptr);
- data.push_back(entry_present[2]
- ? std::make_unique<PasswordFormData>(
- android_correct2(dates[date_index++]))
- : nullptr);
- data.push_back(entry_present[3]
- ? std::make_unique<PasswordFormData>(
- android_incorrect2(dates[date_index++]))
- : nullptr);
-
- SCOPED_TRACE(val);
- SCOPED_TRACE(j);
- SCOPED_TRACE(FormDataMessage("data[0]=", data[0].get()));
- SCOPED_TRACE(FormDataMessage("data[1]=", data[1].get()));
- SCOPED_TRACE(FormDataMessage("data[2]=", data[2].get()));
- SCOPED_TRACE(FormDataMessage("data[3]=", data[3].get()));
-
- const PasswordFormData* latest_data =
- std::find_if(data.begin(), data.end(),
- [latest](const std::unique_ptr<PasswordFormData>& data) {
- return data && data->creation_time == latest;
- })
- ->get();
- ASSERT_TRUE(latest_data);
- std::vector<std::pair<SyncChange::SyncChangeType, autofill::PasswordForm>>
- expected_sync_updates;
- for (int i = 0; i < 2; ++i) {
- if (latest_data != data[i].get()) {
- expected_sync_updates.push_back(std::make_pair(
- data[i] ? SyncChange::ACTION_UPDATE : SyncChange::ACTION_ADD,
- i == 0 ? FormWithCorrectTag(*latest_data)
- : FormWithAndroidAutofillTag(*latest_data)));
- }
- }
-
- std::vector<autofill::PasswordForm> stored_forms;
- for (int i = 2; i < 4; ++i) {
- if (data[i])
- stored_forms.push_back(*FillPasswordFormWithData(*data[i]));
- }
-
- SyncDataList sync_list;
- for (int i = 0; i < 2; ++i) {
- if (data[i]) {
- sync_list.push_back(
- SyncDataFromPassword(*FillPasswordFormWithData(*data[i])));
- }
- }
-
- for (bool swap_sync_list : {false, true}) {
- auto wrapper = std::make_unique<PasswordSyncableServiceWrapper>();
- auto processor =
- std::make_unique<testing::StrictMock<MockSyncChangeProcessor>>();
-
- EXPECT_CALL(*wrapper->password_store(), FillAutofillableLogins(_))
- .WillOnce(AppendForms(stored_forms));
- EXPECT_CALL(*wrapper->password_store(), FillBlacklistLogins(_))
- .WillOnce(Return(true));
- for (int i = 2; i < 4; ++i) {
- if (latest_data != data[i].get()) {
- autofill::PasswordForm latest_form =
- i == 2 ? FormWithCorrectTag(*latest_data)
- : FormWithAndroidAutofillTag(*latest_data);
- if (data[i]) {
- EXPECT_CALL(*wrapper->password_store(),
- UpdateLoginImpl(latest_form));
- } else {
- EXPECT_CALL(*wrapper->password_store(),
- AddLoginImpl(latest_form));
- }
- }
- }
-
- if (expected_sync_updates.size() == 0) {
- EXPECT_CALL(*processor, ProcessSyncChanges(_, IsEmpty()));
- } else if (expected_sync_updates.size() == 1) {
- EXPECT_CALL(
- *processor,
- ProcessSyncChanges(_, ElementsAre(SyncChangeIs(
- expected_sync_updates[0].first,
- expected_sync_updates[0].second))));
- } else if (expected_sync_updates.size() == 2) {
- EXPECT_CALL(
- *processor,
- ProcessSyncChanges(
- _, UnorderedElementsAre(
- SyncChangeIs(expected_sync_updates[0].first,
- expected_sync_updates[0].second),
- SyncChangeIs(expected_sync_updates[1].first,
- expected_sync_updates[1].second))));
- }
-
- if (swap_sync_list && sync_list.size() == 2)
- std::swap(sync_list[0], sync_list[1]);
- wrapper->service()->MergeDataAndStartSyncing(
- syncer::PASSWORDS, sync_list, std::move(processor),
- std::unique_ptr<syncer::SyncErrorFactory>());
- wrapper.reset();
- // Wait til PasswordStore is destroy end therefore all the expectations
- // on it are checked.
- scoped_task_environment_.RunUntilIdle();
- }
- }
- }
-}
-
-TEST_F(PasswordSyncableServiceAndroidAutofillTest, TwoWayServerAndLocalMerge) {
- for (unsigned i = 0; i < 2 * 2; ++i) {
- // Generate 4 different combinations for local/server entries.
- std::vector<unsigned> combination = ExtractTimestamps(i, 2);
- ASSERT_EQ(2u, combination.size());
- const bool sync_data_correct = !!combination[0];
- const bool local_data_correct = !!combination[1];
-
- for (unsigned val = 0; val < 2 * 2; ++val) {
- std::vector<unsigned> dates = ExtractTimestamps(val, 2);
- ASSERT_EQ(2u, dates.size());
-
- const PasswordFormData sync_data = sync_data_correct
- ? android_correct(dates[0])
- : android_incorrect(dates[0]);
- const PasswordFormData local_data = local_data_correct
- ? android_correct2(dates[1])
- : android_incorrect2(dates[1]);
-
- const PasswordFormData* latest_data =
- dates[1] > dates[0] ? &local_data : &sync_data;
-
- auto wrapper = std::make_unique<PasswordSyncableServiceWrapper>();
- auto processor =
- std::make_unique<testing::StrictMock<MockSyncChangeProcessor>>();
-
- EXPECT_CALL(*wrapper->password_store(), FillAutofillableLogins(_))
- .WillOnce(AppendForm(*FillPasswordFormWithData(local_data)));
- EXPECT_CALL(*wrapper->password_store(), FillBlacklistLogins(_))
- .WillOnce(Return(true));
- if (!local_data_correct || latest_data == &sync_data) {
- if (local_data_correct) {
- EXPECT_CALL(*wrapper->password_store(),
- UpdateLoginImpl(FormWithCorrectTag(*latest_data)));
- } else {
- EXPECT_CALL(*wrapper->password_store(),
- AddLoginImpl(FormWithCorrectTag(*latest_data)));
- }
- }
- if (!local_data_correct && latest_data == &sync_data) {
- EXPECT_CALL(*wrapper->password_store(),
- UpdateLoginImpl(FormWithAndroidAutofillTag(*latest_data)));
- } else if (local_data_correct && !sync_data_correct) {
- EXPECT_CALL(*wrapper->password_store(),
- AddLoginImpl(FormWithAndroidAutofillTag(*latest_data)));
- }
-
- std::vector<std::pair<SyncChange::SyncChangeType, autofill::PasswordForm>>
- expected_sync_updates;
- // Deal with the correct sync entry and incorrect one.
- if (sync_data_correct) {
- if (latest_data != &sync_data) {
- expected_sync_updates.push_back(std::make_pair(
- SyncChange::ACTION_UPDATE, FormWithCorrectTag(*latest_data)));
- }
- if (!local_data_correct) {
- expected_sync_updates.push_back(
- std::make_pair(SyncChange::ACTION_ADD,
- FormWithAndroidAutofillTag(*latest_data)));
- }
- } else {
- expected_sync_updates.push_back(std::make_pair(
- SyncChange::ACTION_ADD, FormWithCorrectTag(*latest_data)));
- if (latest_data != &sync_data) {
- expected_sync_updates.push_back(
- std::make_pair(SyncChange::ACTION_UPDATE,
- FormWithAndroidAutofillTag(*latest_data)));
- }
- }
-
- // Set expectation on |processor|.
- if (expected_sync_updates.size() == 0) {
- EXPECT_CALL(*processor, ProcessSyncChanges(_, IsEmpty()));
- } else if (expected_sync_updates.size() == 1) {
- EXPECT_CALL(
- *processor,
- ProcessSyncChanges(
- _, ElementsAre(SyncChangeIs(expected_sync_updates[0].first,
- expected_sync_updates[0].second))));
- } else if (expected_sync_updates.size() == 2) {
- EXPECT_CALL(*processor,
- ProcessSyncChanges(
- _, UnorderedElementsAre(
- SyncChangeIs(expected_sync_updates[0].first,
- expected_sync_updates[0].second),
- SyncChangeIs(expected_sync_updates[1].first,
- expected_sync_updates[1].second))));
- }
-
- SyncDataList sync_list = {
- SyncDataFromPassword(*FillPasswordFormWithData(sync_data))};
- wrapper->service()->MergeDataAndStartSyncing(
- syncer::PASSWORDS, sync_list, std::move(processor),
- std::unique_ptr<syncer::SyncErrorFactory>());
- wrapper.reset();
- // Wait til PasswordStore is destroy end therefore all the expectations on
- // it are checked.
- scoped_task_environment_.RunUntilIdle();
- }
- }
-}
-
-TEST_F(PasswordSyncableServiceAndroidAutofillTest, OneEntryOnly) {
- for (int i = 0; i < 3; ++i) {
- // The case when only local incorrect entry exists is excluded. It's very
- // exotic because a local incorrect entry can come only from the server.
- // In such a case a copy will be uploaded to the server and next
- // MergeDataAndStartSyncing will do a proper migration.
- SCOPED_TRACE(i);
- // Whether the entry exists: Sync correct, Sync Android autofill,
- // local correct, local incorrect.
- const bool entry_is_correct = i == 0 || i == 2;
- const bool entry_is_local = i >= 2;
- PasswordFormData data =
- entry_is_correct ? android_correct(100) : android_incorrect(100);
-
- auto wrapper = std::make_unique<PasswordSyncableServiceWrapper>();
- auto processor =
- std::make_unique<testing::StrictMock<MockSyncChangeProcessor>>();
-
- if (entry_is_local) {
- EXPECT_CALL(*wrapper->password_store(), FillAutofillableLogins(_))
- .WillOnce(AppendForm(*FillPasswordFormWithData(data)));
- } else {
- EXPECT_CALL(*wrapper->password_store(), FillAutofillableLogins(_))
- .WillOnce(Return(true));
- }
- EXPECT_CALL(*wrapper->password_store(), FillBlacklistLogins(_))
- .WillOnce(Return(true));
- if (!entry_is_local && !entry_is_correct) {
- EXPECT_CALL(*wrapper->password_store(),
- AddLoginImpl(FormWithAndroidAutofillTag(data)));
- }
- if (!entry_is_local) {
- EXPECT_CALL(*wrapper->password_store(),
- AddLoginImpl(FormWithCorrectTag(data)));
- }
-
- if (entry_is_correct && !entry_is_local) {
- EXPECT_CALL(*processor, ProcessSyncChanges(_, IsEmpty()));
- } else {
- EXPECT_CALL(*processor,
- ProcessSyncChanges(
- _, ElementsAre(SyncChangeIs(SyncChange::ACTION_ADD,
- FormWithCorrectTag(data)))));
- }
-
- SyncDataList sync_list;
- if (!entry_is_local) {
- sync_list.push_back(
- SyncDataFromPassword(*FillPasswordFormWithData(data)));
- }
- wrapper->service()->MergeDataAndStartSyncing(
- syncer::PASSWORDS, sync_list, std::move(processor),
- std::unique_ptr<syncer::SyncErrorFactory>());
- wrapper.reset();
- // Wait til PasswordStore is destroy end therefore all the expectations on
- // it are checked.
- scoped_task_environment_.RunUntilIdle();
- }
-}
-
-TEST_F(PasswordSyncableServiceAndroidAutofillTest, FourEqualEntries) {
- // Sync correct, Sync Android autofill, local correct, local incorrect with
- // the same content. Nothing should happen.
- const PasswordFormData data = android_correct(100);
- autofill::PasswordForm local_correct = FormWithCorrectTag(data);
- autofill::PasswordForm local_incorrect = FormWithAndroidAutofillTag(data);
- syncer::SyncData sync_correct = SyncDataFromPassword(local_correct);
- syncer::SyncData sync_incorrect = SyncDataFromPassword(local_incorrect);
-
- for (bool correct_sync_first : {true, false}) {
- auto wrapper = std::make_unique<PasswordSyncableServiceWrapper>();
- auto processor =
- std::make_unique<testing::StrictMock<MockSyncChangeProcessor>>();
-
- std::vector<autofill::PasswordForm> stored_forms = {local_correct,
- local_incorrect};
- EXPECT_CALL(*wrapper->password_store(), FillAutofillableLogins(_))
- .WillOnce(AppendForms(stored_forms));
- EXPECT_CALL(*wrapper->password_store(), FillBlacklistLogins(_))
- .WillOnce(Return(true));
- EXPECT_CALL(*processor, ProcessSyncChanges(_, IsEmpty()));
-
- SyncDataList sync_list = {sync_correct, sync_incorrect};
- if (!correct_sync_first)
- std::swap(sync_list[0], sync_list[1]);
- wrapper->service()->MergeDataAndStartSyncing(
- syncer::PASSWORDS, sync_list, std::move(processor),
- std::unique_ptr<syncer::SyncErrorFactory>());
- wrapper.reset();
- // Wait til PasswordStore is destroy end therefore all the expectations on
- // it are checked.
- scoped_task_environment_.RunUntilIdle();
- }
-}
-
-TEST_F(PasswordSyncableServiceAndroidAutofillTest, AndroidCorrectEqualEntries) {
- // Sync correct, local correct with the same content. Nothing should happen.
- const PasswordFormData data = android_correct(100);
- autofill::PasswordForm local_correct = FormWithCorrectTag(data);
- syncer::SyncData sync_correct = SyncDataFromPassword(local_correct);
-
- auto wrapper = std::make_unique<PasswordSyncableServiceWrapper>();
- auto processor =
- std::make_unique<testing::StrictMock<MockSyncChangeProcessor>>();
-
- EXPECT_CALL(*wrapper->password_store(), FillAutofillableLogins(_))
- .WillOnce(AppendForm(local_correct));
- EXPECT_CALL(*wrapper->password_store(), FillBlacklistLogins(_))
- .WillOnce(Return(true));
- EXPECT_CALL(*processor, ProcessSyncChanges(_, IsEmpty()));
-
- wrapper->service()->MergeDataAndStartSyncing(
- syncer::PASSWORDS, {sync_correct}, std::move(processor),
- std::unique_ptr<syncer::SyncErrorFactory>());
- wrapper.reset();
- // Wait til PasswordStore is destroy end therefore all the expectations on
- // it are checked.
- scoped_task_environment_.RunUntilIdle();
-}
-
} // namespace
} // namespace password_manager
diff --git a/chromium/components/safe_browsing/proto/csd.proto b/chromium/components/safe_browsing/proto/csd.proto
index 842637175ae..f84453864fa 100644
--- a/chromium/components/safe_browsing/proto/csd.proto
+++ b/chromium/components/safe_browsing/proto/csd.proto
@@ -1146,3 +1146,18 @@ message NotificationImageReportRequest {
// (even if the image URL is cross-origin). Otherwise a website could mislead
// Safe Browsing into associating phishing image bitmaps with safe image URLs.
}
+
+// Protobuf for Chrome extension webstore install request.
+message ExtensionWebStoreInstallRequest {
+ // If we can find the complete referrer chain, this field will contain URL
+ // transitions from landing referrer to event in reverse chronological
+ // order, i.e. event url comes first in this list, and landing referrer
+ // comes last.
+ // For Safe Browsing Extended Reporting or Scout users, if the referrer
+ // chain is empty or partially missing, we will add/append recent navigation
+ // events to this list. The type of these entries will be RECENT_NAVIGATION.
+ repeated ReferrerChainEntry referrer_chain = 1;
+
+ // Options and metadata about the above referrer chain.
+ optional ReferrerChainOptions referrer_chain_options = 2;
+}
diff --git a/chromium/components/strings/components_strings_mr.xtb b/chromium/components/strings/components_strings_mr.xtb
index 7d8cef25840..67145b8dfcd 100644
--- a/chromium/components/strings/components_strings_mr.xtb
+++ b/chromium/components/strings/components_strings_mr.xtb
@@ -647,7 +647,7 @@
<translation id="5719499550583120431">प्रीपेड कार्डे स्वीकारली जातात.</translation>
<translation id="5720705177508910913">वर्तमान वापरकर्ता</translation>
<translation id="5732392974455271431">आपले पालक तुमच्यासाठी ती अनावरोधित करू शकतात</translation>
-<translation id="5763042198335101085">वैध ईमेल पत्ता एंटर करा</translation>
+<translation id="5763042198335101085">वैध ईमेल अॅड्रेस एंटर करा</translation>
<translation id="5765072501007116331">वितरण पद्धती आणि आवश्यकता पाहण्यासाठी, एक पत्ता निवडा</translation>
<translation id="5770114862687765385">फाइल करप्ट आहे असे दिसते. सेशन रीसेट करण्यासाठी 'रीसेट करा' बटणावर क्लिक करा.</translation>
<translation id="5778550464785688721">MIDI डिव्हाइसेस पूर्ण नियंत्रण</translation>
diff --git a/chromium/components/strings/components_strings_no.xtb b/chromium/components/strings/components_strings_no.xtb
index 3e8755086b2..df9d93ba04b 100644
--- a/chromium/components/strings/components_strings_no.xtb
+++ b/chromium/components/strings/components_strings_no.xtb
@@ -259,6 +259,7 @@
<translation id="2835170189407361413">Slett skjemaet</translation>
<translation id="2851634818064021665">Du trenger tillatelse for å besøke dette nettstedet</translation>
<translation id="2856444702002559011">Det kan hende at angripere prøver å stjele informasjonen din fra <ph name="BEGIN_BOLD" /><ph name="SITE" /><ph name="END_BOLD" /> (for eksempel passord, meldinger og kredittkortinformasjon). <ph name="BEGIN_LEARN_MORE_LINK" />Finn ut mer<ph name="END_LEARN_MORE_LINK" /></translation>
+<translation id="2881276955470682203">Vil du lagre kortet?</translation>
<translation id="2909946352844186028">En nettverksendring ble oppdaget.</translation>
<translation id="2916038427272391327">Lukk andre programmer</translation>
<translation id="2922350208395188000">Tjenerens sertifikat kan ikke kontrolleres.</translation>
@@ -1073,4 +1074,5 @@
&lt;li&gt;Prøv å avinstallere eller slå av «<ph name="SOFTWARE_NAME" />»&lt;/li&gt;
&lt;li&gt;Prøv å koble til et annet nettverk&lt;/li&gt;
&lt;/ul&gt;</translation>
+<translation id="997986563973421916">Fra Google Pay</translation>
</translationbundle> \ No newline at end of file
diff --git a/chromium/components/viz/service/display/gl_renderer.cc b/chromium/components/viz/service/display/gl_renderer.cc
index 66a93a56b75..345f72d6684 100644
--- a/chromium/components/viz/service/display/gl_renderer.cc
+++ b/chromium/components/viz/service/display/gl_renderer.cc
@@ -2128,7 +2128,7 @@ void GLRenderer::DrawContentQuadNoAA(const ContentDrawQuadBase* quad,
// clamping to tex_coord_rect in all cases would cause these border
// texels to not be sampled. Therefore, only clamp texture coordinates
// for external edge bottom/right tiles that don't have content all
- // the way to the edge.
+ // the way to the edge and are using bilinear filtering.
gfx::Size texture_size = quad->texture_size;
bool fills_right_edge =
quad->shared_quad_state->quad_layer_rect.right() != quad->rect.right() ||
@@ -2137,7 +2137,7 @@ void GLRenderer::DrawContentQuadNoAA(const ContentDrawQuadBase* quad,
quad->rect.bottom() ||
texture_size.height() == tex_coord_rect.bottom();
bool has_tex_clamp_rect =
- (!fills_right_edge || !fills_bottom_edge) && !quad->nearest_neighbor;
+ filter == GL_LINEAR && (!fills_right_edge || !fills_bottom_edge);
gfx::SizeF tex_clamp_size(texture_size);
// Clamp from the original tex coord rect, instead of the one that has
// been adjusted by the visible rect.