diff --git a/DEPS b/DEPS index f5fbf56..4cb279e 100644 --- a/DEPS +++ b/DEPS
@@ -129,7 +129,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '76e626d9bb555d2a831b1f91b37e93649bfbd71d', + 'skia_revision': '25e371f7ee5a770ba0d7fe5b8b51887c616cc52b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -141,11 +141,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': 'e6b23e45b380bee1a2dfda06e4728d24d4d4ad8b', + 'angle_revision': 'd581f918e90dd5a1e827ddc15abf83a17656262c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': '5d64ec4c2dcd5dbeac89a1f5e50bb3d6619081cd', + 'swiftshader_revision': 'f41ca6b57107978252fdd14deaefe9fbc396c86c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -196,7 +196,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': 'd27288f5266a4ebf69de7cc91dc865707425736b', + 'catapult_revision': '50b06f012a60d306c1edafb6544fb9e36f07e645', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -260,15 +260,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spirv_cross_revision': '69b034f26e28a76a6f4e5d9521123072b24d7ea2', + 'spirv_cross_revision': 'f07a4e16a60e1d0231dda5d3883550761bd70a47', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'shaderc_revision': '6ff17fe32fd2e0b6bc1890befaf036d526b24540', + 'shaderc_revision': 'ff9ae40e3734a264a56bba02191f5ae18c7e5e03', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'dawn_revision': '51fd66e3dd35d4ed80dc64244a6dd132e2321fa7', + 'dawn_revision': '9a9b837519953393aa8c76dd4f6df6090fba08c7', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -805,7 +805,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f21ce663029c3172c162dae0a199f5be5a0c9991', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f5a6b40dd0b3dc5181f6898236e04622ff2a640d', 'condition': 'checkout_linux', }, @@ -830,7 +830,7 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '6379cd39a3336ab8716c77b1c68ab37ff406d060', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'a67950d67088163e315e3bc4c6d66fb1968f2724', 'src/third_party/devtools-node-modules': Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'), @@ -1172,7 +1172,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'de4e8874ae8261e916af8c5e1926149f8b8540d9', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '2072d9bde71d3bfeef6d03b1bf165e2eaa06d183', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78', @@ -1343,7 +1343,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '688fbfe33779392aa210d67d4aa12cb012f112c2', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '7ddef1af885921e74076b1c2f6695231b48e5ace', + Var('webrtc_git') + '/src.git' + '@' + '21d42d27103eedfa24696e4168a44bd1cbade2ee', 'src/third_party/xdg-utils': { 'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d', @@ -1384,7 +1384,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@3ec1a396fb7932f2fa19253833dd2229394056b4', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c1ad291dcb9c9d1b97ca42d16739693531f1af52', 'condition': 'checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index 4d7f817..d12491a47 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -728,6 +728,9 @@ 'chromeos/services/cellular_setup/|'\ 'ui/webui/resources/cr_components/chromeos/cellular_setup/', }, + 'chromeos_device_policy': { + 'filepath': 'components/policy/proto/chrome_device_policy.proto' + }, 'chromeos_geolocation': { 'filepath': 'chromeos/geolocation/', }, @@ -2137,6 +2140,7 @@ 'chromeos_calculator': ['dharcourt@chromium.org'], 'chromeos_cellular': ['azeemarshad+watch-cellular@chromium.org', 'khorimoto+watch-cellular@chromium.org'], + 'chromeos_device_policy': ['ljusten+watch@chromium.org'], 'chromeos_geolocation': ['alemate+watch@chromium.org'], 'chromeos_lkgm': ['achuith+watch@chromium.org', 'bpastene+watch@chromium.org',
diff --git a/android_webview/browser/gfx/aw_draw_fn_impl.cc b/android_webview/browser/gfx/aw_draw_fn_impl.cc index 4299b44..245a3b1 100644 --- a/android_webview/browser/gfx/aw_draw_fn_impl.cc +++ b/android_webview/browser/gfx/aw_draw_fn_impl.cc
@@ -16,6 +16,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "gpu/ipc/common/android/android_image_reader_utils.h" +#include "gpu/vulkan/vulkan_fence_helper.h" #include "gpu/vulkan/vulkan_function_pointers.h" #include "gpu/vulkan/vulkan_implementation.h" #include "jni/AwDrawFnImpl_jni.h" @@ -38,6 +39,18 @@ namespace { GLNonOwnedCompatibilityContext* g_gl_context = nullptr; + +void CleanupInFlightDraw(sk_sp<GrVkSecondaryCBDrawContext> draw_context, + VkSemaphore post_draw_semaphore, + gpu::VulkanDeviceQueue* device_queue, + bool /* context_lost */) { + VkDevice device = device_queue->GetVulkanDevice(); + // We do the same thing whether or not context is lost. + draw_context->releaseResources(); + draw_context.reset(); + if (post_draw_semaphore != VK_NULL_HANDLE) + vkDestroySemaphore(device, post_draw_semaphore, nullptr); +} } class GLNonOwnedCompatibilityContext : public gl::GLContextEGL { @@ -177,33 +190,6 @@ return SkColorSpace::MakeRGB(transfer_fn, to_xyz); } -// Create a VkFence and submit it to the queue. -VkFence CreateAndSubmitFence(VkDevice device, VkQueue queue) { - VkFence fence = VK_NULL_HANDLE; - VkFenceCreateInfo create_info{ - .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - }; - - auto result = - vkCreateFence(device, &create_info, nullptr /* pAllocator */, &fence); - if (result != VK_SUCCESS) { - LOG(ERROR) << "Could not create VkFence."; - return VK_NULL_HANDLE; - } - - result = - vkQueueSubmit(queue, 0 /* submitCount */, nullptr /* pSubmits */, fence); - if (result != VK_SUCCESS) { - LOG(ERROR) << "Could not create VkFence."; - vkDestroyFence(device, fence, nullptr /* pAllocator */); - return VK_NULL_HANDLE; - } - - return fence; -} - } // namespace static void JNI_AwDrawFnImpl_SetDrawFnFunctionTable(JNIEnv* env, @@ -277,31 +263,8 @@ false /* save_restore */); } - if (!in_flight_draws_.empty()) { - DCHECK(!is_interop_mode_); - // Make sure the last pending draw is finished, and then we can destroy all - // pending draws safely. - VkFence last_fence = in_flight_draws_.back().fence; - VkDevice device = - vulkan_context_provider_->GetDeviceQueue()->GetVulkanDevice(); - VkResult result = - vkWaitForFences(device, 1, &last_fence, VK_TRUE, - base::TimeDelta::FromSeconds(60).InNanoseconds()); - DCHECK_EQ(result, VK_SUCCESS); - while (!in_flight_draws_.empty()) { - auto& draw = in_flight_draws_.front(); - vkDestroyFence(device, draw.fence, nullptr /* pAllocator */); - draw.draw_context->releaseResources(); - draw.draw_context = nullptr; - in_flight_draws_.pop(); - } - } - - while (!in_flight_interop_draws_.empty()) { - DCHECK(is_interop_mode_); - // Let returned InFlightInteropDraw go out of scope. - TakeInFlightInteropDrawForReUse(); - } + // Clear the queue. + { auto queue = std::move(in_flight_interop_draws_); } vulkan_context_provider_.reset(); gl_context_.reset(); @@ -366,31 +329,16 @@ if (!vulkan_context_provider_) return; - DCHECK(draw_context_); - VkDevice device = - vulkan_context_provider_->GetDeviceQueue()->GetVulkanDevice(); - VkQueue queue = vulkan_context_provider_->GetDeviceQueue()->GetVulkanQueue(); - VkFence fence = CreateAndSubmitFence(device, queue); - DCHECK(fence != VK_NULL_HANDLE); - in_flight_draws_.emplace(fence, std::move(draw_context_)); + gpu::VulkanFenceHelper* fence_helper = + vulkan_context_provider_->GetDeviceQueue()->GetFenceHelper(); - // Cleanup completed draws. - while (!in_flight_draws_.empty()) { - auto& draw = in_flight_draws_.front(); - VkResult result = vkGetFenceStatus(device, draw.fence); - if (result == VK_NOT_READY) - break; - if (result == VK_SUCCESS) { - vkDestroyFence(device, draw.fence, nullptr /* pAllocator */); - draw.draw_context->releaseResources(); - draw.draw_context = nullptr; - in_flight_draws_.pop(); - continue; - } - // Handle context lost. - NOTREACHED(); - } - DCHECK_LE(in_flight_draws_.size(), 2u); + fence_helper->EnqueueCleanupTaskForSubmittedWork( + base::BindOnce(&CleanupInFlightDraw, std::move(draw_context_), + static_cast<VkSemaphore>(VK_NULL_HANDLE))); + + // Process cleanup tasks and generate fences at the end of each PostDrawVk. + fence_helper->GenerateCleanupFence(); + fence_helper->ProcessCleanupTasks(); } void AwDrawFnImpl::DrawVkInterop(AwDrawFn_DrawVkParams* params) { @@ -411,7 +359,8 @@ // If we've exhausted our buffers, re-use an existing one. // TODO(ericrk): Benchmark using more than 1 buffer. if (in_flight_interop_draws_.size() >= 1 /* single buffering */) { - pending_draw = TakeInFlightInteropDrawForReUse(); + pending_draw = std::move(in_flight_interop_draws_.front()); + in_flight_interop_draws_.pop(); } // If prev buffer is wrong size, just re-allocate. @@ -636,20 +585,22 @@ } pending_draw->sync_fd = semaphore_handle.TakeHandle(); - DCHECK(VK_NULL_HANDLE == pending_draw->post_draw_fence); + gpu::VulkanFenceHelper* fence_helper = + vulkan_context_provider_->GetDeviceQueue()->GetFenceHelper(); - VkDevice device = - vulkan_context_provider_->GetDeviceQueue()->GetVulkanDevice(); - VkQueue queue = vulkan_context_provider_->GetDeviceQueue()->GetVulkanQueue(); - VkFence fence = CreateAndSubmitFence(device, queue); - if (fence == VK_NULL_HANDLE) { - LOG(ERROR) << "Could not create fence."; - return; - } - pending_draw->post_draw_fence = fence; + fence_helper->EnqueueCleanupTaskForSubmittedWork(base::BindOnce( + &CleanupInFlightDraw, std::move(pending_draw->draw_context), + pending_draw->post_draw_semaphore)); + pending_draw->post_draw_semaphore = VK_NULL_HANDLE; // Add the |pending_draw| to |in_flight_interop_draws_|. in_flight_interop_draws_.push(std::move(pending_draw)); + + // Process cleanup tasks and generate fences at the end of each PostDrawVk. + // TODO(ericrk): We'd ideally combine this with the flushAndSignalSemaphores + // above. + fence_helper->GenerateCleanupFence(); + fence_helper->ProcessCleanupTasks(); } template <typename T> @@ -673,43 +624,6 @@ render_thread_manager_.DrawOnRT(false /* save_restore */, &hr_params); } -std::unique_ptr<AwDrawFnImpl::InFlightInteropDraw> -AwDrawFnImpl::TakeInFlightInteropDrawForReUse() { - DCHECK(vulkan_context_provider_); - DCHECK(!in_flight_interop_draws_.empty()); - std::unique_ptr<InFlightInteropDraw> draw = - std::move(in_flight_interop_draws_.front()); - in_flight_interop_draws_.pop(); - - // Wait for our draw's |post_draw_fence| to pass. - DCHECK(draw->post_draw_fence != VK_NULL_HANDLE); - VkResult wait_result = vkWaitForFences( - vulkan_context_provider_->device(), 1, &draw->post_draw_fence, VK_TRUE, - base::TimeDelta::FromSeconds(60).InNanoseconds()); - if (wait_result != VK_SUCCESS) { - LOG(ERROR) << "Fence did not pass in the expected timeframe."; - return nullptr; - } - - draw->draw_context->releaseResources(); - draw->draw_context.reset(); - vkDestroyFence(vulkan_context_provider_->device(), draw->post_draw_fence, - nullptr); - draw->post_draw_fence = VK_NULL_HANDLE; - vkDestroySemaphore(vulkan_context_provider_->device(), - draw->post_draw_semaphore, nullptr); - draw->post_draw_semaphore = VK_NULL_HANDLE; - return draw; -} - -AwDrawFnImpl::InFlightDraw::InFlightDraw( - VkFence fence, - sk_sp<GrVkSecondaryCBDrawContext> draw_context) - : fence(fence), draw_context(std::move(draw_context)) {} - -AwDrawFnImpl::InFlightDraw::InFlightDraw(InFlightDraw&& other) = default; -AwDrawFnImpl::InFlightDraw::~InFlightDraw() = default; - AwDrawFnImpl::InFlightInteropDraw::InFlightInteropDraw( AwVulkanContextProvider* vk_context_provider) : vk_context_provider(vk_context_provider) {} @@ -734,10 +648,6 @@ draw_context->releaseResources(); draw_context.reset(); } - if (post_draw_fence != VK_NULL_HANDLE) { - vkDestroyFence(vk_context_provider->device(), post_draw_fence, nullptr); - post_draw_fence = VK_NULL_HANDLE; - } if (post_draw_semaphore != VK_NULL_HANDLE) { vkDestroySemaphore(vk_context_provider->device(), post_draw_semaphore, nullptr); @@ -746,7 +656,6 @@ } DCHECK(!draw_context); DCHECK(!ahb_skimage); - DCHECK(post_draw_fence == VK_NULL_HANDLE); DCHECK(post_draw_semaphore == VK_NULL_HANDLE); // Clean up re-usable components that are expected to still be alive. @@ -755,9 +664,10 @@ if (framebuffer_id) glDeleteFramebuffersEXT(1, &framebuffer_id); if (image_info.fImage != VK_NULL_HANDLE) { - vkDestroyImage(vk_context_provider->device(), image_info.fImage, nullptr); - vkFreeMemory(vk_context_provider->device(), image_info.fAlloc.fMemory, - nullptr); + vk_context_provider->GetDeviceQueue() + ->GetFenceHelper() + ->EnqueueImageCleanupForSubmittedWork(image_info.fImage, + image_info.fAlloc.fMemory); } }
diff --git a/android_webview/browser/gfx/aw_draw_fn_impl.h b/android_webview/browser/gfx/aw_draw_fn_impl.h index 80d89d1..a75362c2 100644 --- a/android_webview/browser/gfx/aw_draw_fn_impl.h +++ b/android_webview/browser/gfx/aw_draw_fn_impl.h
@@ -82,8 +82,6 @@ return &render_thread_manager_; } - std::unique_ptr<InFlightInteropDraw> TakeInFlightInteropDrawForReUse(); - const bool is_interop_mode_; int functor_handle_; @@ -96,17 +94,6 @@ // The draw context for the current frame. It is for direct mode only. sk_sp<GrVkSecondaryCBDrawContext> draw_context_; - struct InFlightDraw { - InFlightDraw(VkFence fence, sk_sp<GrVkSecondaryCBDrawContext> draw_context); - InFlightDraw(InFlightDraw&& other); - ~InFlightDraw(); - - // The fence for cleanup the |draw_context|. - VkFence fence = VK_NULL_HANDLE; - sk_sp<GrVkSecondaryCBDrawContext> draw_context; - }; - base::queue<InFlightDraw> in_flight_draws_; - // GL context used to draw via GL in Vk interop path. scoped_refptr<GLNonOwnedCompatibilityContext> gl_context_;
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java index 4198eb1..693fff2 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AndroidViewIntegrationTest.java
@@ -4,8 +4,6 @@ package org.chromium.android_webview.test; -import static org.junit.Assert.assertNotEquals; - import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; import android.view.View; @@ -22,11 +20,14 @@ import org.chromium.android_webview.AwLayoutSizer; import org.chromium.android_webview.test.util.CommonResources; import org.chromium.android_webview.test.util.GraphicsTestUtils; +import org.chromium.base.Log; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.Feature; import java.util.concurrent.atomic.AtomicReference; +import javax.annotation.concurrent.GuardedBy; + /** * Tests for certain edge cases related to integrating with the Android view system. */ @@ -46,25 +47,37 @@ } }; + private static final String TAG = "AndroidViewTest"; // 20 max characters + // TODO(crbug.com/949391): turn this off once we can get some details about flakes. + private static final boolean DEBUG = true; private static final int CONTENT_SIZE_CHANGE_STABILITY_TIMEOUT_MS = 1000; private static class OnContentSizeChangedHelper extends CallbackHelper { + final private Object mLock = new Object(); + @GuardedBy("mLock") private int mWidth; + @GuardedBy("mLock") private int mHeight; public int getWidth() { assert getCallCount() > 0; - return mWidth; + synchronized (mLock) { + return mWidth; + } } public int getHeight() { assert getCallCount() > 0; - return mHeight; + synchronized (mLock) { + return mHeight; + } } public void onContentSizeChanged(int widthCss, int heightCss) { - mWidth = widthCss; - mHeight = heightCss; + synchronized (mLock) { + mWidth = widthCss; + mHeight = heightCss; + } notifyCalled(); } } @@ -223,16 +236,19 @@ private void waitForContentSizeToChangeTo(OnContentSizeChangedHelper helper, int callCount, int widthCss, int heightCss) throws Exception { final int maxSizeChangeNotificationsToWaitFor = 5; - for (int i = 1; i <= maxSizeChangeNotificationsToWaitFor; i++) { - helper.waitForCallback(callCount, i); + for (int i = 0; i < maxSizeChangeNotificationsToWaitFor; i++) { + helper.waitForCallback(callCount + i); + if (DEBUG) { + Log.i(TAG, + "i: " + i + ", height: " + helper.getHeight() + + ", width: " + helper.getWidth()); + } if ((heightCss == -1 || helper.getHeight() == heightCss) && (widthCss == -1 || helper.getWidth() == widthCss)) { - break; + return; } - // This means that we hit the max number of iterations but the expected contents size - // wasn't reached. - assertNotEquals(i, maxSizeChangeNotificationsToWaitFor); } + Assert.fail("The expected contents size was not reached in max # of trials."); } private void loadPageOfSizeAndWaitForSizeChange(AwContents awContents, @@ -294,6 +310,7 @@ + "</style>", "<div>a</div>"); final int contentSizeChangeCallCount = mOnContentSizeChangedHelper.getCallCount(); + Assert.assertEquals(0, contentSizeChangeCallCount); mActivityTestRule.loadDataAsync( testContainerView.getAwContents(), htmlData, "text/html", false);
diff --git a/android_webview/tools/OWNERS b/android_webview/tools/OWNERS new file mode 100644 index 0000000..57537f1 --- /dev/null +++ b/android_webview/tools/OWNERS
@@ -0,0 +1,3 @@ +ntfschr@chromium.org + +# COMPONENT: Mobile>WebView
diff --git a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java index a80822a..93602b0 100644 --- a/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java +++ b/android_webview/tools/system_webview_shell/apk/src/org/chromium/webview_shell/WebViewBrowserActivity.java
@@ -509,12 +509,17 @@ @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main_menu, menu); + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + menu.findItem(R.id.menu_enable_tracing).setEnabled(false); + } return true; } @Override public boolean onPrepareOptionsMenu(Menu menu) { - menu.findItem(R.id.menu_enable_tracing).setChecked(mEnableTracing); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + menu.findItem(R.id.menu_enable_tracing).setChecked(mEnableTracing); + } return true; } @@ -539,6 +544,8 @@ case R.id.menu_enable_tracing: mEnableTracing = !mEnableTracing; item.setChecked(mEnableTracing); + + // TODO(laisminchillo): replace this with AndroidX's TracingController TracingController tracingController = TracingController.getInstance(); if (mEnableTracing) { tracingController.start(
diff --git a/ash/assistant/ui/assistant_web_view.cc b/ash/assistant/ui/assistant_web_view.cc index a5fba4c..99bfd4c9 100644 --- a/ash/assistant/ui/assistant_web_view.cc +++ b/ash/assistant/ui/assistant_web_view.cc
@@ -22,7 +22,6 @@ #include "ui/display/screen.h" #include "ui/gfx/canvas.h" #include "ui/views/layout/box_layout.h" -#include "ui/views/painter.h" #include "ui/views/widget/widget.h" namespace ash { @@ -35,37 +34,6 @@ : kMaxHeightDip; } -// ContentsMaskPainter --------------------------------------------------------- - -class ContentsMaskPainter : public views::Painter { - public: - ContentsMaskPainter() = default; - ~ContentsMaskPainter() override = default; - - // views::Painter: - gfx::Size GetMinimumSize() const override { return gfx::Size(); } - - void Paint(gfx::Canvas* canvas, const gfx::Size& size) override { - cc::PaintFlags flags; - flags.setAntiAlias(true); - flags.setColor(SK_ColorBLACK); - - SkRRect rect; - rect.setRectRadii( - SkRect::MakeWH(size.width(), size.height()), - (const SkVector[]){ - /*upper_left=*/SkVector::Make(0, 0), - /*upper_right=*/SkVector::Make(0, 0), - /*lower_right=*/SkVector::Make(kCornerRadiusDip, kCornerRadiusDip), - /*lower_left=*/SkVector::Make(kCornerRadiusDip, kCornerRadiusDip)}); - - canvas->sk_canvas()->drawRRect(rect, flags); - } - - private: - DISALLOW_COPY_AND_ASSIGN(ContentsMaskPainter); -}; - } // namespace // AssistantWebView ------------------------------------------------------------ @@ -120,21 +88,6 @@ contents_->FocusThroughTabTraversal(reverse); } -void AssistantWebView::OnWindowBoundsChanged(aura::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds, - ui::PropertyChangeReason reason) { - // The mask layer should always match the bounds of the contents' native view. - contents_mask_->layer()->SetBounds(gfx::Rect(new_bounds.size())); -} - -void AssistantWebView::OnWindowDestroying(aura::Window* window) { - // It's possible for |window| to be deleted before AssistantWebView. When this - // happens, we need to perform clean up on |window| before it is destroyed. - window->RemoveObserver(this); - window->layer()->SetMaskLayer(nullptr); -} - void AssistantWebView::InitLayout() { SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); @@ -146,12 +99,6 @@ if (app_list_features::IsEmbeddedAssistantUIEnabled()) caption_bar_->SetButtonVisible(AssistantButtonId::kClose, false); AddChildView(caption_bar_); - - // Contents mask. - // This is used to enforce corner radius on the contents' native view layer. - contents_mask_ = views::Painter::CreatePaintedLayer( - std::make_unique<ContentsMaskPainter>()); - contents_mask_->layer()->SetFillsBoundsOpaquely(false); } bool AssistantWebView::OnCaptionButtonPressed(AssistantButtonId id) { @@ -224,18 +171,10 @@ AddChildView(contents_->GetView()->view()); SetFocusBehavior(FocusBehavior::ALWAYS); - gfx::NativeView native_view = contents_->GetView()->native_view(); - - // We apply a layer mask to the contents' native view to enforce our desired - // corner radius. We need to sync the bounds of mask layer with the bounds - // of the native view prior to application to prevent DCHECK failure. - contents_mask_->layer()->SetBounds( - gfx::Rect(native_view->GetBoundsInScreen().size())); - native_view->layer()->SetMaskLayer(contents_mask_->layer()); - - // We observe |native_view| to ensure we keep the mask layer bounds in sync - // with the native view layer's bounds across size changes. - native_view->AddObserver(this); + // We need to clip the corners of our web contents to match our container. + contents_->GetView()->native_view()->layer()->SetRoundedCornerRadius( + {/*top_left=*/0, /*top_right=*/0, /*bottom_right=*/kCornerRadiusDip, + /*bottom_left=*/kCornerRadiusDip}); } void AssistantWebView::DidSuppressNavigation(const GURL& url, @@ -273,12 +212,6 @@ if (!contents_) return; - gfx::NativeView native_view = contents_->GetView()->native_view(); - if (native_view) { - native_view->RemoveObserver(this); - native_view->layer()->SetMaskLayer(nullptr); - } - views::View* view = contents_->GetView()->view(); if (view) RemoveChildView(view);
diff --git a/ash/assistant/ui/assistant_web_view.h b/ash/assistant/ui/assistant_web_view.h index 1f0b466..37e14a41e 100644 --- a/ash/assistant/ui/assistant_web_view.h +++ b/ash/assistant/ui/assistant_web_view.h
@@ -17,7 +17,6 @@ #include "base/optional.h" #include "mojo/public/cpp/bindings/remote.h" #include "services/content/public/cpp/navigable_contents.h" -#include "ui/aura/window_observer.h" #include "ui/views/view.h" namespace ash { @@ -31,7 +30,6 @@ // Service. class COMPONENT_EXPORT(ASSISTANT_UI) AssistantWebView : public views::View, - public aura::WindowObserver, public AssistantViewDelegateObserver, public CaptionBarDelegate, public content::NavigableContentsObserver, @@ -48,13 +46,6 @@ void OnFocus() override; void AboutToRequestFocusFromTabTraversal(bool reverse) override; - // views::WindowObserver: - void OnWindowBoundsChanged(aura::Window* window, - const gfx::Rect& old_bounds, - const gfx::Rect& new_bounds, - ui::PropertyChangeReason reason) override; - void OnWindowDestroying(aura::Window* window) override; - // CaptionBarDelegate: bool OnCaptionButtonPressed(AssistantButtonId id) override; @@ -88,12 +79,6 @@ mojo::Remote<content::mojom::NavigableContentsFactory> contents_factory_; std::unique_ptr<content::NavigableContents> contents_; - // Our contents are drawn to a layer that is not masked by our widget's layer. - // This causes our contents to ignore the corner radius that we have set on - // the widget. To address this, we apply a separate layer mask to the - // contents' native view layer enforcing our desired corner radius. - std::unique_ptr<ui::LayerOwner> contents_mask_; - base::WeakPtrFactory<AssistantWebView> weak_factory_; DISALLOW_COPY_AND_ASSIGN(AssistantWebView);
diff --git a/ash/public/cpp/ash_switches.cc b/ash/public/cpp/ash_switches.cc index afcf31f7..6b95b9e 100644 --- a/ash/public/cpp/ash_switches.cc +++ b/ash/public/cpp/ash_switches.cc
@@ -81,15 +81,6 @@ const char kAshHideNotificationsForFactory[] = "ash-hide-notifications-for-factory"; -// The color scheme to be used. -const char kAshShelfColorScheme[] = "ash-shelf-color-scheme"; -const char kAshShelfColorSchemeLightMuted[] = "light_muted"; -const char kAshShelfColorSchemeLightVibrant[] = "light_vibrant"; -const char kAshShelfColorSchemeNormalMuted[] = "normal_muted"; -const char kAshShelfColorSchemeNormalVibrant[] = "normal_vibrant"; -const char kAshShelfColorSchemeDarkMuted[] = "dark_muted"; -const char kAshShelfColorSchemeDarkVibrant[] = "dark_vibrant"; - // Enables the heads-up display for tracking touch points. const char kAshTouchHud[] = "ash-touch-hud";
diff --git a/ash/shelf/shelf_background_animator.cc b/ash/shelf/shelf_background_animator.cc index 46c7599..68b18e2 100644 --- a/ash/shelf/shelf_background_animator.cc +++ b/ash/shelf/shelf_background_animator.cc
@@ -30,28 +30,9 @@ namespace { -// Returns color profile used for shelf based on the kAshShelfColorScheme -// command line arg. +// Returns the color profile used for the shelf. ColorProfile GetShelfColorProfile() { - const std::string switch_value = - base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( - switches::kAshShelfColorScheme); - - ColorProfile color_profile(LumaRange::DARK, SaturationRange::MUTED); - - if (switch_value.find("light") != std::string::npos) - color_profile.luma = LumaRange::LIGHT; - else if (switch_value.find("normal") != std::string::npos) - color_profile.luma = LumaRange::NORMAL; - else if (switch_value.find("dark") != std::string::npos) - color_profile.luma = LumaRange::DARK; - - if (switch_value.find("vibrant") != std::string::npos) - color_profile.saturation = SaturationRange::VIBRANT; - else if (switch_value.find("muted") != std::string::npos) - color_profile.saturation = SaturationRange::MUTED; - - return color_profile; + return ColorProfile(LumaRange::DARK, SaturationRange::MUTED); } } // namespace
diff --git a/ash/system/unified/feature_pod_button.cc b/ash/system/unified/feature_pod_button.cc index 4d072b6..64e30584 100644 --- a/ash/system/unified/feature_pod_button.cc +++ b/ash/system/unified/feature_pod_button.cc
@@ -21,6 +21,7 @@ #include "ui/views/controls/image_view.h" #include "ui/views/controls/label.h" #include "ui/views/layout/box_layout.h" +#include "ui/views/view_class_properties.h" namespace ash { @@ -40,6 +41,10 @@ SetBorder(views::CreateEmptyBorder(kUnifiedFeaturePodIconPadding)); SetImageAlignment(ALIGN_CENTER, ALIGN_MIDDLE); TrayPopupUtils::ConfigureTrayPopupButton(this); + + auto path = std::make_unique<SkPath>(); + path->addOval(gfx::RectToSkRect(gfx::Rect(kUnifiedFeaturePodIconSize))); + SetProperty(views::kHighlightPathKey, path.release()); } FeaturePodIconButton::~FeaturePodIconButton() = default; @@ -130,6 +135,8 @@ FeaturePodLabelButton::~FeaturePodLabelButton() = default; void FeaturePodLabelButton::Layout() { + DCHECK(focus_ring()); + focus_ring()->Layout(); LayoutInCenter(label_, GetContentsBounds().y()); LayoutInCenter(sub_label_, GetContentsBounds().CenterPoint().y());
diff --git a/build/android/gyp/desugar.py b/build/android/gyp/desugar.py index 656e4b3..b9d04059 100755 --- a/build/android/gyp/desugar.py +++ b/build/android/gyp/desugar.py
@@ -14,6 +14,7 @@ def main(): args = build_utils.ExpandFileArgs(sys.argv[1:]) parser = argparse.ArgumentParser() + build_utils.AddDepfileOption(parser) parser.add_argument('--desugar-jar', required=True, help='Path to Desugar.jar.') parser.add_argument('--input-jar', required=True, @@ -47,6 +48,13 @@ cmd += ['--classpath_entry', path] build_utils.CheckOutput(cmd, print_stdout=False) + if options.depfile: + build_utils.WriteDepfile( + options.depfile, + options.output_jar, + inputs=options.bootclasspath + options.classpath, + add_pydeps=False) + if __name__ == '__main__': sys.exit(main())
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni index d591271d..9c9031c 100644 --- a/build/config/android/internal_rules.gni +++ b/build/config/android/internal_rules.gni
@@ -1649,6 +1649,7 @@ action_with_pydeps(_desugar_target) { script = "//build/android/gyp/desugar.py" deps = _deps + depfile = "$target_gen_dir/$target_name.d" if (defined(invoker.deps)) { deps += invoker.deps } @@ -1674,6 +1675,8 @@ # is implemented, see http://crbug.com/885273 "--classpath=@FileArg($_rebased_build_config:deps_info:javac_full_interface_classpath)", "--bootclasspath=@FileArg($_rebased_build_config:android:sdk_interface_jars)", + "--depfile", + rebase_path(depfile, root_build_dir), ] }
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index aab9de73..83108887 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -961,6 +961,7 @@ "java/src/org/chromium/chrome/browser/notifications/ChromeNotification.java", "java/src/org/chromium/chrome/browser/notifications/ChromeNotificationBuilder.java", "java/src/org/chromium/chrome/browser/notifications/CustomNotificationBuilder.java", + "java/src/org/chromium/chrome/browser/notifications/ForegroundServiceUtils.java", "java/src/org/chromium/chrome/browser/notifications/NotificationBuilder.java", "java/src/org/chromium/chrome/browser/notifications/NotificationBuilderBase.java", "java/src/org/chromium/chrome/browser/notifications/NotificationBuilderFactory.java",
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java index 402ee196..d202496 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.tasks.tab_management; import android.content.Context; +import android.content.res.Configuration; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -104,8 +105,11 @@ mRecyclerView.setAdapter(adapter); if (mMode == TabListMode.GRID) { - mRecyclerView.setLayoutManager( - new GridLayoutManager(context, GRID_LAYOUT_SPAN_COUNT_PORTRAIT)); + mRecyclerView.setLayoutManager(new GridLayoutManager(context, + context.getResources().getConfiguration().orientation + == Configuration.ORIENTATION_PORTRAIT + ? GRID_LAYOUT_SPAN_COUNT_PORTRAIT + : GRID_LAYOUT_SPAN_COUNT_LANDSCAPE)); } else if (mMode == TabListMode.STRIP) { mRecyclerView.setLayoutManager( new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
diff --git a/chrome/android/java/res/layout/permission_dialog.xml b/chrome/android/java/res/layout/permission_dialog.xml index cd44504..51189b5 100644 --- a/chrome/android/java/res/layout/permission_dialog.xml +++ b/chrome/android/java/res/layout/permission_dialog.xml
@@ -4,17 +4,19 @@ found in the LICENSE file. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:gravity="start" - style="@style/AlertDialogContent" > + style="@style/AlertDialogContent"> - <TextView + <org.chromium.chrome.browser.widget.TextViewWithCompoundDrawables android:id="@+id/text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:textDirection="locale" - android:textSize="@dimen/dialog_text_size" android:paddingBottom="24dp" - android:drawablePadding="8dp" /> + android:drawablePadding="8dp" + android:textAppearance="@style/TextAppearance.BlackBody" + app:chromeDrawableTint="@color/default_icon_color_blue" /> </LinearLayout>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index b5db1203..ef4a8765 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -497,7 +497,6 @@ https://www.google.com/design/spec/components/dialogs.html#dialogs-simple-dialogs --> <dimen name="dialog_width_unit">56dp</dimen> <!-- MD dialog widths are multiples of this. --> <dimen name="dialog_header_margin">14dp</dimen> - <dimen name="dialog_text_size">14sp</dimen> <dimen name="separator_height">1dp</dimen> <!-- Modern List Item dimensions -->
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 7a73854..fbe14aa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/AppHooks.java
@@ -11,7 +11,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.support.annotation.Nullable; -import android.support.v4.content.ContextCompat; import android.view.View; import com.google.android.gms.common.ConnectionResult; @@ -284,18 +283,8 @@ } /** - * Starts a service from {@code intent} with the expectation that it will make itself a - * foreground service with {@link android.app.Service#startForeground(int, Notification)}. - * - * @param intent The {@link Intent} to fire to start the service. - */ - public void startForegroundService(Intent intent) { - ContextCompat.startForegroundService(ContextUtils.getApplicationContext(), intent); - } - - /** * Upgrades a service from background to foreground after calling - * {@link #startForegroundService(Intent)}. + * {@link Service#startForegroundService(Intent)}. * @param service The service to be foreground. * @param id The notification id. * @param notification The notification attached to the foreground service.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsService.java b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsService.java index aa04dfe..c8cbe8b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browseractions/BrowserActionsService.java
@@ -20,12 +20,12 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; -import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.document.ChromeLauncherActivity; import org.chromium.chrome.browser.notifications.ChromeNotification; import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder; +import org.chromium.chrome.browser.notifications.ForegroundServiceUtils; import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; import org.chromium.chrome.browser.notifications.NotificationConstants; import org.chromium.chrome.browser.notifications.NotificationMetadata; @@ -234,7 +234,7 @@ ChromeNotification notification = createNotificationBuilder(isUpdate, tabId).buildChromeNotification(); - AppHooks.get().startForeground(this, notification.getMetadata().id, + ForegroundServiceUtils.getInstance().startForeground(this, notification.getMetadata().id, notification.getNotification(), 0 /* foregroundServiceType */); if (!isUpdate) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java index d1599e3a..b6ed513 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchBarControl.java
@@ -384,8 +384,7 @@ * @return The visibility percentage for the divider line ranging from 0.f to 1.f. */ public float getDividerLineVisibilityPercentage() { - return mContextualSearchPanel.useGenericSheetUx() ? DIVIDER_LINE_OPACITY_GENERIC - : mDividerLineVisibilityPercentage; + return mDividerLineVisibilityPercentage; } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java index bb50c39..c50cd5da 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/bottombar/contextualsearch/ContextualSearchPanel.java
@@ -62,13 +62,6 @@ private ContextualSearchSceneLayer mSceneLayer; /** - * Whether to use the Generic Sheet UX. - * This activates the closebox in the peeking Bar, and may someday do more, - * e.g. swipe-closed behavior. See crbug.com/831783 for details. - */ - private boolean mUseGenericSheetUx; - - /** * A ScrimView for adjusting the Status Bar's brightness when a scrim is present (when the panel * is open). */ @@ -105,12 +98,6 @@ } @Override - protected void initializeUiState() { - mUseGenericSheetUx = false; - // TODO(crbug.com/831783): Clean up this code. - } - - @Override public OverlayPanelContent createNewOverlayPanelContent() { return new OverlayPanelContent(mManagementDelegate.getOverlayContentDelegate(), new PanelProgressObserver(), mActivity, /* isIncognito= */ false, getBarHeight()); @@ -277,9 +264,7 @@ getSearchBarControl().onSearchBarClick(x); if (isPeeking()) { - if (useGenericSheetUx() && isCoordinateInsideCloseButton(x)) { - closePanel(StateChangeReason.CLOSE_BUTTON, true); - } else if (getSearchBarControl().getQuickActionControl().hasQuickAction() + if (getSearchBarControl().getQuickActionControl().hasQuickAction() && isCoordinateInsideActionTarget(x)) { mPanelMetrics.setWasQuickActionClicked(); getSearchBarControl().getQuickActionControl().sendIntent( @@ -723,33 +708,6 @@ } } - @Override - public float getArrowIconOpacity() { - if (useGenericSheetUx()) { - return ARROW_ICON_OPACITY_GENERIC_UX; - } else { - return super.getArrowIconOpacity(); - } - } - - @Override - public float getCloseIconOpacity() { - if (useGenericSheetUx()) { - return CLOSE_ICON_OPACITY_GENERIC_UX; - } else { - return super.getCloseIconOpacity(); - } - } - - /** - * Whether the UX should match the generic sheet UX used by the generic assistive surface. - * TODO(crbug.com/831783) remove when the generic sheet UX is the default. - * @return Whether to apply the generic UX, rather than the legacy Contextual Search UX. - */ - boolean useGenericSheetUx() { - return mUseGenericSheetUx; - } - // ============================================================================================ // Selection position // ============================================================================================
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 c4cc5f75..e6f03a4 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
@@ -21,7 +21,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.VisibleForTesting; -import org.chromium.chrome.browser.AppHooks; +import org.chromium.chrome.browser.notifications.ForegroundServiceUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -60,7 +60,8 @@ */ public static void startDownloadForegroundService(Context context) { // TODO(crbug.com/770389): Grab a WakeLock here until the service has started. - AppHooks.get().startForegroundService(new Intent(context, DownloadForegroundService.class)); + ForegroundServiceUtils.getInstance().startForegroundService( + new Intent(context, DownloadForegroundService.class)); } /** @@ -241,7 +242,7 @@ @VisibleForTesting void startForegroundInternal(int notificationId, Notification notification) { Log.w(TAG, "startForegroundInternal id: " + notificationId); - AppHooks.get().startForeground( + ForegroundServiceUtils.getInstance().startForeground( this, notificationId, notification, 0 /* foregroundServiceType */); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java index a299ea4..385dd58 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/DownloadNotificationService.java
@@ -8,7 +8,6 @@ import static org.chromium.chrome.browser.download.DownloadSnackbarController.INVALID_NOTIFICATION_ID; import android.app.Notification; -import android.app.NotificationManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -29,6 +28,8 @@ import org.chromium.base.VisibleForTesting; import org.chromium.base.library_loader.LibraryProcessType; import org.chromium.chrome.R; +import org.chromium.chrome.browser.notifications.NotificationManagerProxy; +import org.chromium.chrome.browser.notifications.NotificationManagerProxyImpl; import org.chromium.chrome.browser.notifications.NotificationUmaTracker; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.util.FeatureUtilities; @@ -94,7 +95,7 @@ @VisibleForTesting final List<ContentId> mDownloadsInProgress = new ArrayList<ContentId>(); - private NotificationManager mNotificationManager; + private NotificationManagerProxy mNotificationManager; private Bitmap mDownloadSuccessLargeIcon; private DownloadSharedPreferenceHelper mDownloadSharedPreferenceHelper; private DownloadForegroundServiceManager mDownloadForegroundServiceManager; @@ -114,8 +115,7 @@ @VisibleForTesting DownloadNotificationService() { mNotificationManager = - (NotificationManager) ContextUtils.getApplicationContext().getSystemService( - Context.NOTIFICATION_SERVICE); + new NotificationManagerProxyImpl(ContextUtils.getApplicationContext()); mDownloadSharedPreferenceHelper = DownloadSharedPreferenceHelper.getInstance(); mDownloadForegroundServiceManager = new DownloadForegroundServiceManager(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java index fef3686..7d8c981 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/list/DateOrderedListMediator.java
@@ -338,7 +338,7 @@ } private void onRenameItem(OfflineItem item) { - // TODO(hesen): Add uma stats. + UmaUtils.recordItemAction(ViewAction.MENU_RENAME); mRenameController.rename(item.title, (newName, renameCallback) -> { mProvider.renameItem(item, newName, renameCallback); });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java index 37a5c6a..f17ced2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/download/home/metrics/UmaUtils.java
@@ -40,7 +40,7 @@ // Please treat this list as append only and keep it in sync with // Android.DownloadManager.List.View.Actions in enums.xml. @IntDef({ViewAction.OPEN, ViewAction.RESUME, ViewAction.PAUSE, ViewAction.CANCEL, - ViewAction.MENU_SHARE, ViewAction.MENU_DELETE, ViewAction.RETRY}) + ViewAction.MENU_SHARE, ViewAction.MENU_DELETE, ViewAction.RETRY, ViewAction.MENU_RENAME}) @Retention(RetentionPolicy.SOURCE) public @interface ViewAction { int OPEN = 0; @@ -50,7 +50,8 @@ int MENU_SHARE = 4; int MENU_DELETE = 5; int RETRY = 6; - int NUM_ENTRIES = 7; + int MENU_RENAME = 7; + int NUM_ENTRIES = 8; } // Please treat this list as append only and keep it in sync with @@ -121,6 +122,9 @@ case ViewAction.RETRY: userActionSuffix = "Retry"; break; + case ViewAction.MENU_RENAME: + userActionSuffix = "MenuRename"; + break; default: assert false : "Unexpected action " + action + " passed to recordItemAction."; return;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java index d2a085ad..437468f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaButtonReceiver.java
@@ -10,7 +10,7 @@ import android.view.KeyEvent; import org.chromium.base.Log; -import org.chromium.chrome.browser.AppHooks; +import org.chromium.chrome.browser.notifications.ForegroundServiceUtils; /** * MediaButtonReceiver is a basic BroadcastReceiver class that receives @@ -40,6 +40,6 @@ } intent.setClass(context, getServiceClass()); - AppHooks.get().startForegroundService(intent); + ForegroundServiceUtils.getInstance().startForegroundService(intent); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java index ea13439..6202f28 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/media/ui/MediaNotificationManager.java
@@ -40,10 +40,10 @@ import org.chromium.base.SysUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; -import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.notifications.ChromeNotification; import org.chromium.chrome.browser.notifications.ChromeNotificationBuilder; +import org.chromium.chrome.browser.notifications.ForegroundServiceUtils; import org.chromium.chrome.browser.notifications.NotificationBuilderFactory; import org.chromium.chrome.browser.notifications.NotificationConstants; import org.chromium.chrome.browser.notifications.NotificationManagerProxy; @@ -293,7 +293,7 @@ NotificationBuilderFactory.createChromeNotificationBuilder(true /* preferCompat */, ChannelDefinitions.ChannelId.MEDIA, null /* remoteAppPackageName */, metadata); - AppHooks.get().startForeground(s, s.getNotificationId(), + ForegroundServiceUtils.getInstance().startForeground(s, s.getNotificationId(), builder.buildChromeNotification().getNotification(), 0 /* foregroundServiceType */); } @@ -851,7 +851,7 @@ if (mService == null) { updateMediaSession(); updateNotificationBuilder(); - AppHooks.get().startForegroundService(createIntent()); + ForegroundServiceUtils.getInstance().startForegroundService(createIntent()); } else { updateNotification(false, false); } @@ -939,7 +939,9 @@ // crash Chrome. boolean foregroundedService = false; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && serviceStarting) { - mService.startForeground(mMediaNotificationInfo.id, notification.getNotification()); + ForegroundServiceUtils.getInstance().startForeground(mService, + mMediaNotificationInfo.id, notification.getNotification(), + 0 /*foregroundServiceType*/); foregroundedService = true; } @@ -953,7 +955,9 @@ NotificationManagerProxy manager = new NotificationManagerProxyImpl(getContext()); manager.notify(notification); } else if (!foregroundedService) { - mService.startForeground(mMediaNotificationInfo.id, notification.getNotification()); + ForegroundServiceUtils.getInstance().startForeground(mService, + mMediaNotificationInfo.id, notification.getNotification(), + 0 /*foregroundServiceType*/); } if (shouldLogNotification) { mNotificationUmaTracker.onNotificationShown(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/ForegroundServiceUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/ForegroundServiceUtils.java new file mode 100644 index 0000000..666ac36 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/ForegroundServiceUtils.java
@@ -0,0 +1,70 @@ +// Copyright 2019 The Chromium 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.notifications; + +import android.app.Notification; +import android.app.Service; +import android.content.Intent; +import android.support.v4.content.ContextCompat; + +import org.chromium.base.ContextUtils; +import org.chromium.base.VisibleForTesting; +import org.chromium.chrome.browser.AppHooks; + +/** + * Utility functions that call into Android foreground service related API, and provides + * compatibility for older Android versions and work around for Android API bugs. + */ +public class ForegroundServiceUtils { + private ForegroundServiceUtils() {} + + /** + * Gets the singleton instance of ForegroundServiceUtils. + */ + public static ForegroundServiceUtils getInstance() { + return ForegroundServiceUtils.LazyHolder.sInstance; + } + + /** + * Sets a mocked instance for testing. + */ + @VisibleForTesting + public static void setInstanceForTesting(ForegroundServiceUtils instance) { + ForegroundServiceUtils.LazyHolder.sInstance = instance; + } + + private static class LazyHolder { + private static ForegroundServiceUtils sInstance = new ForegroundServiceUtils(); + } + + /** + * Starts a service from {@code intent} with the expectation that it will make itself a + * foreground service with {@link android.app.Service#startForeground(int, Notification)}. + * + * @param intent The {@link Intent} to fire to start the service. + */ + public void startForegroundService(Intent intent) { + ContextCompat.startForegroundService(ContextUtils.getApplicationContext(), intent); + } + + /** + * Upgrades a service from background to foreground after calling + * {@link #startForegroundService(Intent)}. + * @param service The service to be foreground. + * @param id The notification id. + * @param notification The notification attached to the foreground service. + * @param foregroundServiceType The type of foreground service. Must be a subset of the + * foreground service types defined in AndroidManifest.xml. + * Use 0 if no foregroundServiceType attribute is defined. + */ + public void startForeground( + Service service, int id, Notification notification, int foregroundServiceType) { + // If android fail to build the notification, do nothing. + if (notification == null) return; + + // TODO(xingliu): Remove startForeground call from AppHooks when Q sdk is available. + AppHooks.get().startForeground(service, id, notification, foregroundServiceType); + } +}
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 7335918..b670f3a 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
@@ -1036,7 +1036,8 @@ } mStatusViewCoordinator.setUseDarkColors(useDarkColors); - mAutocompleteCoordinator.updateVisualsForState(useDarkColors); + mAutocompleteCoordinator.updateVisualsForState( + useDarkColors, mToolbarDataProvider.isIncognito()); } @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java index 50828d44..a77cf3d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteCoordinator.java
@@ -339,9 +339,10 @@ /** * Update the visuals of the autocomplete UI. * @param useDarkColors Whether dark colors should be applied to the UI. + * @param isIncognito Whether the UI is for incognito mode or not. */ - public void updateVisualsForState(boolean useDarkColors) { - mMediator.setUseDarkColors(useDarkColors); + public void updateVisualsForState(boolean useDarkColors, boolean isIncognito) { + mMediator.updateVisualsForState(useDarkColors, isIncognito); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java index 3a52b13..3b9f00f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/AutocompleteMediator.java
@@ -266,10 +266,11 @@ /** * Specifies the visual state to be used by the suggestions. * @param useDarkColors Whether dark colors should be used for fonts and icons. + * @param isIncognito Whether the UI is for incognito mode or not. */ - void setUseDarkColors(boolean useDarkColors) { + void updateVisualsForState(boolean useDarkColors, boolean isIncognito) { mUseDarkColors = useDarkColors; - mListPropertyModel.set(SuggestionListProperties.USE_DARK_BACKGROUND, !useDarkColors); + mListPropertyModel.set(SuggestionListProperties.IS_INCOGNITO, isIncognito); for (int i = 0; i < mCurrentModels.size(); i++) { PropertyModel model = mCurrentModels.get(i).model; model.set(SuggestionCommonProperties.USE_DARK_COLORS, useDarkColors);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsList.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsList.java index 71f4014..0cc8da64 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsList.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsList.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.omnibox.suggestions; import android.content.Context; +import android.content.res.Resources; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; @@ -20,6 +21,7 @@ import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; import org.chromium.chrome.browser.WindowDelegate; +import org.chromium.chrome.browser.util.ColorUtils; import org.chromium.chrome.browser.util.KeyNavigationUtil; import org.chromium.chrome.browser.util.ViewUtils; @@ -30,11 +32,10 @@ */ @VisibleForTesting public class OmniboxSuggestionsList extends ListView { - private static final int LIGHT_BG_COLOR = 0xFFFFFFFF; - private static final int DARK_BG_COLOR = 0xFF3C4043; - private final int[] mTempPosition = new int[2]; private final Rect mTempRect = new Rect(); + private final int mStandardBgColor; + private final int mIncognitoBgColor; private OmniboxSuggestionListEmbedder mEmbedder; private View mAnchorView; @@ -74,8 +75,11 @@ setFocusable(true); setFocusableInTouchMode(true); - int paddingBottom = context.getResources().getDimensionPixelOffset( - R.dimen.omnibox_suggestion_list_padding_bottom); + final Resources resources = context.getResources(); + mStandardBgColor = ColorUtils.getDefaultThemeColor(resources, false); + mIncognitoBgColor = ColorUtils.getDefaultThemeColor(resources, true); + int paddingBottom = + resources.getDimensionPixelOffset(R.dimen.omnibox_suggestion_list_padding_bottom); ViewCompat.setPaddingRelative(this, 0, 0, 0, paddingBottom); } @@ -143,8 +147,8 @@ /** * Update the suggestion popup background to reflect the current state. */ - void refreshPopupBackground(boolean useDarkBackground) { - int color = useDarkBackground ? DARK_BG_COLOR : LIGHT_BG_COLOR; + void refreshPopupBackground(boolean isIncognito) { + int color = isIncognito ? mIncognitoBgColor : mStandardBgColor; if (!isHardwareAccelerated()) { // When HW acceleration is disabled, changing mSuggestionList' items somehow erases // mOmniboxResultsContainer' background from the area not covered by mSuggestionList.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java index ca80a402..e6f7b9f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListProperties.java
@@ -30,9 +30,8 @@ SUGGESTION_MODELS = new WritableObjectPropertyKey<>(true); /** Whether the suggestion list should have a dark background. */ - public static final WritableBooleanPropertyKey USE_DARK_BACKGROUND = - new WritableBooleanPropertyKey(); + public static final WritableBooleanPropertyKey IS_INCOGNITO = new WritableBooleanPropertyKey(); public static final PropertyKey[] ALL_KEYS = - new PropertyKey[] {VISIBLE, EMBEDDER, SUGGESTION_MODELS, USE_DARK_BACKGROUND}; + new PropertyKey[] {VISIBLE, EMBEDDER, SUGGESTION_MODELS, IS_INCOGNITO}; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java index 1405cb2..7fa3738 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/suggestions/SuggestionListViewBinder.java
@@ -55,9 +55,8 @@ } else if (SuggestionListProperties.SUGGESTION_MODELS.equals(propertyKey)) { view.adapter.updateModels(model.get(SuggestionListProperties.SUGGESTION_MODELS)); view.listView.setSelection(0); - } else if (SuggestionListProperties.USE_DARK_BACKGROUND.equals(propertyKey)) { - view.listView.refreshPopupBackground( - model.get(SuggestionListProperties.USE_DARK_BACKGROUND)); + } else if (SuggestionListProperties.IS_INCOGNITO.equals(propertyKey)) { + view.listView.refreshPopupBackground(model.get(SuggestionListProperties.IS_INCOGNITO)); } } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webshare/BlobReceiver.java b/chrome/android/java/src/org/chromium/chrome/browser/webshare/BlobReceiver.java index a8c6c6c8..2e8bbf7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webshare/BlobReceiver.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webshare/BlobReceiver.java
@@ -76,7 +76,7 @@ @Override public void onConnectionError(MojoException e) { if (mCallback == null) return; - reportError(MojoResult.INTERNAL, "Connection error detected."); + reportError(e.getMojoResult(), "Connection error detected."); } // BlobReaderClient @@ -109,7 +109,10 @@ // BlobReaderClient @Override - public void onComplete(int status, long dataLength) {} + public void onComplete(int status, long dataLength) { + if (mCallback == null) return; + read(); + } private void read() { try {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java index 21c8fc0..47ef65b 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationActionsUpdatedTest.java
@@ -48,7 +48,9 @@ getManager().mThrottler.mManager = getManager(); doCallRealMethod().when(getManager()).onServiceStarted(any(ListenerService.class)); - doCallRealMethod().when(mMockAppHooks).startForegroundService(any(Intent.class)); + doCallRealMethod() + .when(mMockForegroundServiceUtils) + .startForegroundService(any(Intent.class)); mTabHolder = new MediaNotificationTestTabHolder(TAB_ID_1, "about:blank", "title1"); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationFaviconTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationFaviconTest.java index d8a0b74..98210ef 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationFaviconTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationFaviconTest.java
@@ -76,7 +76,9 @@ getManager().mThrottler.mManager = getManager(); doCallRealMethod().when(getManager()).onServiceStarted(any(ListenerService.class)); - doCallRealMethod().when(mMockAppHooks).startForegroundService(any(Intent.class)); + doCallRealMethod() + .when(mMockForegroundServiceUtils) + .startForegroundService(any(Intent.class)); mTabHolder = new MediaNotificationTestTabHolder(TAB_ID_1, "about:blank", "title1"); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceLifecycleTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceLifecycleTest.java index 18fee49..f7118fb 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceLifecycleTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerServiceLifecycleTest.java
@@ -110,7 +110,7 @@ verify(getManager()).showNotification(newInfo); verifyNoMoreInteractions(getManager()); - verify(mMockAppHooks, never()).startForegroundService(any(Intent.class)); + verify(mMockForegroundServiceUtils, never()).startForegroundService(any(Intent.class)); verify(mMockContext, never()).startService(any(Intent.class)); verify(mMockUmaTracker, never()).onNotificationShown(anyInt(), any(Notification.class)); } @@ -127,7 +127,7 @@ verify(getManager()).showNotification(newInfo); verifyNoMoreInteractions(getManager()); - verify(mMockAppHooks, never()).startForegroundService(any(Intent.class)); + verify(mMockForegroundServiceUtils, never()).startForegroundService(any(Intent.class)); verify(mMockContext, never()).startService(any(Intent.class)); verify(mMockUmaTracker, never()).onNotificationShown(anyInt(), any(Notification.class)); } @@ -140,7 +140,7 @@ verify(getManager(), times(1)).updateMediaSession(); verify(getManager(), times(1)).updateNotificationBuilder(); verify(mMockContext, never()).startService(any(Intent.class)); - verify(mMockAppHooks, times(1)).startForegroundService(any(Intent.class)); + verify(mMockForegroundServiceUtils, times(1)).startForegroundService(any(Intent.class)); verify(getManager(), never()).updateNotification(anyBoolean(), eq(false)); } @@ -154,7 +154,7 @@ getManager().showNotification(newInfo); verify(getManager()).showNotification(newInfo); - verify(mMockAppHooks, never()).startForegroundService(any(Intent.class)); + verify(mMockForegroundServiceUtils, never()).startForegroundService(any(Intent.class)); verify(mMockContext, never()).startService(any(Intent.class)); verify(getManager()).updateNotification(anyBoolean(), eq(false)); verify(mMockUmaTracker, never()).onNotificationShown(anyInt(), any(Notification.class)); @@ -169,12 +169,13 @@ MediaNotificationInfo oldInfo = mMediaNotificationInfoBuilder.build(); getManager().showNotification(oldInfo); - InOrder order = inOrder(getManager(), mMockAppHooks); + InOrder order = inOrder(getManager(), mMockForegroundServiceUtils); assertEquals(oldInfo, getManager().mMediaNotificationInfo); order.verify(getManager(), times(1)).updateMediaSession(); order.verify(getManager(), times(1)).updateNotificationBuilder(); - order.verify(mMockAppHooks, times(1)).startForegroundService(any(Intent.class)); + order.verify(mMockForegroundServiceUtils, times(1)) + .startForegroundService(any(Intent.class)); order.verify(getManager(), never()).updateNotification(anyBoolean(), eq(false)); // The second call to |showNotification()| should only update the notification info. @@ -185,7 +186,8 @@ assertEquals(newInfo, getManager().mMediaNotificationInfo); order.verify(getManager(), times(1)).updateMediaSession(); order.verify(getManager(), times(1)).updateNotificationBuilder(); - order.verify(mMockAppHooks, times(1)).startForegroundService(any(Intent.class)); + order.verify(mMockForegroundServiceUtils, times(1)) + .startForegroundService(any(Intent.class)); order.verify(getManager(), never()).updateNotification(anyBoolean(), eq(false)); verify(getManager(), never()).onServiceStarted(any(ListenerService.class)); @@ -244,7 +246,9 @@ getManager().mMediaNotificationInfo = mMediaNotificationInfoBuilder.build(); getManager().updateNotification(false, false); - verify(mService).startForeground(eq(getNotificationId()), any(Notification.class)); + verify(mMockForegroundServiceUtils) + .startForeground( + eq(mService), eq(getNotificationId()), any(Notification.class), eq(0)); } @Test @@ -255,7 +259,9 @@ getManager().mMediaNotificationInfo = mMediaNotificationInfoBuilder.build(); getManager().updateNotification(false, false); - verify(mService).startForeground(eq(getNotificationId()), any(Notification.class)); + verify(mMockForegroundServiceUtils) + .startForeground( + eq(mService), eq(getNotificationId()), any(Notification.class), eq(0)); } private ShadowNotificationManager getShadowNotificationManager() {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java index 02564ce..5ea143d 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationManagerTestBase.java
@@ -34,9 +34,9 @@ import org.chromium.base.CommandLine; import org.chromium.base.ContextUtils; import org.chromium.chrome.browser.AppHooks; -import org.chromium.chrome.browser.AppHooksImpl; import org.chromium.chrome.browser.ChromeFeatureList; import org.chromium.chrome.browser.media.ui.MediaNotificationManager.ListenerService; +import org.chromium.chrome.browser.notifications.ForegroundServiceUtils; import org.chromium.chrome.browser.notifications.NotificationUmaTracker; import org.chromium.services.media_session.MediaMetadata; @@ -53,7 +53,7 @@ Context mMockContext; MockListenerService mService; MediaNotificationListener mListener; - AppHooksImpl mMockAppHooks; + ForegroundServiceUtils mMockForegroundServiceUtils; NotificationUmaTracker mMockUmaTracker; MediaNotificationInfo.Builder mMediaNotificationInfoBuilder; @@ -135,8 +135,8 @@ .when(mMockContext) .startService(any(Intent.class)); - mMockAppHooks = mock(AppHooksImpl.class); - AppHooks.setInstanceForTesting(mMockAppHooks); + mMockForegroundServiceUtils = mock(ForegroundServiceUtils.class); + ForegroundServiceUtils.setInstanceForTesting(mMockForegroundServiceUtils); // Init the command line to avoid assertion failure in |SysUtils#isLowEndDevice()|. CommandLine.init(null);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTitleUpdatedTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTitleUpdatedTest.java index 888e5c4..9021c7a 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTitleUpdatedTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/media/ui/MediaNotificationTitleUpdatedTest.java
@@ -51,7 +51,9 @@ getManager().mThrottler.mManager = getManager(); doCallRealMethod().when(getManager()).onServiceStarted(any(ListenerService.class)); - doCallRealMethod().when(mMockAppHooks).startForegroundService(any(Intent.class)); + doCallRealMethod() + .when(mMockForegroundServiceUtils) + .startForegroundService(any(Intent.class)); mTabHolder = new MediaNotificationTestTabHolder(TAB_ID_1, "about:blank", "title1"); }
diff --git a/chrome/android/touchless/java/res/drawable/suggestion_tile.xml b/chrome/android/touchless/java/res/drawable/suggestion_tile.xml new file mode 100644 index 0000000..9ae6fed --- /dev/null +++ b/chrome/android/touchless/java/res/drawable/suggestion_tile.xml
@@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2019 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:drawable="@drawable/tile_view_icon_focused" android:state_focused="true"/> +</selector> \ No newline at end of file
diff --git a/chrome/android/touchless/java/res/drawable/tile_view_icon_focused.xml b/chrome/android/touchless/java/res/drawable/tile_view_icon_focused.xml new file mode 100644 index 0000000..a19a724 --- /dev/null +++ b/chrome/android/touchless/java/res/drawable/tile_view_icon_focused.xml
@@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright 2019 The Chromium Authors. All rights reserved. + Use of this source code is governed by a BSD-style license that can be + found in the LICENSE file. --> +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="oval"> + <stroke android:width="@dimen/most_likely_tile_focus_stroke_width" android:color="@color/light_active_color"/> +</shape> \ No newline at end of file
diff --git a/chrome/android/touchless/java/res/layout/most_likely_touchless.xml b/chrome/android/touchless/java/res/layout/most_likely_touchless.xml index 8ab76e7..18409af 100644 --- a/chrome/android/touchless/java/res/layout/most_likely_touchless.xml +++ b/chrome/android/touchless/java/res/layout/most_likely_touchless.xml
@@ -7,7 +7,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:layout_marginVertical="@dimen/most_likely_carousel_vertical_spacer" + android:paddingVertical="@dimen/most_likely_carousel_edge_spacer" android:gravity="center_horizontal"> <android.support.v7.widget.RecyclerView @@ -16,7 +16,6 @@ android:scrollbars="none" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginBottom="@dimen/most_likely_carousel_edge_spacer" android:orientation="horizontal" /> <TextView @@ -24,6 +23,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" - android:textAppearance="@style/TextAppearance.BlackTitle2" /> + android:textAppearance="@style/TextAppearance.BlackTitle2" + android:maxLines="1"/> </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/touchless/java/res/layout/touchless_suggestions_tile_view.xml b/chrome/android/touchless/java/res/layout/touchless_suggestions_tile_view.xml index 0255d23b..cf50acd 100644 --- a/chrome/android/touchless/java/res/layout/touchless_suggestions_tile_view.xml +++ b/chrome/android/touchless/java/res/layout/touchless_suggestions_tile_view.xml
@@ -5,11 +5,41 @@ <org.chromium.chrome.browser.touchless.SiteSuggestionsTileView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:paddingHorizontal="@dimen/most_likely_tile_horizontal_spacer"> - <include - layout="@layout/tile_no_text_view_condensed" - android:layout_width="match_parent" - android:layout_height="match_parent" /> + android:layout_gravity="center" + android:background="@drawable/suggestion_tile"> + <!-- The icon background. --> + <View + android:id="@+id/tile_view_icon_background" + android:layout_width="@dimen/tile_view_icon_size" + android:layout_height="@dimen/tile_view_icon_size" + android:background="@drawable/tile_view_icon_background_modern" /> + + <!-- The main icon. --> + <ImageView + android:id="@+id/tile_view_icon" + android:layout_width="@dimen/tile_view_icon_size_modern" + android:layout_height="@dimen/tile_view_icon_size_modern" + android:layout_gravity="center" + android:importantForAccessibility="no" /> + + <!-- Focus highlight. --> + <View + android:layout_width="@dimen/tile_view_icon_size" + android:layout_height="@dimen/tile_view_icon_size" + android:background="@drawable/suggestion_tile" + android:duplicateParentState="true"/> + + <!-- The offline badge. --> + <ImageView + android:id="@+id/offline_badge" + android:layout_width="@dimen/tile_view_offline_badge_size_modern" + android:layout_height="@dimen/tile_view_offline_badge_size_modern" + android:layout_gravity="top|end" + android:layout_marginEnd="@dimen/tile_view_offline_badge_margin_end_modern_condensed" + android:visibility="gone" + android:contentDescription="@string/accessibility_ntp_offline_badge" + app:srcCompat="@drawable/ic_offline_pin_blue_white" /> </org.chromium.chrome.browser.touchless.SiteSuggestionsTileView>
diff --git a/chrome/android/touchless/java/res/values-v17/dimens.xml b/chrome/android/touchless/java/res/values-v17/dimens.xml index baeac27..bfa5041b 100644 --- a/chrome/android/touchless/java/res/values-v17/dimens.xml +++ b/chrome/android/touchless/java/res/values-v17/dimens.xml
@@ -26,7 +26,7 @@ <dimen name="open_last_tab_primary_text_margin_left">8dp</dimen> <!-- Most likely carousel dimensions. --> + <dimen name="most_likely_tile_focus_stroke_width">2dp</dimen> <dimen name="most_likely_tile_horizontal_spacer">6dp</dimen> <dimen name="most_likely_carousel_edge_spacer">8dp</dimen> - <dimen name="most_likely_carousel_vertical_spacer">16dp</dimen> </resources>
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsCoordinator.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsCoordinator.java index 5b6044e..3e2cb04 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsCoordinator.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsCoordinator.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.touchless; import android.content.Context; +import android.graphics.Rect; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; @@ -64,6 +65,22 @@ adapter = new RecyclerViewAdapter<>( adapterDelegate, new SiteSuggestionsViewHolderFactory()); + // Add spacing because tile margins get swallowed/overridden somehow. + // TODO(chili): use layout margin. + recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() { + @Override + public void getItemOffsets( + Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + outRect.bottom = context.getResources().getDimensionPixelSize( + R.dimen.most_likely_carousel_edge_spacer); + outRect.left = context.getResources().getDimensionPixelSize( + R.dimen.most_likely_tile_horizontal_spacer); + outRect.right = context.getResources().getDimensionPixelSize( + R.dimen.most_likely_tile_horizontal_spacer); + outRect.top = context.getResources().getDimensionPixelSize( + R.dimen.most_likely_carousel_edge_spacer); + } + }); recyclerView.setLayoutManager(layoutManager); recyclerView.setAdapter(adapter);
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java index 4b0d7ea..ade379c1 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/SiteSuggestionsLayoutManager.java
@@ -27,7 +27,7 @@ int position = getPosition(child); // Calculates the offset for the child's left edge such that the child would be // perfectly centered in the view. - int childHalfWidth = child.getWidth() / 2; + int childHalfWidth = child.getWidth() / 2 + getLeftDecorationWidth(child); int offset = parent.getWidth() / 2 - childHalfWidth; // Scroll to child with calculated offset. scrollToPositionWithOffset(position, offset);
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java index 6e73ecd..a30cf13 100644 --- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java +++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessNewTabPage.java
@@ -28,6 +28,7 @@ import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegate; import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegateImpl; import org.chromium.chrome.browser.tab.Tab; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.widget.displaystyle.UiConfig; import org.chromium.chrome.touchless.R; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; @@ -109,7 +110,7 @@ SuggestionsSource suggestionsSource = depsFactory.createSuggestionSource(profile); SuggestionsEventReporter eventReporter = depsFactory.createEventReporter(); SuggestionsNavigationDelegate navigationDelegate = new SuggestionsNavigationDelegate( - activity, profile, nativePageHost, mTab.getTabModelSelector()); + activity, profile, nativePageHost, TabModelSelector.from(mTab)); SuggestionsUiDelegate suggestionsUiDelegate = new SuggestionsUiDelegateImpl( suggestionsSource, eventReporter, navigationDelegate, profile, nativePageHost, activity.getChromeApplication().getReferencePool(), activity.getSnackbarManager());
diff --git a/chrome/app/OWNERS b/chrome/app/OWNERS index 6693dae..a4f3eaa8 100644 --- a/chrome/app/OWNERS +++ b/chrome/app/OWNERS
@@ -14,7 +14,7 @@ per-file chromium_strings.grd=* per-file generated_resources.grd=* per-file google_chrome_strings.grd=* -per-file md_extensions_strings.grdp=* +per-file extensions_strings.grdp=* per-file app_management_strings.grdp=file://chrome/browser/ui/webui/app_management/OWNERS
diff --git a/chrome/app/md_extensions_strings.grdp b/chrome/app/extensions_strings.grdp similarity index 100% rename from chrome/app/md_extensions_strings.grdp rename to chrome/app/extensions_strings.grdp
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 085dee6..8ee40fe 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -209,7 +209,7 @@ <!-- MD Extensions specific strings --> <if expr="enable_extensions"> - <part file="md_extensions_strings.grdp" /> + <part file="extensions_strings.grdp" /> </if> <!-- NUX Welcome onboarding experience strings -->
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 0eb15c8..2f69ec0d 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -466,28 +466,6 @@ switches::kTopChromeTouchUiEnabled}}; #if defined(OS_CHROMEOS) -const FeatureEntry::Choice kAshShelfColorSchemeChoices[] = { - {flags_ui::kGenericExperimentChoiceDefault, "", ""}, - {flag_descriptions::kAshShelfColorSchemeLightVibrant, - ash::switches::kAshShelfColorScheme, - ash::switches::kAshShelfColorSchemeLightVibrant}, - {flag_descriptions::kAshShelfColorSchemeNormalVibrant, - ash::switches::kAshShelfColorScheme, - ash::switches::kAshShelfColorSchemeNormalVibrant}, - {flag_descriptions::kAshShelfColorSchemeDarkVibrant, - ash::switches::kAshShelfColorScheme, - ash::switches::kAshShelfColorSchemeDarkVibrant}, - {flag_descriptions::kAshShelfColorSchemeLightMuted, - ash::switches::kAshShelfColorScheme, - ash::switches::kAshShelfColorSchemeLightMuted}, - {flag_descriptions::kAshShelfColorSchemeNormalMuted, - ash::switches::kAshShelfColorScheme, - ash::switches::kAshShelfColorSchemeNormalMuted}, - {flag_descriptions::kAshShelfColorSchemeDarkMuted, - ash::switches::kAshShelfColorScheme, - ash::switches::kAshShelfColorSchemeDarkMuted}, -}; - const FeatureEntry::Choice kUiShowCompositedLayerBordersChoices[] = { {flags_ui::kGenericExperimentChoiceDefault, "", ""}, {flag_descriptions::kUiShowCompositedLayerBordersRenderPass, @@ -1389,9 +1367,6 @@ kOsAll, SINGLE_VALUE_TYPE(ash::switches::kAshDebugShortcuts), }, - {"ash-shelf-color-scheme", flag_descriptions::kAshShelfColorScheme, - flag_descriptions::kAshShelfColorSchemeDescription, kOsCrOS, - MULTI_VALUE_TYPE(kAshShelfColorSchemeChoices)}, {"ui-slow-animations", flag_descriptions::kUiSlowAnimationsName, flag_descriptions::kUiSlowAnimationsDescription, kOsCrOS, SINGLE_VALUE_TYPE(switches::kUISlowAnimations)},
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index a7c05f9b..ef90d1fe 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd
@@ -98,8 +98,8 @@ <include name="IDR_ABOUT_NACL_JS" file="resources\about_nacl\about_nacl.js" type="BINDATA" /> </if> <if expr="not is_android"> - <include name="IDR_ABOUT_SYS_HTML" file="resources\about_sys\about_sys.html" compress="gzip" flattenhtml="true" type="BINDATA" /> - <include name="IDR_ABOUT_SYS_CSS" file="resources\about_sys\about_sys.css" compress="gzip" type="BINDATA" /> + <include name="IDR_ABOUT_SYS_HTML" file="resources\about_sys\about_sys.html" compress="gzip" type="BINDATA" /> + <include name="IDR_ABOUT_SYS_CSS" file="resources\about_sys\about_sys.css" compress="gzip" flattenhtml="true" type="BINDATA" /> <include name="IDR_ABOUT_SYS_JS" file="resources\about_sys\about_sys.js" compress="gzip" type="BINDATA" /> </if> <include name="IDR_ACCESSIBILITY_HTML" file="resources\accessibility\accessibility.html" flattenhtml="true" allowexternalscript="true" compress="gzip" type="BINDATA" />
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index dfed891..d8cd1ae8 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -581,10 +581,12 @@ "arc/screen_capture/arc_screen_capture_session.h", "arc/tracing/arc_cpu_event.cc", "arc/tracing/arc_cpu_event.h", - "arc/tracing/arc_cpu_model.cc", - "arc/tracing/arc_cpu_model.h", "arc/tracing/arc_graphics_jank_detector.cc", "arc/tracing/arc_graphics_jank_detector.h", + "arc/tracing/arc_system_model.cc", + "arc/tracing/arc_system_model.h", + "arc/tracing/arc_system_stat_collector.cc", + "arc/tracing/arc_system_stat_collector.h", "arc/tracing/arc_tracing_bridge.cc", "arc/tracing/arc_tracing_bridge.h", "arc/tracing/arc_tracing_event.cc", @@ -595,6 +597,10 @@ "arc/tracing/arc_tracing_graphics_model.h", "arc/tracing/arc_tracing_model.cc", "arc/tracing/arc_tracing_model.h", + "arc/tracing/arc_value_event.cc", + "arc/tracing/arc_value_event.h", + "arc/tracing/arc_value_event_trimmer.cc", + "arc/tracing/arc_value_event_trimmer.h", "arc/tts/arc_tts_service.cc", "arc/tts/arc_tts_service.h", "arc/user_session/arc_user_session_service.cc", @@ -1995,6 +2001,8 @@ "ui/request_pin_view.h", "ui/screen_capture_notification_ui_chromeos.cc", "ui/screen_capture_notification_ui_chromeos.h", + "ui/tpm_auto_update_notification.cc", + "ui/tpm_auto_update_notification.h", "usb/cros_usb_detector.cc", "usb/cros_usb_detector.h", "virtual_machines/virtual_machines_util.cc", @@ -2263,7 +2271,9 @@ "arc/process/arc_process_unittest.cc", "arc/tracing/arc_cpu_event_unittest.cc", "arc/tracing/arc_graphics_jank_detector_unittest.cc", + "arc/tracing/arc_system_stat_collector_unittest.cc", "arc/tracing/arc_tracing_model_unittest.cc", + "arc/tracing/arc_value_event_unittest.cc", "arc/tts/arc_tts_service_unittest.cc", "arc/voice_interaction/fake_voice_interaction_controller.cc", "arc/voice_interaction/voice_interaction_controller_client_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc b/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc index c10f9fd..9d42620 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc +++ b/chrome/browser/chromeos/arc/tracing/arc_cpu_event.cc
@@ -78,6 +78,8 @@ break; case ArcCpuEvent::Type::kWakeUp: switch (type) { + case ArcCpuEvent::Type::kIdleIn: + break; case ArcCpuEvent::Type::kIdleOut: break; case ArcCpuEvent::Type::kWakeUp:
diff --git a/chrome/browser/chromeos/arc/tracing/arc_cpu_event_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_cpu_event_unittest.cc index 2573dc27..c815fc5 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_cpu_event_unittest.cc +++ b/chrome/browser/chromeos/arc/tracing/arc_cpu_event_unittest.cc
@@ -77,8 +77,7 @@ EXPECT_TRUE( CheckTrasition(Type::kIdleOut, idle_tid, Type::kActive, real_tid)); - EXPECT_FALSE( - CheckTrasition(Type::kWakeUp, real_tid, Type::kIdleIn, idle_tid)); + EXPECT_TRUE(CheckTrasition(Type::kWakeUp, real_tid, Type::kIdleIn, idle_tid)); EXPECT_TRUE( CheckTrasition(Type::kWakeUp, real_tid, Type::kIdleOut, idle_tid)); EXPECT_TRUE(CheckTrasition(Type::kWakeUp, real_tid, Type::kWakeUp, real_tid));
diff --git a/chrome/browser/chromeos/arc/tracing/arc_cpu_model.cc b/chrome/browser/chromeos/arc/tracing/arc_cpu_model.cc deleted file mode 100644 index 165e8e2..0000000 --- a/chrome/browser/chromeos/arc/tracing/arc_cpu_model.cc +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/chromeos/arc/tracing/arc_cpu_model.h" - -#include <stdio.h> - -#include "base/strings/stringprintf.h" - -namespace arc { - -namespace { - -constexpr char kKeyEvents[] = "events"; -constexpr char kKeyName[] = "name"; -constexpr char kKeyPid[] = "pid"; -constexpr char kKeyThreads[] = "threads"; - -bool LoadThreads(const base::Value* value, - ArcCpuModel::ThreadMap* out_threads) { - if (!value || !value->is_dict()) - return false; - - for (const auto& it : value->DictItems()) { - int tid; - if (sscanf(it.first.c_str(), "%d", &tid) != 1) - return false; - - if (!it.second.is_dict()) - return false; - - const base::Value* name = it.second.FindKey(kKeyName); - if (!name || !name->is_string()) - return false; - const base::Value* pid = it.second.FindKey(kKeyPid); - if (!pid || !pid->is_int()) - return false; - - (*out_threads)[tid] = - ArcCpuModel::ThreadInfo(pid->GetInt(), name->GetString()); - } - - return true; -} - -base::DictionaryValue SerializeThreads(const ArcCpuModel::ThreadMap& threads) { - base::DictionaryValue result; - - for (auto& thread_info : threads) { - base::DictionaryValue entry; - entry.SetKey(kKeyPid, base::Value(thread_info.second.pid)); - entry.SetKey(kKeyName, base::Value(thread_info.second.name)); - result.SetKey(base::StringPrintf("%d", thread_info.first), - std::move(entry)); - } - - return result; -} - -} // namespace - -ArcCpuModel::ThreadInfo::ThreadInfo() = default; - -ArcCpuModel::ThreadInfo::ThreadInfo(int pid, const std::string& name) - : pid(pid), name(name) {} - -bool ArcCpuModel::ThreadInfo::operator==(const ThreadInfo& other) const { - return pid == other.pid && name == other.name; -} - -ArcCpuModel::ArcCpuModel() = default; - -ArcCpuModel::~ArcCpuModel() = default; - -void ArcCpuModel::Reset() { - thread_map_.clear(); - all_cpu_events_.clear(); -} - -void ArcCpuModel::CopyFrom(const ArcCpuModel& other) { - thread_map_ = other.thread_map_; - all_cpu_events_ = other.all_cpu_events_; -} - -base::DictionaryValue ArcCpuModel::Serialize() const { - base::DictionaryValue result; - result.SetKey(kKeyThreads, SerializeThreads(thread_map_)); - result.SetKey(kKeyEvents, SerializeAllCpuEvents(all_cpu_events_)); - return result; -} - -bool ArcCpuModel::Load(const base::Value* root) { - if (!root || !root->is_dict()) - return false; - - if (!LoadThreads(root->FindKey(kKeyThreads), &thread_map_)) - return false; - - if (!LoadAllCpuEvents(root->FindKey(kKeyEvents), &all_cpu_events_)) - return false; - - return true; -} - -bool ArcCpuModel::operator==(const ArcCpuModel& other) const { - return thread_map_ == other.thread_map_ && - all_cpu_events_ == other.all_cpu_events_; -} - -} // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_model.cc b/chrome/browser/chromeos/arc/tracing/arc_system_model.cc new file mode 100644 index 0000000..f5cb611 --- /dev/null +++ b/chrome/browser/chromeos/arc/tracing/arc_system_model.cc
@@ -0,0 +1,120 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h" + +#include <stdio.h> + +#include "base/strings/stringprintf.h" + +namespace arc { + +namespace { + +constexpr char kKeyCpu[] = "cpu"; +constexpr char kKeyMemory[] = "memory"; +constexpr char kKeyName[] = "name"; +constexpr char kKeyPid[] = "pid"; +constexpr char kKeyThreads[] = "threads"; + +bool LoadThreads(const base::Value* value, + ArcSystemModel::ThreadMap* out_threads) { + if (!value || !value->is_dict()) + return false; + + for (const auto& it : value->DictItems()) { + int tid; + if (sscanf(it.first.c_str(), "%d", &tid) != 1) + return false; + + if (!it.second.is_dict()) + return false; + + const base::Value* name = it.second.FindKey(kKeyName); + if (!name || !name->is_string()) + return false; + const base::Value* pid = it.second.FindKey(kKeyPid); + if (!pid || !pid->is_int()) + return false; + + (*out_threads)[tid] = + ArcSystemModel::ThreadInfo(pid->GetInt(), name->GetString()); + } + + return true; +} + +base::DictionaryValue SerializeThreads( + const ArcSystemModel::ThreadMap& threads) { + base::DictionaryValue result; + + for (auto& thread_info : threads) { + base::DictionaryValue entry; + entry.SetKey(kKeyPid, base::Value(thread_info.second.pid)); + entry.SetKey(kKeyName, base::Value(thread_info.second.name)); + result.SetKey(base::StringPrintf("%d", thread_info.first), + std::move(entry)); + } + + return result; +} + +} // namespace + +ArcSystemModel::ThreadInfo::ThreadInfo() = default; + +ArcSystemModel::ThreadInfo::ThreadInfo(int pid, const std::string& name) + : pid(pid), name(name) {} + +bool ArcSystemModel::ThreadInfo::operator==(const ThreadInfo& other) const { + return pid == other.pid && name == other.name; +} + +ArcSystemModel::ArcSystemModel() = default; + +ArcSystemModel::~ArcSystemModel() = default; + +void ArcSystemModel::Reset() { + thread_map_.clear(); + all_cpu_events_.clear(); + memory_events_.clear(); +} + +void ArcSystemModel::CopyFrom(const ArcSystemModel& other) { + thread_map_ = other.thread_map_; + all_cpu_events_ = other.all_cpu_events_; + memory_events_ = other.memory_events_; +} + +base::DictionaryValue ArcSystemModel::Serialize() const { + base::DictionaryValue result; + result.SetKey(kKeyThreads, SerializeThreads(thread_map_)); + result.SetKey(kKeyCpu, SerializeAllCpuEvents(all_cpu_events_)); + result.SetKey(kKeyMemory, SerializeValueEvents(memory_events_)); + return result; +} + +bool ArcSystemModel::Load(const base::Value* root) { + if (!root || !root->is_dict()) + return false; + + if (!LoadThreads(root->FindKey(kKeyThreads), &thread_map_)) + return false; + + if (!LoadAllCpuEvents(root->FindKey(kKeyCpu), &all_cpu_events_)) + return false; + + if (!LoadValueEvents(root->FindKey(kKeyMemory), &memory_events_)) + return false; + + return true; +} + +bool ArcSystemModel::operator==(const ArcSystemModel& other) const { + return thread_map_ == other.thread_map_ && + all_cpu_events_ == other.all_cpu_events_ && + memory_events_ == other.memory_events_; +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_cpu_model.h b/chrome/browser/chromeos/arc/tracing/arc_system_model.h similarity index 61% rename from chrome/browser/chromeos/arc/tracing/arc_cpu_model.h rename to chrome/browser/chromeos/arc/tracing/arc_system_model.h index b3f82ec..94f6567 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_cpu_model.h +++ b/chrome/browser/chromeos/arc/tracing/arc_system_model.h
@@ -2,19 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_CPU_MODEL_H_ -#define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_CPU_MODEL_H_ +#ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_MODEL_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_MODEL_H_ #include <map> #include <string> #include "base/values.h" #include "chrome/browser/chromeos/arc/tracing/arc_cpu_event.h" +#include "chrome/browser/chromeos/arc/tracing/arc_value_event.h" namespace arc { -// Contains information about CPU activity events and involved threads. -class ArcCpuModel { +// Contains information about system activity and involved threads. System +// activity includes CPU and memory events. +class ArcSystemModel { public: static constexpr int kUnknownPid = -1; @@ -32,16 +34,16 @@ using ThreadMap = std::map<int, ThreadInfo>; - ArcCpuModel(); - ~ArcCpuModel(); + ArcSystemModel(); + ~ArcSystemModel(); void Reset(); - void CopyFrom(const ArcCpuModel& other); + void CopyFrom(const ArcSystemModel& other); base::DictionaryValue Serialize() const; bool Load(const base::Value* root); - bool operator==(const ArcCpuModel& other) const; + bool operator==(const ArcSystemModel& other) const; ThreadMap& thread_map() { return thread_map_; } const ThreadMap& thread_map() const { return thread_map_; } @@ -49,13 +51,17 @@ AllCpuEvents& all_cpu_events() { return all_cpu_events_; } const AllCpuEvents& all_cpu_events() const { return all_cpu_events_; } + ValueEvents& memory_events() { return memory_events_; } + const ValueEvents& memory_events() const { return memory_events_; } + private: ThreadMap thread_map_; AllCpuEvents all_cpu_events_; + ValueEvents memory_events_; - DISALLOW_COPY_AND_ASSIGN(ArcCpuModel); + DISALLOW_COPY_AND_ASSIGN(ArcSystemModel); }; } // namespace arc -#endif // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_CPU_MODEL_H_ +#endif // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_MODEL_H_
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.cc b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.cc new file mode 100644 index 0000000..c5660ca --- /dev/null +++ b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.cc
@@ -0,0 +1,221 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h" + +#include "base/bind.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/task/post_task.h" +#include "base/task_runner_util.h" +#include "base/threading/thread_restrictions.h" +#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h" +#include "chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h" + +namespace arc { + +namespace { + +// Interval to update system stats. +constexpr base::TimeDelta kSystemStatUpdateInterval = + base::TimeDelta::FromMilliseconds(10); + +bool IsWhitespace(char c) { + return c == ' ' || c == '\t' || c == '\n'; +} + +bool IsDigit(char c) { + return c >= '0' && c <= '9'; +} + +bool IsEnd(char c) { + return IsWhitespace(c) || c == 0; +} + +} // namespace + +struct ArcSystemStatCollector::Sample { + base::TimeTicks timestamp; + int swap_sectors_read = 0; + int swap_sectors_write = 0; + int swap_waiting_time_ms = 0; + int mem_total_kb = 0; + int mem_used_kb = 0; +}; + +// static +constexpr int ArcSystemStatCollector::kZramStatColumns[]; + +// static +constexpr int ArcSystemStatCollector::kMemInfoColumns[]; + +ArcSystemStatCollector::ArcSystemStatCollector() : weak_ptr_factory_(this) {} + +ArcSystemStatCollector::~ArcSystemStatCollector() = default; + +void ArcSystemStatCollector::Start(const base::TimeDelta& max_interval) { + const size_t sample_count = + 1 + max_interval.InMicroseconds() / + kSystemStatUpdateInterval.InMicroseconds(); + samples_.resize(sample_count); + write_index_ = 0; + // Maximum 10 warning per session. + missed_update_warning_left_ = 10; + + background_task_runner_ = base::CreateSequencedTaskRunnerWithTraits( + {base::MayBlock(), base::TaskPriority::USER_VISIBLE}); + timer_.Start( + FROM_HERE, kSystemStatUpdateInterval, + base::BindRepeating(&ArcSystemStatCollector::ScheduleSystemStatUpdate, + base::Unretained(this))); +} + +void ArcSystemStatCollector::Stop() { + weak_ptr_factory_.InvalidateWeakPtrs(); + background_task_runner_.reset(); + timer_.Stop(); + request_scheduled_ = false; +} + +void ArcSystemStatCollector::Flush(const base::TimeTicks& min_timestamp, + const base::TimeTicks& max_timestamp, + ArcSystemModel* system_model) { + DCHECK(!timer_.IsRunning()); + size_t sample_index = + write_index_ >= samples_.size() ? write_index_ - samples_.size() : 0; + ArcValueEventTrimmer mem_total(&system_model->memory_events(), + ArcValueEvent::Type::kMemTotal); + ArcValueEventTrimmer mem_used(&system_model->memory_events(), + ArcValueEvent::Type::kMemUsed); + ArcValueEventTrimmer swap_read(&system_model->memory_events(), + ArcValueEvent::Type::kSwapRead); + ArcValueEventTrimmer swap_write(&system_model->memory_events(), + ArcValueEvent::Type::kSwapWrite); + ArcValueEventTrimmer swap_wait(&system_model->memory_events(), + ArcValueEvent::Type::kSwapWait); + while (sample_index < write_index_) { + const Sample& sample = samples_[sample_index % samples_.size()]; + ++sample_index; + if (sample.timestamp > max_timestamp) + break; + if (sample.timestamp < min_timestamp) + continue; + const int64_t timestamp = + (sample.timestamp - base::TimeTicks()).InMicroseconds(); + mem_total.MaybeAdd(timestamp, sample.mem_total_kb); + mem_used.MaybeAdd(timestamp, sample.mem_used_kb); + swap_read.MaybeAdd(timestamp, sample.swap_sectors_read); + swap_write.MaybeAdd(timestamp, sample.swap_sectors_write); + swap_wait.MaybeAdd(timestamp, sample.swap_waiting_time_ms); + } +} + +void ArcSystemStatCollector::ScheduleSystemStatUpdate() { + if (request_scheduled_) { + if (missed_update_warning_left_-- > 0) + LOG(WARNING) << "Dropping update, already pending"; + return; + } + base::TaskRunner* task_runner = background_task_runner_.get(); + base::PostTaskAndReplyWithResult( + task_runner, FROM_HERE, + base::BindOnce(&ArcSystemStatCollector::ReadSystemStatOnBackgroundThread), + base::BindOnce(&ArcSystemStatCollector::UpdateSystemStatOnUiThread, + weak_ptr_factory_.GetWeakPtr())); + request_scheduled_ = true; +} + +// static +ArcSystemStatCollector::RuntimeFrame +ArcSystemStatCollector::ReadSystemStatOnBackgroundThread() { + const base::FilePath zram_stat_path( + FILE_PATH_LITERAL("/sys/block/zram0/stat")); + const base::FilePath mem_info_path(FILE_PATH_LITERAL("/proc/meminfo")); + + ArcSystemStatCollector::RuntimeFrame current_frame; + if (!ParseStatFile(zram_stat_path, kZramStatColumns, + current_frame.zram_stat)) { + memset(current_frame.zram_stat, 0, sizeof(current_frame.zram_stat)); + static bool error_reported = false; + if (!error_reported) { + LOG(ERROR) << "Failed to read zram stat file: " << zram_stat_path.value(); + error_reported = true; + } + } + if (!ParseStatFile(mem_info_path, kMemInfoColumns, current_frame.mem_info)) { + memset(current_frame.mem_info, 0, sizeof(current_frame.mem_info)); + static bool error_reported = false; + if (!error_reported) { + LOG(ERROR) << "Failed to read mem info file: " << mem_info_path.value(); + error_reported = true; + } + } + return current_frame; +} + +void ArcSystemStatCollector::UpdateSystemStatOnUiThread( + RuntimeFrame current_frame) { + DCHECK(request_scheduled_); + request_scheduled_ = false; + DCHECK(!samples_.empty()); + Sample& current_sample = samples_[write_index_ % samples_.size()]; + current_sample.timestamp = base::TimeTicks::Now(); + current_sample.mem_total_kb = current_frame.mem_info[0]; + // Total - available. + current_sample.mem_used_kb = + current_frame.mem_info[0] - current_frame.mem_info[1]; + // We calculate delta, so ignore first update. + if (write_index_) { + current_sample.swap_sectors_read = + current_frame.zram_stat[0] - previous_frame_.zram_stat[0]; + current_sample.swap_sectors_write = + current_frame.zram_stat[1] - previous_frame_.zram_stat[1]; + current_sample.swap_waiting_time_ms = + current_frame.zram_stat[2] - previous_frame_.zram_stat[2]; + } + DCHECK_GE(current_sample.swap_sectors_read, 0); + DCHECK_GE(current_sample.swap_sectors_write, 0); + DCHECK_GE(current_sample.swap_waiting_time_ms, 0); + DCHECK_GE(current_sample.mem_total_kb, 0); + DCHECK_GE(current_sample.mem_used_kb, 0); + previous_frame_ = current_frame; + ++write_index_; +} + +bool ParseStatFile(const base::FilePath& path, + const int* columns, + int64_t* output) { + char buffer[128]; + const int read = base::ReadFile(path, buffer, sizeof(buffer) - 1); + if (read < 0) + return false; + buffer[read] = 0; + int column_index = 0; + const char* scan = buffer; + while (true) { + // Skip whitespace. + while (IsWhitespace(*scan)) + ++scan; + if (*columns != column_index) { + // Just skip this entry. It may be digits or text. + while (!IsWhitespace(*scan)) + ++scan; + } else { + int64_t value = 0; + while (IsDigit(*scan)) { + value = 10 * value + *scan - '0'; + ++scan; + } + *output++ = value; + ++columns; + if (*columns < 0) + return IsEnd(*scan); // All columns are read. + } + if (!IsWhitespace(*scan)) + return false; + ++column_index; + } +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h new file mode 100644 index 0000000..4cc2c2f --- /dev/null +++ b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h
@@ -0,0 +1,116 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_STAT_COLLECTOR_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_STAT_COLLECTOR_H_ + +#include <vector> + +#include "base/files/file_path.h" +#include "base/macros.h" +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" + +namespace base { +class FilePath; +class TimeDelta; +class SequencedTaskRunner; +} // namespace base + +namespace arc { + +class ArcSystemModel; + +// Collects various system statistics and appends results to the +// |ArcSystemModel|. +class ArcSystemStatCollector { + public: + // Indices of fields to parse zram info, see + // https://www.kernel.org/doc/Documentation/block/stat.txt + static constexpr int kZramStatColumns[] = { + 2, // number of sectors read + 6, // number of sectors written + 10, // total wait time for all requests (milliseconds) + -1, // End of sequence + }; + + // Indices of fields to parse /proc/meminfo + // As an example: + // MemTotal: 8058940 kB + // MemFree: 314184 kB + // MemAvailable: 2714260 kB + // ... + static constexpr int kMemInfoColumns[] = { + 1, // MemTotal in kb. + 7, // MemAvailable in kb. + -1, // End of sequence + }; + + ArcSystemStatCollector(); + ~ArcSystemStatCollector(); + + // Starts sample collection, |max_interval| defines the maximum interval and + // it is used for circle buffer size calculation. + void Start(const base::TimeDelta& max_interval); + // Stops sample collection. + void Stop(); + // Appends collected samples to |system_model|.|min_timestamp| and + // |max_timestamp| specify the minimum and maximum timestamps respectively to + // add to |system_model|. + void Flush(const base::TimeTicks& min_timestamp, + const base::TimeTicks& max_timestamp, + ArcSystemModel* system_model); + + private: + struct Sample; + + struct RuntimeFrame { + // read, written sectors and total time in milliseconds. + int64_t zram_stat[base::size(kZramStatColumns) - 1] = {0}; + // total, available. + int64_t mem_info[base::size(kMemInfoColumns) - 1] = {0}; + }; + + // Schedule reading System stat files in |ReadSystemStatOnBackgroundThread| on + // background thread. Once ready result is passed to + // |UpdateSystemStatOnUiThread| + void ScheduleSystemStatUpdate(); + static RuntimeFrame ReadSystemStatOnBackgroundThread(); + void UpdateSystemStatOnUiThread(RuntimeFrame current_frame); + + // To schedule updates of system stat. + base::RepeatingTimer timer_; + // Performs reading kernel stat files on backgrond thread. + scoped_refptr<base::SequencedTaskRunner> background_task_runner_; + // Use to prevent double scheduling. + bool request_scheduled_ = false; + // Used to limit the number of warnings printed in case System stat update is + // dropped due to previous update is in progress. + int missed_update_warning_left_ = 0; + + // Samples are implemented as a circle buffer. + std::vector<Sample> samples_; + size_t write_index_ = 0; + + // Used to calculate delta. + RuntimeFrame previous_frame_; + + base::WeakPtrFactory<ArcSystemStatCollector> weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(ArcSystemStatCollector); +}; + +// Helper that reads and parses stat file containing decimal number separated by +// whitespace and text fields. It does not have any dynamic memory allocation. +// |path| specifies the file to read and parse. |columns| contains index of +// column to parse, end of sequence is specified by terminator -1. |output| +// receives parsed value. Must be the size as |columns| size - 1. +bool ParseStatFile(const base::FilePath& path, + const int* columns, + int64_t* output); + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_SYSTEM_STAT_COLLECTOR_H_
diff --git a/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector_unittest.cc new file mode 100644 index 0000000..1e0a5b7 --- /dev/null +++ b/chrome/browser/chromeos/arc/tracing/arc_system_stat_collector_unittest.cc
@@ -0,0 +1,43 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h" + +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "chrome/common/chrome_paths.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace arc { + +using ArcSystemStatCollectorTest = testing::Test; + +namespace { + +base::FilePath GetPath(const std::string& name) { + base::FilePath base_path; + base::PathService::Get(chrome::DIR_TEST_DATA, &base_path); + return base_path.Append("arc_graphics_tracing").Append(name); +} + +} // namespace + +TEST_F(ArcSystemStatCollectorTest, Parse) { + int64_t zram_values[3]; + EXPECT_TRUE(ParseStatFile(GetPath("zram_stat"), + ArcSystemStatCollector::kZramStatColumns, + zram_values)); + EXPECT_EQ(2384, zram_values[0]); + EXPECT_EQ(56696, zram_values[1]); + EXPECT_EQ(79, zram_values[2]); + + int64_t mem_values[2]; + EXPECT_TRUE(ParseStatFile(GetPath("proc_meminfo"), + ArcSystemStatCollector::kMemInfoColumns, + mem_values)); + EXPECT_EQ(8058940, mem_values[0]); + EXPECT_EQ(2714260, mem_values[1]); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc index 4375f338..9d728c3 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.cc
@@ -36,10 +36,10 @@ constexpr char kKeyAndroid[] = "android"; constexpr char kKeyBuffers[] = "buffers"; constexpr char kKeyChrome[] = "chrome"; -constexpr char kKeyCpu[] = "cpu"; constexpr char kKeyDuration[] = "duration"; constexpr char kKeyGlobalEvents[] = "global_events"; constexpr char kKeyViews[] = "views"; +constexpr char kKeySystem[] = "system"; constexpr char kKeyTaskId[] = "task_id"; constexpr char kAcquireBufferQuery[] = @@ -980,7 +980,7 @@ return false; } - cpu_model_.CopyFrom(common_model.cpu_model()); + system_model_.CopyFrom(common_model.system_model()); NormalizeTimestamps(); @@ -1012,13 +1012,18 @@ } } - for (const auto& cpu_events : cpu_model_.all_cpu_events()) { + for (const auto& cpu_events : system_model_.all_cpu_events()) { if (!cpu_events.empty()) { min = std::min(min, cpu_events.front().timestamp); max = std::max(max, cpu_events.back().timestamp); } } + if (!system_model_.memory_events().empty()) { + min = std::min(min, system_model_.memory_events().front().timestamp); + max = std::max(max, system_model_.memory_events().back().timestamp); + } + duration_ = max - min + 1; for (BufferEvents* buffer : all_buffers) { @@ -1026,10 +1031,13 @@ event.timestamp -= min; } - for (auto& cpu_events : cpu_model_.all_cpu_events()) { + for (auto& cpu_events : system_model_.all_cpu_events()) { for (auto& cpu_event : cpu_events) cpu_event.timestamp -= min; } + + for (auto& memory_event : system_model_.memory_events()) + memory_event.timestamp -= min; } void ArcTracingGraphicsModel::Reset() { @@ -1037,7 +1045,7 @@ android_top_level_.Reset(); view_buffers_.clear(); chrome_buffer_id_to_task_id_.clear(); - cpu_model_.Reset(); + system_model_.Reset(); duration_ = 0; } @@ -1070,8 +1078,8 @@ // Chrome top events root->SetKey(kKeyChrome, SerializeEventsContainer(chrome_top_level_)); - // CPU. - root->SetKey(kKeyCpu, cpu_model_.Serialize()); + // System. + root->SetKey(kKeySystem, system_model_.Serialize()); // Duration. root->SetKey(kKeyDuration, base::Value(static_cast<double>(duration_))); @@ -1130,7 +1138,7 @@ if (!LoadEventsContainer(root.FindKey(kKeyChrome), &chrome_top_level_)) return false; - if (!cpu_model_.Load(root.FindKey(kKeyCpu))) + if (!system_model_.Load(root.FindKey(kKeySystem))) return false; const base::Value* duration = root.FindKey(kKeyDuration);
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h index a62c407c..92aee932 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h
@@ -12,7 +12,7 @@ #include "base/macros.h" #include "base/values.h" -#include "chrome/browser/chromeos/arc/tracing/arc_cpu_model.h" +#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h" namespace arc { @@ -154,8 +154,8 @@ const EventsContainer& chrome_top_level() const { return chrome_top_level_; } - ArcCpuModel& cpu_model() { return cpu_model_; } - const ArcCpuModel& cpu_model() const { return cpu_model_; } + ArcSystemModel& system_model() { return system_model_; } + const ArcSystemModel& system_model() const { return system_model_; } private: // Normalizes timestamp for all events by subtracting the timestamp of the @@ -178,7 +178,7 @@ // Map Chrome buffer id to task id. std::map<std::string, int> chrome_buffer_id_to_task_id_; // CPU event model. - ArcCpuModel cpu_model_; + ArcSystemModel system_model_; DISALLOW_COPY_AND_ASSIGN(ArcTracingGraphicsModel); };
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_model.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_model.cc index 8968f308..2d94d3e3 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_model.cc +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_model.cc
@@ -421,12 +421,13 @@ return false; } - if (cpu_model_.thread_map().find(tid) == cpu_model_.thread_map().end()) { + if (system_model_.thread_map().find(tid) == + system_model_.thread_map().end()) { int thread_name_start = 0; while (line[thread_name_start] == ' ') ++thread_name_start; - cpu_model_.thread_map()[tid] = ArcCpuModel::ThreadInfo( - ArcCpuModel::kUnknownPid, + system_model_.thread_map()[tid] = ArcSystemModel::ThreadInfo( + ArcSystemModel::kUnknownPid, line.substr(thread_name_start, 16 - thread_name_start)); } @@ -461,20 +462,20 @@ return false; } } else if (!strncmp(&line[separator_position], kCpuIdle, kCpuIdleLength)) { - if (!HandleCpuIdle(&cpu_model_.all_cpu_events(), timestamp, cpu_id, tid, - line, separator_position + kCpuIdleLength)) { + if (!HandleCpuIdle(&system_model_.all_cpu_events(), timestamp, cpu_id, + tid, line, separator_position + kCpuIdleLength)) { return false; } } else if (!strncmp(&line[separator_position], kSchedWakeUp, kSchedWakeUpLength)) { - if (!HandleSchedWakeUp(&cpu_model_.all_cpu_events(), timestamp, cpu_id, + if (!HandleSchedWakeUp(&system_model_.all_cpu_events(), timestamp, cpu_id, tid, line, separator_position + kSchedWakeUpLength)) { return false; } } else if (!strncmp(&line[separator_position], kSchedSwitch, kSchedSwitchLength)) { - if (!HandleSchedSwitch(&cpu_model_.all_cpu_events(), timestamp, cpu_id, + if (!HandleSchedSwitch(&system_model_.all_cpu_events(), timestamp, cpu_id, tid, line, separator_position + kSchedSwitchLength)) { return false;
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_model.h b/chrome/browser/chromeos/arc/tracing/arc_tracing_model.h index 716c5085..234f0b7 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_model.h +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_model.h
@@ -12,7 +12,7 @@ #include "base/macros.h" #include "base/values.h" -#include "chrome/browser/chromeos/arc/tracing/arc_cpu_model.h" +#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h" namespace arc { @@ -57,7 +57,8 @@ // Dumps this model to |stream|. void Dump(std::ostream& stream) const; - const ArcCpuModel& cpu_model() const { return cpu_model_; } + ArcSystemModel& system_model() { return system_model_; } + const ArcSystemModel& system_model() const { return system_model_; } private: // Processes list of events. Returns true in case all events were processed @@ -77,7 +78,7 @@ // tracing events. std::map<std::string, TracingEvents> group_events_; - ArcCpuModel cpu_model_; + ArcSystemModel system_model_; // Metadata events. TracingEvents metadata_events_;
diff --git a/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc index 53ecc86..5e146e7f 100644 --- a/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc +++ b/chrome/browser/chromeos/arc/tracing/arc_tracing_model_unittest.cc
@@ -144,8 +144,8 @@ ASSERT_TRUE(model.Build(tracing_data)); // 4 CPU cores. - EXPECT_EQ(4U, model.cpu_model().all_cpu_events().size()); - for (const auto& cpu_events : model.cpu_model().all_cpu_events()) + EXPECT_EQ(4U, model.system_model().all_cpu_events().size()); + for (const auto& cpu_events : model.system_model().all_cpu_events()) EXPECT_TRUE(ValidateCpuEvents(cpu_events)); // Perform several well-known queries. @@ -212,14 +212,14 @@ // Note, CPU events in |graphics_model| are normalized by timestamp. So they // are not equal and we cannot do direct comparison. - ASSERT_EQ(graphics_model.cpu_model().all_cpu_events().size(), - model.cpu_model().all_cpu_events().size()); - EXPECT_EQ(graphics_model.cpu_model().thread_map(), - model.cpu_model().thread_map()); - for (size_t i = 0; i < graphics_model.cpu_model().all_cpu_events().size(); + ASSERT_EQ(graphics_model.system_model().all_cpu_events().size(), + model.system_model().all_cpu_events().size()); + EXPECT_EQ(graphics_model.system_model().thread_map(), + model.system_model().thread_map()); + for (size_t i = 0; i < graphics_model.system_model().all_cpu_events().size(); ++i) { - EXPECT_EQ(graphics_model.cpu_model().all_cpu_events()[i].size(), - model.cpu_model().all_cpu_events()[i].size()); + EXPECT_EQ(graphics_model.system_model().all_cpu_events()[i].size(), + model.system_model().all_cpu_events()[i].size()); } EXPECT_GT(graphics_model.duration(), 0U); @@ -238,7 +238,8 @@ graphics_model_loaded.chrome_top_level()); EXPECT_EQ(graphics_model.view_buffers(), graphics_model_loaded.view_buffers()); - EXPECT_EQ(graphics_model.cpu_model(), graphics_model_loaded.cpu_model()); + EXPECT_EQ(graphics_model.system_model(), + graphics_model_loaded.system_model()); EXPECT_EQ(graphics_model.duration(), graphics_model_loaded.duration()); }
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event.cc b/chrome/browser/chromeos/arc/tracing/arc_value_event.cc new file mode 100644 index 0000000..4f140c5 --- /dev/null +++ b/chrome/browser/chromeos/arc/tracing/arc_value_event.cc
@@ -0,0 +1,73 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/tracing/arc_value_event.h" + +namespace arc { + +ArcValueEvent::ArcValueEvent(int64_t timestamp, Type type, int value) + : timestamp(timestamp), type(type), value(value) {} + +bool ArcValueEvent::operator==(const ArcValueEvent& other) const { + return timestamp == other.timestamp && type == other.type && + value == other.value; +} + +base::ListValue SerializeValueEvents(const ValueEvents& value_events) { + base::ListValue list; + for (const auto& event : value_events) { + base::ListValue event_value; + event_value.GetList().push_back(base::Value(static_cast<int>(event.type))); + event_value.GetList().push_back( + base::Value(static_cast<double>(event.timestamp))); + event_value.GetList().push_back(base::Value(event.value)); + list.GetList().emplace_back(std::move(event_value)); + } + return list; +} + +bool LoadValueEvents(const base::Value* value, ValueEvents* value_events) { + if (!value || !value->is_list()) + return false; + + int64_t previous_timestamp = 0; + for (const auto& entry : value->GetList()) { + if (!entry.is_list() || entry.GetList().size() != 3) + return false; + if (!entry.GetList()[0].is_int()) + return false; + const ArcValueEvent::Type type = + static_cast<ArcValueEvent::Type>(entry.GetList()[0].GetInt()); + switch (type) { + case ArcValueEvent::Type::kMemTotal: + case ArcValueEvent::Type::kMemUsed: + case ArcValueEvent::Type::kSwapRead: + case ArcValueEvent::Type::kSwapWrite: + case ArcValueEvent::Type::kSwapWait: + break; + default: + return false; + } + if (!entry.GetList()[1].is_double() && !entry.GetList()[1].is_int()) + return false; + const int64_t timestamp = entry.GetList()[1].GetDouble(); + if (timestamp < previous_timestamp) + return false; + if (!entry.GetList()[2].is_int()) + return false; + const int value = entry.GetList()[2].GetInt(); + value_events->emplace_back(timestamp, type, value); + previous_timestamp = timestamp; + } + + return true; +} + +std::ostream& operator<<(std::ostream& os, ArcValueEvent::Type event_type) { + return os << static_cast< + typename std::underlying_type<ArcValueEvent::Type>::type>( + event_type); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event.h b/chrome/browser/chromeos/arc/tracing/arc_value_event.h new file mode 100644 index 0000000..2876d3bc --- /dev/null +++ b/chrome/browser/chromeos/arc/tracing/arc_value_event.h
@@ -0,0 +1,54 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_H_ + +#include <ostream> +#include <vector> + +#include "base/values.h" + +namespace arc { + +// Tracing event with a value. +struct ArcValueEvent { + enum class Type { + kMemTotal, + kMemUsed, + kSwapRead, + kSwapWrite, + kSwapWait, + }; + + ArcValueEvent(int64_t timestamp, Type type, int value); + + bool operator==(const ArcValueEvent& other) const; + + int64_t timestamp; + Type type; + /** + * kMemTotal - kb. + * kMemUsed - kb. + * kSwapRead - number of sectors. + * kSwapWrite - number of sectors. + * kSwapWait - milliseconds. + */ + int value; +}; + +using ValueEvents = std::vector<ArcValueEvent>; + +// Serializes value events into |base::ListValue|. +base::ListValue SerializeValueEvents(const ValueEvents& value_events); + +// Loads value events from |base::ListValue|. Returns true in case value +// events were loaded successfully. +bool LoadValueEvents(const base::Value* value, ValueEvents* value_events); + +std::ostream& operator<<(std::ostream& os, ArcValueEvent::Type event_type); + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_H_
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.cc b/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.cc new file mode 100644 index 0000000..81360397 --- /dev/null +++ b/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.cc
@@ -0,0 +1,36 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h" + +namespace arc { + +ArcValueEventTrimmer::ArcValueEventTrimmer(ValueEvents* events, + ArcValueEvent::Type type) + : events_(events), type_(type) {} + +ArcValueEventTrimmer::~ArcValueEventTrimmer() { + Flush(); +} + +void ArcValueEventTrimmer::MaybeAdd(int64_t timestamp, int value) { + if (!first_event_ && last_value_ == value) { + last_trimmed_timestamp_ = timestamp; + was_trimmed_ = true; + return; + } + Flush(); + events_->emplace_back(timestamp, type_, value); + last_value_ = value; + first_event_ = false; + was_trimmed_ = false; +} + +void ArcValueEventTrimmer::Flush() { + if (was_trimmed_) + events_->emplace_back(last_trimmed_timestamp_, type_, last_value_); + was_trimmed_ = false; +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h b/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h new file mode 100644 index 0000000..21dfbe96 --- /dev/null +++ b/chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h
@@ -0,0 +1,46 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_TRIMMER_H_ +#define CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_TRIMMER_H_ + +#include "base/values.h" +#include "chrome/browser/chromeos/arc/tracing/arc_value_event.h" + +namespace arc { + +// Helper that prevents adding events with the same value. +// For example event values (value:timestamp) +// 1:100 2:101 2:102 2:103 2:104 1:105 2:106 +// would be trimmed to +// 1:100 2:101 2:104 1:105 2:106. +class ArcValueEventTrimmer { + public: + ArcValueEventTrimmer(ValueEvents* events, ArcValueEvent::Type type); + ~ArcValueEventTrimmer(); + + // May be add the next event, in case it is not trimmed out. + void MaybeAdd(int64_t timestamp, int value); + + private: + // In case value has changed, insert last trimmed value. + void Flush(); + + ValueEvents* const events_; + const ArcValueEvent::Type type_; + // Indicate if this is first event that would never be trimmed. + bool first_event_ = true; + // Set to true in case last event was trimmed. + bool was_trimmed_ = false; + // Timestamp of the last trimmed event. + int64_t last_trimmed_timestamp_; + // Value of the last event. + int last_value_ = 0; + + DISALLOW_COPY_AND_ASSIGN(ArcValueEventTrimmer); +}; + +} // namespace arc + +#endif // CHROME_BROWSER_CHROMEOS_ARC_TRACING_ARC_VALUE_EVENT_TRIMMER_H_
diff --git a/chrome/browser/chromeos/arc/tracing/arc_value_event_unittest.cc b/chrome/browser/chromeos/arc/tracing/arc_value_event_unittest.cc new file mode 100644 index 0000000..7ced142 --- /dev/null +++ b/chrome/browser/chromeos/arc/tracing/arc_value_event_unittest.cc
@@ -0,0 +1,61 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/arc/tracing/arc_value_event.h" +#include "chrome/browser/chromeos/arc/tracing/arc_value_event_trimmer.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace arc { + +using ArcValueEventTest = testing::Test; +using Type = ArcValueEvent::Type; + +TEST_F(ArcValueEventTest, Trimmer) { + ValueEvents events; + { + ArcValueEventTrimmer trimmer(&events, ArcValueEvent::Type::kMemUsed); + trimmer.MaybeAdd(100 /* timestamp */, 1 /* value */); + ASSERT_EQ(1U, events.size()); + EXPECT_EQ(ArcValueEvent(100, ArcValueEvent::Type::kMemUsed, 1), events[0]); + trimmer.MaybeAdd(101, 2); + ASSERT_EQ(2U, events.size()); + EXPECT_EQ(ArcValueEvent(101, ArcValueEvent::Type::kMemUsed, 2), events[1]); + trimmer.MaybeAdd(102, 2); + EXPECT_EQ(2U, events.size()); + trimmer.MaybeAdd(103, 2); + EXPECT_EQ(2U, events.size()); + trimmer.MaybeAdd(104, 2); + EXPECT_EQ(2U, events.size()); + trimmer.MaybeAdd(105, 1); + ASSERT_EQ(4U, events.size()); + EXPECT_EQ(ArcValueEvent(104, ArcValueEvent::Type::kMemUsed, 2), events[2]); + EXPECT_EQ(ArcValueEvent(105, ArcValueEvent::Type::kMemUsed, 1), events[3]); + trimmer.MaybeAdd(106, 2); + ASSERT_EQ(5U, events.size()); + EXPECT_EQ(ArcValueEvent(106, ArcValueEvent::Type::kMemUsed, 2), events[4]); + trimmer.MaybeAdd(107, 2); + EXPECT_EQ(5U, events.size()); + } + // Check auto-close, last trimmed is added. + ASSERT_EQ(6U, events.size()); + EXPECT_EQ(ArcValueEvent(107, ArcValueEvent::Type::kMemUsed, 2), events[5]); +} + +TEST_F(ArcValueEventTest, Serialize) { + const ValueEvents events{ + {100 /* timestamp */, ArcValueEvent::Type::kMemTotal, 10 /* value */}, + {101 /* timestamp */, ArcValueEvent::Type::kMemUsed, 20 /* value */}, + {102 /* timestamp */, ArcValueEvent::Type::kSwapRead, 30 /* value */}, + {103 /* timestamp */, ArcValueEvent::Type::kSwapWrite, 40 /* value */}, + {104 /* timestamp */, ArcValueEvent::Type::kSwapWait, 50 /* value */}}; + + const base::ListValue value = SerializeValueEvents(events); + + ValueEvents loaded_events; + EXPECT_TRUE(LoadValueEvents(&value, &loaded_events)); + EXPECT_EQ(events, loaded_events); +} + +} // namespace arc
diff --git a/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc b/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc index 169c688..6fb8d54 100644 --- a/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc +++ b/chrome/browser/chromeos/kiosk_next_home/app_controller_service_unittest.cc
@@ -23,10 +23,14 @@ #include "chrome/test/base/testing_profile.h" #include "chromeos/constants/chromeos_switches.h" #include "components/arc/test/fake_app_instance.h" +#include "components/keyed_service/core/keyed_service.h" #include "content/public/test/test_browser_thread_bundle.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/bindings/interface_request.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +#include "ui/display/types/display_constants.h" +#include "ui/events/event_constants.h" namespace chromeos { namespace kiosk_next_home { @@ -61,13 +65,36 @@ std::vector<mojom::AppPtr> app_updates_; }; +// Mock instance for the AppServiceProxy. It only overrides a subset of the +// methods provided by the proxy since we expect that most tests can be written +// with their real implementations (i.e. AppRegistryCache()). +class MockAppServiceProxy : public KeyedService, public apps::AppServiceProxy { + public: + static MockAppServiceProxy* OverrideRealProxyForProfile(Profile* profile) { + return static_cast<MockAppServiceProxy*>( + apps::AppServiceProxyFactory::GetInstance()->SetTestingFactoryAndUse( + profile, base::BindRepeating([](content::BrowserContext* context) { + return static_cast<std::unique_ptr<KeyedService>>( + std::make_unique<MockAppServiceProxy>()); + }))); + } + + // apps::AppServiceProxy: + MOCK_METHOD4(Launch, + void(const std::string& app_id, + int32_t event_flags, + apps::mojom::LaunchSource launch_source, + int64_t display_id)); + MOCK_METHOD1(Uninstall, void(const std::string& app_id)); +}; + class AppControllerServiceTest : public testing::Test { protected: void SetUp() override { profile_ = std::make_unique<TestingProfile>(); arc_test_.SetUp(profile()); - proxy_ = apps::AppServiceProxyFactory::GetForProfile(profile()); + proxy_ = MockAppServiceProxy::OverrideRealProxyForProfile(profile()); app_controller_service_ = AppControllerService::Get(profile()); @@ -81,6 +108,8 @@ Profile* profile() { return profile_.get(); } + MockAppServiceProxy* proxy() { return proxy_; } + AppControllerService* service() { return app_controller_service_; } std::string GetAppIdFromAndroidPackage(const std::string& package) { @@ -125,7 +154,7 @@ // returns them in a map keyed by their |app_id|. AppMap GetAppsFromController() { AppMap apps; - app_controller_service_->GetApps(base::BindLambdaForTesting( + service()->GetApps(base::BindLambdaForTesting( [&apps](std::vector<mojom::AppPtr> app_list) { for (const auto& app : app_list) { apps[app->app_id] = app.Clone(); @@ -160,7 +189,7 @@ bool returned_success; std::string returned_android_id; - app_controller_service_->GetArcAndroidId(base::BindLambdaForTesting( + service()->GetArcAndroidId(base::BindLambdaForTesting( [&returned_success, &returned_android_id]( bool success, const std::string& android_id) { returned_success = success; @@ -230,8 +259,8 @@ content::TestBrowserThreadBundle test_browser_thread_bundle_; std::unique_ptr<TestingProfile> profile_; ArcAppTest arc_test_; - apps::AppServiceProxy* proxy_; - AppControllerService* app_controller_service_; + MockAppServiceProxy* proxy_ = nullptr; + AppControllerService* app_controller_service_ = nullptr; std::unique_ptr<FakeAppControllerClient> client_; void ExpectEqualApps(const mojom::App& expected_app, @@ -651,5 +680,19 @@ ExpectAppChangedUpdates({first_app_state}); } +TEST_F(AppControllerServiceTest, LaunchAppCallsAppServiceCorrectly) { + EXPECT_CALL(*proxy(), Launch("fake_app_id", ui::EventFlags::EF_NONE, + apps::mojom::LaunchSource::kFromKioskNextHome, + display::kDefaultDisplayId)); + + service()->LaunchApp("fake_app_id"); +} + +TEST_F(AppControllerServiceTest, UninstallAppCallsAppServiceCorrectly) { + EXPECT_CALL(*proxy(), Uninstall("fake_app_id")); + + service()->UninstallApp("fake_app_id"); +} + } // namespace kiosk_next_home } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/session/chrome_session_manager.cc b/chrome/browser/chromeos/login/session/chrome_session_manager.cc index f306d370..afc5a99 100644 --- a/chrome/browser/chromeos/login/session/chrome_session_manager.cc +++ b/chrome/browser/chromeos/login/session/chrome_session_manager.cc
@@ -31,6 +31,7 @@ #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/policy/app_install_event_log_manager_wrapper.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#include "chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/tether/tether_service.h" #include "chrome/browser/chromeos/tpm_firmware_update_notification.h" @@ -194,6 +195,11 @@ UserSessionManager::GetInstance()->CheckEolStatus(user_profile); tpm_firmware_update::ShowNotificationIfNeeded(user_profile); + g_browser_process->platform_part() + ->browser_policy_connector_chromeos() + ->GetTPMAutoUpdateModePolicyHandler() + ->ShowTPMAutoUpdateNotificationIfNeeded(); + ArcTermsOfServiceScreen::MaybeLaunchArcSettings(user_profile); SyncConsentScreen::MaybeLaunchSyncConsentSettings(user_profile); UserSessionManager::GetInstance()->StartAccountManagerMigration(user_profile);
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc index 0e02efe..ec87b0d 100644 --- a/chrome/browser/chromeos/login/session/user_session_manager.cc +++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -76,6 +76,7 @@ #include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/policy/app_install_event_log_manager_wrapper.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" +#include "chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/tether/tether_service.h" @@ -2185,6 +2186,11 @@ // and show the message accordingly. tpm_firmware_update::ShowNotificationIfNeeded(profile); + g_browser_process->platform_part() + ->browser_policy_connector_chromeos() + ->GetTPMAutoUpdateModePolicyHandler() + ->ShowTPMAutoUpdateNotificationIfNeeded(); + if (should_launch_browser_) { ArcTermsOfServiceScreen::MaybeLaunchArcSettings(profile); SyncConsentScreen::MaybeLaunchSyncConsentSettings(profile);
diff --git a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc index 545fe4e3..7d45d80 100644 --- a/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc +++ b/chrome/browser/chromeos/login/signin/oauth2_browsertest.cc
@@ -53,6 +53,7 @@ #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h" +#include "content/public/browser/storage_partition.h" #include "content/public/test/browser_test_utils.h" #include "extensions/browser/extension_host.h" #include "extensions/browser/process_manager.h" @@ -309,9 +310,9 @@ test::OobeJS().ExpectTrue("!!document.querySelector('#account-picker')"); test::OobeJS().ExpectTrue("!!document.querySelector('#pod-row')"); - std::string account_id = PickAccountId( - ProfileManager::GetPrimaryUserProfile(), kTestGaiaId, kTestEmail); - + // PickAccountId does not work at this point as the primary user profile has + // not yet been created. + const std::string account_id = kTestEmail; EXPECT_EQ(GetOAuthStatusFromLocalState(account_id), user_manager::User::OAUTH2_TOKEN_STATUS_VALID); @@ -320,6 +321,7 @@ TryToLogin(AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId), kTestAccountPassword)); Profile* profile = ProfileManager::GetPrimaryUserProfile(); + ASSERT_EQ(account_id, PickAccountId(profile, kTestGaiaId, kTestEmail)); // Wait for the session merge to finish. WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_DONE); @@ -483,54 +485,38 @@ DISALLOW_COPY_AND_ASSIGN(OAuth2Test); }; -class CookieReader : public base::RefCountedThreadSafe<CookieReader> { +class CookieReader { public: - CookieReader() {} + CookieReader() = default; + ~CookieReader() = default; void ReadCookies(Profile* profile) { - context_ = profile->GetRequestContext(); - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::IO}, - base::BindOnce(&CookieReader::ReadCookiesOnIOThread, this)); - run_loop_ = std::make_unique<base::RunLoop>(); - run_loop_->Run(); + base::RunLoop run_loop; + content::BrowserContext::GetDefaultStoragePartition(profile) + ->GetCookieManagerForBrowserProcess() + ->GetAllCookies(base::BindOnce(&CookieReader::OnGotAllCookies, + base::Unretained(this), + run_loop.QuitClosure())); + run_loop.Run(); } std::string GetCookieValue(const std::string& name) { - for (std::vector<net::CanonicalCookie>::const_iterator iter = - cookie_list_.begin(); - iter != cookie_list_.end(); ++iter) { - if (iter->Name() == name) { - return iter->Value(); + for (const auto& item : cookie_list_) { + if (item.Name() == name) { + return item.Value(); } } return std::string(); } private: - friend class base::RefCountedThreadSafe<CookieReader>; - - virtual ~CookieReader() {} - - void ReadCookiesOnIOThread() { - context_->GetURLRequestContext()->cookie_store()->GetAllCookiesAsync( - base::BindOnce(&CookieReader::OnGetAllCookiesOnUIThread, this)); - } - - void OnGetAllCookiesOnUIThread( - const net::CookieList& cookies, - const net::CookieStatusList& excluded_cookies) { + void OnGotAllCookies(base::OnceClosure callback, + const net::CookieList& cookies) { cookie_list_ = cookies; - base::PostTaskWithTraits( - FROM_HERE, {content::BrowserThread::UI}, - base::BindOnce(&CookieReader::OnCookiesReadyOnUIThread, this)); + std::move(callback).Run(); } - void OnCookiesReadyOnUIThread() { run_loop_->Quit(); } - - scoped_refptr<net::URLRequestContextGetter> context_; net::CookieList cookie_list_; - std::unique_ptr<base::RunLoop> run_loop_; DISALLOW_COPY_AND_ASSIGN(CookieReader); }; @@ -547,10 +533,10 @@ EXPECT_EQ(GetOAuthStatusFromLocalState(account_id), user_manager::User::OAUTH2_TOKEN_STATUS_VALID); - scoped_refptr<CookieReader> cookie_reader(new CookieReader()); - cookie_reader->ReadCookies(GetProfile()); - EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSessionSIDCookie); - EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSessionLSIDCookie); + CookieReader cookie_reader; + cookie_reader.ReadCookies(GetProfile()); + EXPECT_EQ(cookie_reader.GetCookieValue("SID"), kTestSessionSIDCookie); + EXPECT_EQ(cookie_reader.GetCookieValue("LSID"), kTestSessionLSIDCookie); } // MergeSession test is running merge session process for an existing profile @@ -561,35 +547,33 @@ SetupGaiaServerForUnexpiredAccount(); SimulateNetworkOnline(); LoginAsExistingUser(); - scoped_refptr<CookieReader> cookie_reader(new CookieReader()); - cookie_reader->ReadCookies(GetProfile()); + CookieReader cookie_reader; + cookie_reader.ReadCookies(GetProfile()); // These are still cookie values from the initial session since // /ListAccounts - EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSessionSIDCookie); - EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSessionLSIDCookie); + EXPECT_EQ(cookie_reader.GetCookieValue("SID"), kTestSessionSIDCookie); + EXPECT_EQ(cookie_reader.GetCookieValue("LSID"), kTestSessionLSIDCookie); } // MergeSession test is running merge session process for an existing profile // that was generated in PRE_PRE_MergeSession test. -// Disabled due to flakiness: crbug.com/496832 -IN_PROC_BROWSER_TEST_F(OAuth2Test, DISABLED_PRE_MergeSession) { +IN_PROC_BROWSER_TEST_F(OAuth2Test, PRE_MergeSession) { SetupGaiaServerForExpiredAccount(); SimulateNetworkOnline(); LoginAsExistingUser(); - scoped_refptr<CookieReader> cookie_reader(new CookieReader()); - cookie_reader->ReadCookies(GetProfile()); + CookieReader cookie_reader; + cookie_reader.ReadCookies(GetProfile()); // These should be cookie values that we generated by calling /MergeSession, // since /ListAccounts should have tell us that the initial session cookies // are stale. - EXPECT_EQ(cookie_reader->GetCookieValue("SID"), kTestSession2SIDCookie); - EXPECT_EQ(cookie_reader->GetCookieValue("LSID"), kTestSession2LSIDCookie); + EXPECT_EQ(cookie_reader.GetCookieValue("SID"), kTestSession2SIDCookie); + EXPECT_EQ(cookie_reader.GetCookieValue("LSID"), kTestSession2LSIDCookie); } // MergeSession test is attempting to merge session for an existing profile // that was generated in PRE_PRE_MergeSession test. This attempt should fail // since FakeGaia instance isn't configured to return relevant tokens/cookies. -// Disabled due to flakiness: crbug.com/496832 -IN_PROC_BROWSER_TEST_F(OAuth2Test, DISABLED_MergeSession) { +IN_PROC_BROWSER_TEST_F(OAuth2Test, MergeSession) { SimulateNetworkOnline(); content::WindowedNotificationObserver( @@ -600,7 +584,9 @@ test::OobeJS().ExpectTrue("!!document.querySelector('#account-picker')"); test::OobeJS().ExpectTrue("!!document.querySelector('#pod-row')"); - std::string account_id = PickAccountId(GetProfile(), kTestGaiaId, kTestEmail); + // PickAccountId does not work at this point as the primary user profile has + // not yet been created. + const std::string account_id = kTestEmail; EXPECT_EQ(GetOAuthStatusFromLocalState(account_id), user_manager::User::OAUTH2_TOKEN_STATUS_VALID); @@ -608,6 +594,8 @@ TryToLogin(AccountId::FromUserEmailGaiaId(kTestEmail, kTestGaiaId), kTestAccountPassword)); + ASSERT_EQ(account_id, PickAccountId(GetProfile(), kTestGaiaId, kTestEmail)); + // Wait for the session merge to finish. WaitForMergeSessionCompletion(OAuth2LoginManager::SESSION_RESTORE_FAILED);
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc index 31f17e1..134026c 100644 --- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc +++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -243,7 +243,7 @@ tpm_auto_update_mode_policy_handler_ = std::make_unique<TPMAutoUpdateModePolicyHandler>( - chromeos::CrosSettings::Get()); + chromeos::CrosSettings::Get(), local_state); } void BrowserPolicyConnectorChromeOS::PreShutdown() {
diff --git a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.cc b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.cc index ee7af931..29c3b640 100644 --- a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.cc +++ b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.cc
@@ -7,13 +7,20 @@ #include <utility> #include "base/bind.h" +#include "base/time/time.h" +#include "base/timer/timer.h" #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/tpm_firmware_update.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/pref_names.h" #include "chromeos/dbus/session_manager/session_manager_client.h" #include "chromeos/settings/cros_settings_names.h" #include "chromeos/settings/cros_settings_provider.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" +#include "components/user_manager/user_manager.h" namespace { @@ -21,6 +28,9 @@ const base::TimeDelta kFirmwareAvailabilityCheckerTimeout = base::TimeDelta::FromSeconds(20); +const base::TimeDelta kTPMUpdatePlannedNotificationWaitTime = + base::TimeDelta::FromDays(1); + // Reads the value of the the device setting key // TPMFirmwareUpdateSettings.AutoUpdateMode from a trusted store. If the value // is temporarily untrusted |callback| will be invoked later when trusted values @@ -71,8 +81,12 @@ namespace policy { TPMAutoUpdateModePolicyHandler::TPMAutoUpdateModePolicyHandler( - chromeos::CrosSettings* cros_settings) - : cros_settings_(cros_settings), weak_factory_(this) { + chromeos::CrosSettings* cros_settings, + PrefService* local_state) + : cros_settings_(cros_settings), + local_state_(local_state), + weak_factory_(this) { + DCHECK(local_state_); policy_subscription_ = cros_settings_->AddSettingsObserver( chromeos::kTPMFirmwareUpdateSettings, base::BindRepeating(&TPMAutoUpdateModePolicyHandler::OnPolicyChanged, @@ -81,6 +95,12 @@ update_checker_callback_ = base::BindRepeating(&TPMAutoUpdateModePolicyHandler::CheckForUpdate, weak_factory_.GetWeakPtr()); + + show_notfication_callback_ = + base::BindRepeating(&chromeos::ShowAutoUpdateNotification); + + notification_timer_ = std::make_unique<base::OneShotTimer>(); + // Fire it once so we're sure we get an invocation on startup. OnPolicyChanged(); } @@ -95,11 +115,20 @@ if (auto_update_mode == AutoUpdateMode::kNever || auto_update_mode == AutoUpdateMode::kEnrollment) { + if (notification_timer_->IsRunning()) + notification_timer_->Stop(); return; } - if (auto_update_mode == AutoUpdateMode::kWithoutAcknowledgment) - update_checker_callback_.Run(base::BindOnce(&OnUpdateAvailableCheckResult)); + if (auto_update_mode == AutoUpdateMode::kUserAcknowledgment) { + if (!WasTPMUpdateOnNextRebootNotificationShown()) { + update_checker_callback_.Run(base::BindOnce( + &TPMAutoUpdateModePolicyHandler::ShowTPMAutoUpdateNotification, + weak_factory_.GetWeakPtr())); + return; + } + } + update_checker_callback_.Run(base::BindOnce(&OnUpdateAvailableCheckResult)); } void TPMAutoUpdateModePolicyHandler::CheckForUpdate( @@ -123,6 +152,11 @@ update_checker_callback_ = callback; } +void TPMAutoUpdateModePolicyHandler::SetShowNotificationCallbackForTesting( + const ShowNotificationCallback& callback) { + show_notfication_callback_ = callback; +} + void TPMAutoUpdateModePolicyHandler::UpdateOnEnrollmentIfNeeded() { AutoUpdateMode auto_update_mode = GetTPMAutoUpdateModeSetting( cros_settings_, @@ -140,4 +174,98 @@ } } +void TPMAutoUpdateModePolicyHandler::ShowTPMAutoUpdateNotificationIfNeeded() { + AutoUpdateMode auto_update_mode = GetTPMAutoUpdateModeSetting( + cros_settings_, + base::BindRepeating(&TPMAutoUpdateModePolicyHandler::OnPolicyChanged, + weak_factory_.GetWeakPtr())); + + if (auto_update_mode != AutoUpdateMode::kUserAcknowledgment) + return; + + update_checker_callback_.Run(base::BindOnce( + &TPMAutoUpdateModePolicyHandler::ShowTPMAutoUpdateNotification, + weak_factory_.GetWeakPtr())); +} + +void TPMAutoUpdateModePolicyHandler::ShowTPMAutoUpdateNotification( + bool update_available) { + if (!update_available) + return; + + if (!user_manager::UserManager::IsInitialized()) + return; + + const user_manager::UserManager* user_manager = + user_manager::UserManager::Get(); + if (!user_manager->IsUserLoggedIn() || user_manager->IsLoggedInAsKioskApp()) + return; + + Profile* profile = ProfileManager::GetActiveUserProfile(); + if (!profile) + return; + + base::Time notification_shown = + local_state_->GetTime(prefs::kTPMUpdatePlannedNotificationShownTime); + + if (notification_shown == base::Time::Min()) { + notification_shown = base::Time::Now(); + local_state_->SetTime(prefs::kTPMUpdatePlannedNotificationShownTime, + notification_shown); + show_notfication_callback_.Run( + chromeos::TpmAutoUpdateUserNotification::kPlanned, profile); + } + + // Show update on next reboot notification after + // |kTPMUpdatePlannedNotificationWaitTime|. + base::Time show_reboot_notification_time = + notification_shown + kTPMUpdatePlannedNotificationWaitTime; + + if (show_reboot_notification_time <= base::Time::Now()) { + if (notification_timer_->IsRunning()) + notification_timer_->Stop(); + ShowTPMUpdateOnNextRebootNotification(); + return; + } + + // Set a timer that will display the update on next reboot notification after + // 24 hours. + if (notification_timer_->IsRunning()) + return; + notification_timer_->Start( + FROM_HERE, show_reboot_notification_time - base::Time::Now(), this, + &TPMAutoUpdateModePolicyHandler::ShowTPMUpdateOnNextRebootNotification); +} + +bool TPMAutoUpdateModePolicyHandler:: + WasTPMUpdateOnNextRebootNotificationShown() { + return local_state_->GetBoolean( + prefs::kTPMUpdateOnNextRebootNotificationShown); +} + +// static +void TPMAutoUpdateModePolicyHandler::RegisterPrefs( + PrefRegistrySimple* registry) { + registry->RegisterTimePref(prefs::kTPMUpdatePlannedNotificationShownTime, + base::Time::Min()); + registry->RegisterBooleanPref(prefs::kTPMUpdateOnNextRebootNotificationShown, + false); +} + +void TPMAutoUpdateModePolicyHandler::ShowTPMUpdateOnNextRebootNotification() { + Profile* profile = ProfileManager::GetActiveUserProfile(); + if (!profile) + return; + local_state_->SetBoolean(prefs::kTPMUpdateOnNextRebootNotificationShown, + true); + + show_notfication_callback_.Run( + chromeos::TpmAutoUpdateUserNotification::kOnNextReboot, profile); +} + +void TPMAutoUpdateModePolicyHandler::SetNotificationTimerForTesting( + std::unique_ptr<base::OneShotTimer> timer) { + notification_timer_ = std::move(timer); +} + } // namespace policy
diff --git a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h index 467625ea..e53921e5 100644 --- a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h +++ b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h
@@ -11,6 +11,15 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "chrome/browser/chromeos/settings/cros_settings.h" +#include "chrome/browser/chromeos/ui/tpm_auto_update_notification.h" + +class PrefRegistrySimple; +class PrefService; +class Profile; + +namespace base { +class OneShotTimer; +} namespace policy { @@ -38,34 +47,70 @@ using UpdateCheckerCallback = base::RepeatingCallback<void(base::OnceCallback<void(bool)> callback)>; - explicit TPMAutoUpdateModePolicyHandler( - chromeos::CrosSettings* cros_settings); + // Will be invoked by TPMAutoUpdateModePolicyHandler to display a notification + // informing the user that a TPM update which will clear user data is planned + // in 24 hours or at next reboot, depending on |notification_type|. + using ShowNotificationCallback = base::RepeatingCallback<void( + chromeos::TpmAutoUpdateUserNotification notification_type, + Profile* profile)>; + + TPMAutoUpdateModePolicyHandler(chromeos::CrosSettings* cros_settings, + PrefService* local_state); ~TPMAutoUpdateModePolicyHandler(); // Sets a UpdateCheckerCallback for testing. void SetUpdateCheckerCallbackForTesting( const UpdateCheckerCallback& callback); + void SetShowNotificationCallbackForTesting( + const ShowNotificationCallback& callback); + + void SetNotificationTimerForTesting( + std::unique_ptr<base::OneShotTimer> timer); + // Updates the TPM firmware if the device is set to update at enrollment via // device policy option TPMFirmwareUpdateSettings.AutoUpdateMode. If the TPM // firmware is not vulnerable the method will return without updating. void UpdateOnEnrollmentIfNeeded(); + // Shows notifications informing the user about a planned auto-update that + // will clear user data. Notifications are shown only if the TPM firmware + // needs to be updated and the device policy + // TPMFirmwareUpdateSettings.AutoUpdateMode is set to |UserAcknowledgment|. + void ShowTPMAutoUpdateNotificationIfNeeded(); + + static void RegisterPrefs(PrefRegistrySimple* registry); + private: void OnPolicyChanged(); + // Called by the TPM firmware update availability checker via + // |UpdateCheckerCallback|. Shows TPM auto-update notifications if + // |update_available| is true. + void ShowTPMAutoUpdateNotification(bool update_available); + static void OnUpdateAvailableCheckResult(bool update_available); // Check if a TPM firmware update is available. void CheckForUpdate(base::OnceCallback<void(bool)> callback); + bool WasTPMUpdateOnNextRebootNotificationShown(); + + void ShowTPMUpdateOnNextRebootNotification(); + chromeos::CrosSettings* cros_settings_; + PrefService* local_state_; + + std::unique_ptr<base::OneShotTimer> notification_timer_; + std::unique_ptr<chromeos::CrosSettings::ObserverSubscription> policy_subscription_; UpdateCheckerCallback update_checker_callback_; + ShowNotificationCallback show_notfication_callback_; + base::WeakPtrFactory<TPMAutoUpdateModePolicyHandler> weak_factory_; DISALLOW_COPY_AND_ASSIGN(TPMAutoUpdateModePolicyHandler);
diff --git a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler_unittest.cc b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler_unittest.cc index 55a47e8..5320ced 100644 --- a/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler_unittest.cc +++ b/chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler_unittest.cc
@@ -9,21 +9,43 @@ #include "base/bind.h" #include "base/bind_helpers.h" #include "base/run_loop.h" +#include "base/timer/mock_timer.h" +#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" #include "chrome/browser/chromeos/settings/scoped_testing_cros_settings.h" #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h" #include "chrome/browser/chromeos/tpm_firmware_update.h" +#include "chrome/browser/prefs/browser_prefs.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/testing_browser_process.h" +#include "chrome/test/base/testing_profile.h" +#include "chrome/test/base/testing_profile_manager.h" #include "chromeos/dbus/dbus_thread_manager.h" #include "chromeos/dbus/session_manager/fake_session_manager_client.h" #include "chromeos/settings/cros_settings_names.h" #include "chromeos/tpm/stub_install_attributes.h" +#include "components/account_id/account_id.h" +#include "components/prefs/pref_service.h" +#include "components/prefs/testing_pref_service.h" +#include "components/user_manager/fake_user_manager.h" +#include "components/user_manager/scoped_user_manager.h" #include "content/public/test/test_browser_thread_bundle.h" #include "testing/gtest/include/gtest/gtest.h" +namespace { +constexpr char kFakeUserName[] = "test@example.com"; +constexpr char kFakeGaiaId[] = "1234567890"; +} // namespace + namespace policy { class TPMAutoUpdateModePolicyHandlerTest : public testing::Test { public: - TPMAutoUpdateModePolicyHandlerTest() { + TPMAutoUpdateModePolicyHandlerTest() + : local_state_(TestingBrowserProcess::GetGlobal()), + user_manager_(new chromeos::FakeChromeUserManager()), + user_manager_enabler_(base::WrapUnique(user_manager_)), + profile_manager_(TestingBrowserProcess::GetGlobal(), &local_state_) { + CHECK(profile_manager_.SetUp()); chromeos::SessionManagerClient::InitializeFakeInMemory(); } @@ -44,10 +66,23 @@ std::move(callback).Run(update_available_); } + void ShowNotification( + chromeos::TpmAutoUpdateUserNotification notification_type, + Profile* profile) { + last_shown_notification_ = notification_type; + } + protected: bool update_available_ = false; + chromeos::TpmAutoUpdateUserNotification last_shown_notification_ = + chromeos::TpmAutoUpdateUserNotification::kNone; content::TestBrowserThreadBundle thread_bundle_; + ScopedTestingLocalState local_state_; + chromeos::FakeChromeUserManager* user_manager_; + user_manager::ScopedUserManager user_manager_enabler_; + TestingProfileManager profile_manager_; + // Set up fake install attributes to pretend the machine is enrolled. chromeos::ScopedStubInstallAttributes test_install_attributes_{ chromeos::StubInstallAttributes::CreateCloudManaged("example.com", @@ -61,7 +96,7 @@ // policy option TPMFirmwareUpdateSettings.AutoUpdateMode. TEST_F(TPMAutoUpdateModePolicyHandlerTest, PolicyUpdatesTriggered) { TPMAutoUpdateModePolicyHandler tpm_update_policy_handler( - chromeos::CrosSettings::Get()); + chromeos::CrosSettings::Get(), local_state_.Get()); tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting( base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate, weak_factory_.GetWeakPtr())); @@ -99,7 +134,7 @@ // state preserving update is not available. TEST_F(TPMAutoUpdateModePolicyHandlerTest, NoUpdatesAvailable) { TPMAutoUpdateModePolicyHandler tpm_update_policy_handler( - chromeos::CrosSettings::Get()); + chromeos::CrosSettings::Get(), local_state_.Get()); tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting( base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate, weak_factory_.GetWeakPtr())); @@ -112,4 +147,141 @@ ->start_tpm_firmware_update_call_count()); } +// Verify that the notification informing the user that an update is planned +// after 24 hours is shown. +TEST_F(TPMAutoUpdateModePolicyHandlerTest, ShowPlannedUpdateNotification) { + TPMAutoUpdateModePolicyHandler tpm_update_policy_handler( + chromeos::CrosSettings::Get(), local_state_.Get()); + tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting( + base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate, + weak_factory_.GetWeakPtr())); + tpm_update_policy_handler.SetShowNotificationCallbackForTesting( + base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::ShowNotification, + base::Unretained(this))); + + const AccountId account_id( + AccountId::FromUserEmailGaiaId(kFakeUserName, kFakeGaiaId)); + user_manager_->AddUser(account_id); + user_manager_->LoginUser(account_id); + + update_available_ = true; + + EXPECT_EQ(last_shown_notification_, + chromeos::TpmAutoUpdateUserNotification::kNone); + + SetAutoUpdateMode(AutoUpdateMode::kUserAcknowledgment); + base::RunLoop().RunUntilIdle(); + + // TPM update is not triggered. + EXPECT_EQ(0, chromeos::FakeSessionManagerClient::Get() + ->start_tpm_firmware_update_call_count()); + + EXPECT_EQ(last_shown_notification_, + chromeos::TpmAutoUpdateUserNotification::kPlanned); +} + +// Verify that the notification informing the user that an update will happen at +// the next reboot is shown. +TEST_F(TPMAutoUpdateModePolicyHandlerTest, + ShowUpdateOnRebootNotificationNoTimer) { + TPMAutoUpdateModePolicyHandler tpm_update_policy_handler( + chromeos::CrosSettings::Get(), local_state_.Get()); + tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting( + base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate, + weak_factory_.GetWeakPtr())); + tpm_update_policy_handler.SetShowNotificationCallbackForTesting( + base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::ShowNotification, + base::Unretained(this))); + + const AccountId account_id( + AccountId::FromUserEmailGaiaId(kFakeUserName, kFakeGaiaId)); + user_manager_->AddUser(account_id); + user_manager_->LoginUser(account_id); + + update_available_ = true; + + // First notification was shwed more than 24 hours ago. + base::Time yesterday = base::Time::Now() - base::TimeDelta::FromHours(25); + local_state_.Get()->SetInt64( + prefs::kTPMUpdatePlannedNotificationShownTime, + yesterday.ToDeltaSinceWindowsEpoch().InSeconds()); + + SetAutoUpdateMode(AutoUpdateMode::kUserAcknowledgment); + base::RunLoop().RunUntilIdle(); + + // TPM update is not triggered. + EXPECT_EQ(0, chromeos::FakeSessionManagerClient::Get() + ->start_tpm_firmware_update_call_count()); + + // Show planned update notification. + EXPECT_EQ(last_shown_notification_, + chromeos::TpmAutoUpdateUserNotification::kOnNextReboot); +} + +// Verify that the notification informing the user that an update will happen at +// the next reboot is triggered by the timer. +TEST_F(TPMAutoUpdateModePolicyHandlerTest, + ShowUpdateOnRebootNotificationTimer) { + TPMAutoUpdateModePolicyHandler tpm_update_policy_handler( + chromeos::CrosSettings::Get(), local_state_.Get()); + tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting( + base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate, + weak_factory_.GetWeakPtr())); + tpm_update_policy_handler.SetShowNotificationCallbackForTesting( + base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::ShowNotification, + base::Unretained(this))); + + auto mock_timer = std::make_unique<base::MockOneShotTimer>(); + auto* mock_timer_ptr = mock_timer.get(); + + tpm_update_policy_handler.SetNotificationTimerForTesting( + std::move(mock_timer)); + + const AccountId account_id( + AccountId::FromUserEmailGaiaId(kFakeUserName, kFakeGaiaId)); + user_manager_->AddUser(account_id); + user_manager_->LoginUser(account_id); + + update_available_ = true; + + SetAutoUpdateMode(AutoUpdateMode::kUserAcknowledgment); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(0, chromeos::FakeSessionManagerClient::Get() + ->start_tpm_firmware_update_call_count()); + + // Show planned update notification. + EXPECT_EQ(last_shown_notification_, + chromeos::TpmAutoUpdateUserNotification::kPlanned); + + mock_timer_ptr->Fire(); + + // Show update at reboot notification. + EXPECT_EQ(last_shown_notification_, + chromeos::TpmAutoUpdateUserNotification::kOnNextReboot); +} + +// TPM update with user acknowlegment triggered. +TEST_F(TPMAutoUpdateModePolicyHandlerTest, UpdateWithUserAcknowlegment) { + TPMAutoUpdateModePolicyHandler tpm_update_policy_handler( + chromeos::CrosSettings::Get(), local_state_.Get()); + tpm_update_policy_handler.SetUpdateCheckerCallbackForTesting( + base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::CheckForUpdate, + weak_factory_.GetWeakPtr())); + tpm_update_policy_handler.SetShowNotificationCallbackForTesting( + base::BindRepeating(&TPMAutoUpdateModePolicyHandlerTest::ShowNotification, + base::Unretained(this))); + + update_available_ = true; + + // Update at next reboot notification already shown. + local_state_.Get()->SetBoolean(prefs::kTPMUpdateOnNextRebootNotificationShown, + true); + SetAutoUpdateMode(AutoUpdateMode::kUserAcknowledgment); + base::RunLoop().RunUntilIdle(); + + // Update is triggered. + EXPECT_EQ(1, chromeos::FakeSessionManagerClient::Get() + ->start_tpm_firmware_update_call_count()); +} + } // namespace policy
diff --git a/chrome/browser/chromeos/ui/tpm_auto_update_notification.cc b/chrome/browser/chromeos/ui/tpm_auto_update_notification.cc new file mode 100644 index 0000000..8aa1cca --- /dev/null +++ b/chrome/browser/chromeos/ui/tpm_auto_update_notification.cc
@@ -0,0 +1,69 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/ui/tpm_auto_update_notification.h" + +#include "ash/public/cpp/notification_utils.h" +#include "base/bind.h" +#include "base/strings/string16.h" +#include "chrome/browser/notifications/notification_display_service.h" +#include "chrome/browser/notifications/notification_display_service_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/pref_names.h" +#include "chrome/grit/generated_resources.h" +#include "components/prefs/pref_service.h" +#include "components/vector_icons/vector_icons.h" +#include "ui/base/l10n/l10n_util.h" + +namespace chromeos { + +constexpr char kTPMPlannedAutoUpdateNotificationId[] = + "chrome://tpm_planned_firmware_auto_update"; +constexpr char kTPMAutoUpdateOnRebootNotificationId[] = + "chrome://tpm_firmware_auto_update_on_reboot"; + +void ShowAutoUpdateNotification(TpmAutoUpdateUserNotification notification_type, + Profile* profile) { + base::string16 title, text; + std::string notification_id; + bool pinned = false; + + switch (notification_type) { + case TpmAutoUpdateUserNotification::kPlanned: + title = l10n_util::GetStringUTF16( + IDS_TPM_AUTO_UPDATE_PLANNED_NOTIFICATION_TITLE); + text = l10n_util::GetStringUTF16( + IDS_TPM_AUTO_UPDATE_PLANNED_NOTIFICATION_MESSAGE); + notification_id = kTPMPlannedAutoUpdateNotificationId; + break; + case TpmAutoUpdateUserNotification::kOnNextReboot: + title = l10n_util::GetStringUTF16( + IDS_TPM_AUTO_UPDATE_REBOOT_NOTIFICATION_TITLE); + text = l10n_util::GetStringUTF16( + IDS_TPM_AUTO_UPDATE_REBOOT_NOTIFICATION_MESSAGE); + notification_id = kTPMAutoUpdateOnRebootNotificationId; + pinned = true; + break; + default: + return; + } + + std::unique_ptr<message_center::Notification> notification = + ash::CreateSystemNotification( + message_center::NOTIFICATION_TYPE_SIMPLE, notification_id, title, + text, base::string16() /*display_source*/, GURL(), + message_center::NotifierId( + message_center::NotifierType::SYSTEM_COMPONENT, notification_id), + message_center::RichNotificationData(), + new message_center::NotificationDelegate(), + vector_icons::kBusinessIcon, + message_center::SystemNotificationWarningLevel::NORMAL); + notification->set_priority(message_center::SYSTEM_PRIORITY); + notification->set_pinned(pinned); + + NotificationDisplayServiceFactory::GetForProfile(profile)->Display( + NotificationHandler::Type::TRANSIENT, *notification, + nullptr /*metadata*/); +} +} // namespace chromeos
diff --git a/chrome/browser/chromeos/ui/tpm_auto_update_notification.h b/chrome/browser/chromeos/ui/tpm_auto_update_notification.h new file mode 100644 index 0000000..9d271bb --- /dev/null +++ b/chrome/browser/chromeos/ui/tpm_auto_update_notification.h
@@ -0,0 +1,31 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CHROMEOS_UI_TPM_AUTO_UPDATE_NOTIFICATION_H_ +#define CHROME_BROWSER_CHROMEOS_UI_TPM_AUTO_UPDATE_NOTIFICATION_H_ + +class Profile; + +namespace chromeos { + +// For the TPM firmware auto-update flow with user acknowledgment users will be +// shown two notifications, one informing that an auto-update will be performed +// at the first reboot after 24 hours and one displayed after at least 24 hours +// informing that an update will happen at the next reboot. +enum class TpmAutoUpdateUserNotification { + kNone = 0, + // Corresponds to the notification informing the user that an update that will + // clear user data will be performed at the first reboot after 24 hours. + kPlanned = 1, + // Corresponds to the notification informing the user that an update that will + // clear user data will be performed after the next reboot. + kOnNextReboot = 2 +}; + +void ShowAutoUpdateNotification(TpmAutoUpdateUserNotification notification_type, + Profile* profile); + +} // namespace chromeos + +#endif // CHROME_BROWSER_CHROMEOS_UI_TPM_AUTO_UPDATE_NOTIFICATION_H_
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 83195747..a36cd56 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -168,11 +168,6 @@ "expiry_milestone": 75 }, { - "name": "ash-shelf-color-scheme", - "owners": [ "manucornet" ], - "expiry_milestone": 76 - }, - { "name": "auto-fetch-on-net-error-page", "owners": [ "harringtond", "offline-dev" ], "expiry_milestone": 82
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 4669071b..0a291df 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -3005,17 +3005,6 @@ "Enable unified desktop mode which allows a window to span multiple " "displays."; -const char kAshShelfColorScheme[] = "Shelf color scheme in Chrome OS System UI"; -const char kAshShelfColorSchemeDescription[] = - "Specify how the color is derived from the wallpaper. This flag is only " - "used when the --ash-shelf-color flag is enabled. Defaults to Dark & Muted"; -const char kAshShelfColorSchemeLightVibrant[] = "Light & Vibrant"; -const char kAshShelfColorSchemeNormalVibrant[] = "Normal & Vibrant"; -const char kAshShelfColorSchemeDarkVibrant[] = "Dark & Vibrant"; -const char kAshShelfColorSchemeLightMuted[] = "Light & Muted"; -const char kAshShelfColorSchemeNormalMuted[] = "Normal & Muted"; -const char kAshShelfColorSchemeDarkMuted[] = "Dark & Muted"; - const char kBulkPrintersName[] = "Bulk Printers Policy"; const char kBulkPrintersDescription[] = "Enables the new bulk printers policy";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 38d717f..662fd77d 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1806,18 +1806,6 @@ extern const char kAshEnableUnifiedDesktopName[]; extern const char kAshEnableUnifiedDesktopDescription[]; -extern const char kAshShelfColorName[]; -extern const char kAshShelfColorDescription[]; - -extern const char kAshShelfColorScheme[]; -extern const char kAshShelfColorSchemeDescription[]; -extern const char kAshShelfColorSchemeLightVibrant[]; -extern const char kAshShelfColorSchemeNormalVibrant[]; -extern const char kAshShelfColorSchemeDarkVibrant[]; -extern const char kAshShelfColorSchemeLightMuted[]; -extern const char kAshShelfColorSchemeNormalMuted[]; -extern const char kAshShelfColorSchemeDarkMuted[]; - extern const char kBulkPrintersName[]; extern const char kBulkPrintersDescription[];
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index 75917ffe..cbaf6a0c 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -740,6 +740,9 @@ { key::kDeviceBootOnAcEnabled, ash::prefs::kDeviceBootOnAcEnabled, base::Value::Type::BOOLEAN }, + { key::kSamlInSessionPasswordChangeEnabled, + prefs::kSamlInSessionPasswordChangeEnabled, + base::Value::Type::BOOLEAN }, #endif // defined(OS_CHROMEOS) // Metrics reporting is controlled by a platform specific policy for ChromeOS
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index b2d101462..8169d37c 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/accessibility/invert_bubble_prefs.h" #include "chrome/browser/browser_process_impl.h" #include "chrome/browser/chrome_content_browser_client.h" +#include "chrome/browser/chromeos/policy/tpm_auto_update_mode_policy_handler.h" #include "chrome/browser/chromeos/scheduler_configuration_manager.h" #include "chrome/browser/component_updater/component_updater_prefs.h" #include "chrome/browser/custom_handlers/protocol_handler_registry.h" @@ -583,6 +584,7 @@ policy::DeviceWallpaperImageHandler::RegisterPrefs(registry); policy::DMTokenStorage::RegisterPrefs(registry); policy::PolicyCertServiceFactory::RegisterPrefs(registry); + policy::TPMAutoUpdateModePolicyHandler::RegisterPrefs(registry); quirks::QuirksManager::RegisterPrefs(registry); #endif
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index d6143f9e..83d3ee6 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -65,6 +65,7 @@ #include "chrome/browser/search_engines/template_url_fetcher_factory.h" #include "chrome/browser/search_engines/template_url_service_factory.h" #include "chrome/browser/send_tab_to_self/send_tab_to_self_client_service_factory.h" +#include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h" #include "chrome/browser/sessions/session_service_factory.h" #include "chrome/browser/sessions/tab_restore_service_factory.h" #include "chrome/browser/signin/about_signin_internals_factory.h" @@ -377,7 +378,9 @@ #if defined(OS_ANDROID) SearchPermissionsService::Factory::GetInstance(); #endif - send_tab_to_self::SendTabToSelfClientServiceFactory::GetInstance(); + if (send_tab_to_self::IsReceivingEnabled()) { + send_tab_to_self::SendTabToSelfClientServiceFactory::GetInstance(); + } #if BUILDFLAG(ENABLE_SESSION_SERVICE) SessionServiceFactory::GetInstance(); #endif
diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc index 70a64a5..7caa218 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.cc +++ b/chrome/browser/profiles/off_the_record_profile_impl.cc
@@ -224,14 +224,13 @@ GetDefaultStoragePartition(this)->GetNetworkContext()->ClearHostCache( nullptr, network::mojom::NetworkContext::ClearHostCacheCallback()); - BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices( - this); - // The SimpleDependencyManager should always be called after the + // The SimpleDependencyManager should always be passed after the // BrowserContextDependencyManager. This is because the KeyedService instances // in the BrowserContextDependencyManager's dependency graph can depend on the // ones in the SimpleDependencyManager's graph. - SimpleDependencyManager::GetInstance()->DestroyKeyedServices( - GetSimpleFactoryKey()); + DependencyManager::PerformInterlockedTwoPhaseShutdown( + BrowserContextDependencyManager::GetInstance(), this, + SimpleDependencyManager::GetInstance(), GetSimpleFactoryKey()); #if BUILDFLAG(ENABLE_EXTENSIONS) base::PostTaskWithTraits(
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index 6ee37bc..8ff2f79 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc
@@ -799,14 +799,13 @@ FullBrowserTransitionManager::Get()->OnProfileDestroyed(this); - BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices( - this); - // The SimpleDependencyManager should always be called after the + // The SimpleDependencyManager should always be passed after the // BrowserContextDependencyManager. This is because the KeyedService instances // in the BrowserContextDependencyManager's dependency graph can depend on the // ones in the SimpleDependencyManager's graph. - SimpleDependencyManager::GetInstance()->DestroyKeyedServices( - GetSimpleFactoryKey()); + DependencyManager::PerformInterlockedTwoPhaseShutdown( + BrowserContextDependencyManager::GetInstance(), this, + SimpleDependencyManager::GetInstance(), GetSimpleFactoryKey()); // This causes the Preferences file to be written to disk. if (prefs_loaded)
diff --git a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc index 5c31a1a..b80baec1 100644 --- a/chrome/browser/resource_coordinator/tab_manager_browsertest.cc +++ b/chrome/browser/resource_coordinator/tab_manager_browsertest.cc
@@ -1562,7 +1562,13 @@ EXPECT_TRUE(IsTabDiscarded(browser4->tab_strip_model()->GetWebContentsAt(1))); } -IN_PROC_BROWSER_TEST_F(TabManagerTest, UnfreezeTabOnNavigationEvent) { +#if defined(OS_WIN) +// Flaky: https://crbug.com/918701 +#define MAYBE_UnfreezeTabOnNavigationEvent DISABLED_UnfreezeTabOnNavigationEvent +#else +#define MAYBE_UnfreezeTabOnNavigationEvent UnfreezeTabOnNavigationEvent +#endif +IN_PROC_BROWSER_TEST_F(TabManagerTest, MAYBE_UnfreezeTabOnNavigationEvent) { TestTransitionFromActiveToPendingFreeze(); browser()->tab_strip_model()->GetWebContentsAt(1)->GetController().Reload(
diff --git a/chrome/browser/resources/about_sys/about_sys.css b/chrome/browser/resources/about_sys/about_sys.css index 8b626b540..6048d803 100644 --- a/chrome/browser/resources/about_sys/about_sys.css +++ b/chrome/browser/resources/about_sys/about_sys.css
@@ -132,16 +132,11 @@ .number-expanded, .number-collapsed { - text-align: left; + text-align: start; text-overflow: ellipsis; width: 80%; } -html[dir='rtl'] .number-expanded, -html[dir='rtl'] .number-collapsed { - text-align: right; -} - tr > *:nth-child(1), tr > *:nth-child(2) { border-inline-end: 1px solid rgb(181, 198, 222); @@ -171,7 +166,7 @@ } .spinner { - -webkit-animation: rotate 2s linear infinite; + animation: rotate 2s linear infinite; border: 4px solid rgb(239, 243, 255); border-radius: 50%; border-top: 4px solid rgb(82, 150, 222); @@ -179,7 +174,7 @@ width: 20px; } -@-webkit-keyframes rotate { +@keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
diff --git a/chrome/browser/resources/about_sys/about_sys.html b/chrome/browser/resources/about_sys/about_sys.html index d9cfd51..2c364771 100644 --- a/chrome/browser/resources/about_sys/about_sys.html +++ b/chrome/browser/resources/about_sys/about_sys.html
@@ -4,12 +4,11 @@ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>$i18n{title}</title> <link rel="stylesheet" href="chrome://resources/css/text_defaults.css"> - <link rel="stylesheet" href="chrome://system/about_sys.css"> + <link rel="stylesheet" href="about_sys.css"> <script src="chrome://resources/js/util.js"></script> - <script src="chrome://resources/js/jstemplate_compiled.js"></script> <script src="chrome://resources/js/load_time_data.js"></script> - <script src="chrome://system/about_sys.js"></script> - <script src="chrome://system/strings.js"></script> + <script src="about_sys.js"></script> + <script src="strings.js"></script> </head> <body> <div id="header">
diff --git a/chrome/browser/resources/about_sys/about_sys.js b/chrome/browser/resources/about_sys/about_sys.js index 097abdb..ec28d40 100644 --- a/chrome/browser/resources/about_sys/about_sys.js +++ b/chrome/browser/resources/about_sys/about_sys.js
@@ -174,7 +174,7 @@ updateLogEntries(systemInfo); const spinner = $('loadingIndicator'); spinner.style.display = 'none'; - spinner.style.webkitAnimationPlayState = 'paused'; + spinner.style.animationPlayState = 'paused'; } /**
diff --git a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js index ab4af53f1..2c84504 100644 --- a/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js +++ b/chrome/browser/resources/chromeos/arc_graphics_tracing/arc_graphics_tracing_ui.js
@@ -683,9 +683,9 @@ // Construct sub-model of active/idle events per each thread, active within // this interval. var eventsPerTid = {}; - for (var cpuId = 0; cpuId < overviewBand.model.cpu.events.length; cpuId++) { + for (var cpuId = 0; cpuId < overviewBand.model.system.cpu.length; cpuId++) { var activeEvents = new Events( - overviewBand.model.cpu.events[cpuId], 3 /* kActive */, + overviewBand.model.system.cpu[cpuId], 3 /* kActive */, 3 /* kActive */); var activeTid = 0; var index = activeEvents.getFirstAfter(minTimestamp); @@ -715,7 +715,7 @@ var totalTime = 0; for (var tid in eventsPerTid) { var thread = eventsPerTid[tid]; - var pid = overviewBand.model.cpu.threads[tid].pid; + var pid = overviewBand.model.system.threads[tid].pid; if (!(pid in threadsPerPid)) { pids.push(pid); threadsPerPid[pid] = {}; @@ -750,8 +750,8 @@ var pid = pids[i]; var threads = threadsPerPid[pid].threads; var processName; - if (pid in overviewBand.model.cpu.threads) { - processName = overviewBand.model.cpu.threads[pid].name; + if (pid in overviewBand.model.system.threads) { + processName = overviewBand.model.system.threads[pid].name; } else { processName = 'Others'; } @@ -773,7 +773,7 @@ var tid = threads[j].tid; bands.addBand( new Events(eventsPerTid[tid].events, 0, 1), cpuBandHeight, padding); - var threadName = overviewBand.model.cpu.threads[tid].name; + var threadName = overviewBand.model.system.threads[tid].name; var threadCpuUsage = 100.0 * threads[j].totalTime / duration; var threadInfo = threadName + ' ' + threadCpuUsage.toFixed(2) + '%'; SVG.addText( @@ -849,9 +849,9 @@ this.model = model; var bandHeight = 6; var padding = 2; - for (var cpuId = 0; cpuId < this.model.cpu.events.length; cpuId++) { + for (var cpuId = 0; cpuId < this.model.system.cpu.length; cpuId++) { this.addBand( - new Events(this.model.cpu.events[cpuId], 0, 1), bandHeight, padding); + new Events(this.model.system.cpu[cpuId], 0, 1), bandHeight, padding); } }
diff --git a/chrome/browser/resources/local_ntp/animations.css b/chrome/browser/resources/local_ntp/animations.css index cb2efa4..465d029a 100644 --- a/chrome/browser/resources/local_ntp/animations.css +++ b/chrome/browser/resources/local_ntp/animations.css
@@ -49,7 +49,8 @@ border-radius: 4px; font-size: 12px; font-weight: 500; - height: 32px; + line-height: 1.6; + min-height: 32px; padding: 0 16px; position: relative; transition-duration: 200ms;
diff --git a/chrome/browser/resources/local_ntp/custom_backgrounds.css b/chrome/browser/resources/local_ntp/custom_backgrounds.css index 57b25e42..bc03c5e 100644 --- a/chrome/browser/resources/local_ntp/custom_backgrounds.css +++ b/chrome/browser/resources/local_ntp/custom_backgrounds.css
@@ -581,9 +581,10 @@ color: #FFF; display: inline-block; font-size: 13px; - height: 32px; + line-height: 1.6; + min-height: 32px; overflow: hidden; - padding: 8px 16px 0 16px; + padding: 0 16px; position: absolute; text-overflow: ellipsis; user-select: none;
diff --git a/chrome/browser/resources/local_ntp/custom_links_edit.css b/chrome/browser/resources/local_ntp/custom_links_edit.css index d4c2cad..88fabe70 100644 --- a/chrome/browser/resources/local_ntp/custom_links_edit.css +++ b/chrome/browser/resources/local_ntp/custom_links_edit.css
@@ -75,8 +75,8 @@ caret-color: rgb(var(--GB600-rgb)); color: rgb(var(--GG900-rgb)); font-size: 13px; - height: 32px; - line-height: 24px; + line-height: 1.6; + min-height: 32px; outline: none; padding-inline-end: 8px; padding-inline-start: 8px;
diff --git a/chrome/browser/resources/settings/about_page/about_page.html b/chrome/browser/resources/settings/about_page/about_page.html index d0c98a66..2228620 100644 --- a/chrome/browser/resources/settings/about_page/about_page.html +++ b/chrome/browser/resources/settings/about_page/about_page.html
@@ -57,9 +57,10 @@ margin-inline-end: var(--about-page-image-space); } - iron-icon { + .icon-container { margin-inline-end: var(--about-page-image-space); min-width: 32px; /* The width of the product-logo img. */ + text-align: center; } iron-icon[icon='settings:check-circle'] { @@ -105,19 +106,21 @@ src URL --> <!-- Set the icon from the iconset (when it's obsolete/EOL and when update is done) or set the src (when it's updating). --> - <iron-icon - hidden="[[!shouldShowIcons_(showUpdateStatus_)]]" + <div class="icon-container" + hidden="[[!shouldShowIcons_(showUpdateStatus_)]]"> + <iron-icon <if expr="not chromeos"> - icon$="[[getUpdateStatusIcon_( - obsoleteSystemInfo_, currentUpdateStatusEvent_)]]" - src="[[getThrobberSrcIfUpdating_(obsoleteSystemInfo_, currentUpdateStatusEvent_)]]"> + icon$="[[getUpdateStatusIcon_( + obsoleteSystemInfo_, currentUpdateStatusEvent_)]]" + src="[[getThrobberSrcIfUpdating_(obsoleteSystemInfo_, currentUpdateStatusEvent_)]]"> </if> <if expr="chromeos"> - icon$="[[getUpdateStatusIcon_( - hasEndOfLife_, currentUpdateStatusEvent_)]]" - src="[[getThrobberSrcIfUpdating_(hasEndOfLife_, currentUpdateStatusEvent_)]]"> + icon$="[[getUpdateStatusIcon_( + hasEndOfLife_, currentUpdateStatusEvent_)]]" + src="[[getThrobberSrcIfUpdating_(hasEndOfLife_, currentUpdateStatusEvent_)]]"> </if> - </iron-icon> + </iron-icon> + </div> <div class="start padded"> <div id="updateStatusMessage" hidden="[[!showUpdateStatus_]]"> <div
diff --git a/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc b/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc index 7d7ba77f..e451244 100644 --- a/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc +++ b/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc
@@ -8,6 +8,7 @@ #include "base/memory/singleton.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h" #include "chrome/browser/sync/model_type_store_service_factory.h" #include "chrome/common/channel_info.h" #include "components/keyed_service/content/browser_context_dependency_manager.h" @@ -39,6 +40,8 @@ KeyedService* SendTabToSelfSyncServiceFactory::BuildServiceInstanceFor( content::BrowserContext* context) const { + DCHECK(send_tab_to_self::IsReceivingEnabled()); + Profile* profile = Profile::FromBrowserContext(context); syncer::OnceModelTypeStoreFactory store_factory =
diff --git a/chrome/browser/ui/accelerator_utils.h b/chrome/browser/ui/accelerator_utils.h index 3c274f7b..9c76d66 100644 --- a/chrome/browser/ui/accelerator_utils.h +++ b/chrome/browser/ui/accelerator_utils.h
@@ -15,8 +15,7 @@ // Returns true if the given |accelerator| is currently registered by // Chrome. -bool IsChromeAccelerator(const ui::Accelerator& accelerator, - Profile* profile); +bool IsChromeAccelerator(const ui::Accelerator& accelerator, Profile* profile); ui::Accelerator GetPrimaryChromeAcceleratorForBookmarkPage();
diff --git a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc index 12f080d..228ddd0 100644 --- a/chrome/browser/ui/autofill/autofill_popup_layout_model.cc +++ b/chrome/browser/ui/autofill/autofill_popup_layout_model.cc
@@ -19,6 +19,7 @@ #include "components/autofill/core/common/autofill_util.h" #include "components/grit/components_scaled_resources.h" #include "components/strings/grit/components_strings.h" +#include "components/vector_icons/vector_icons.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/base/resource/resource_bundle.h" #include "ui/gfx/color_palette.h" @@ -230,10 +231,12 @@ return gfx::CreateVectorIcon(omnibox::kHttpsInvalidIcon, kIconSize, gfx::kGoogleRed700); } - if (icon_str == "keyIcon") + if (icon_str == "keyIcon") { return gfx::CreateVectorIcon(kKeyIcon, kIconSize, gfx::kChromeIconGrey); - if (icon_str == "globeIcon") + } + if (icon_str == "globeIcon") { return gfx::CreateVectorIcon(kGlobeIcon, kIconSize, gfx::kChromeIconGrey); + } if (icon_str == "google") { #if defined(GOOGLE_CHROME_BUILD) return gfx::CreateVectorIcon(kGoogleGLogoIcon, kIconSize, @@ -243,6 +246,15 @@ #endif } + if (icon_str == "locationOnIcon") { + return gfx::CreateVectorIcon(vector_icons::kLocationOnIcon, kIconSize, + gfx::kChromeIconGrey); + } + if (icon_str == "userAccountAvatarIcon") { + return gfx::CreateVectorIcon(kUserAccountAvatarIcon, kIconSize, + gfx::kChromeIconGrey); + } + // For other suggestion entries, get icon from PNG files. int icon_id = GetIconResourceID(icon_str); DCHECK_NE(kResourceNotFoundId, icon_id);
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index f8250a3..84e0e2f 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -223,6 +223,7 @@ #if defined(OS_WIN) #include <shellapi.h> #include <windows.h> + #include "chrome/browser/ui/view_ids.h" #include "components/autofill/core/browser/autofill_ie_toolbar_import_win.h" #include "ui/base/win/shell.h" @@ -370,9 +371,7 @@ class Browser::InterstitialObserver : public content::WebContentsObserver { public: InterstitialObserver(Browser* browser, content::WebContents* web_contents) - : WebContentsObserver(web_contents), - browser_(browser) { - } + : WebContentsObserver(web_contents), browser_(browser) {} void DidAttachInterstitialPage() override { browser_->UpdateBookmarkBarState(BOOKMARK_BAR_STATE_CHANGE_TAB_STATE); @@ -446,10 +445,9 @@ extension_registry_observer_.Add( extensions::ExtensionRegistry::Get(profile_)); #if !defined(OS_ANDROID) - registrar_.Add( - this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, - content::Source<ThemeService>( - ThemeServiceFactory::GetForProfile(profile_))); + registrar_.Add(this, chrome::NOTIFICATION_BROWSER_THEME_CHANGED, + content::Source<ThemeService>( + ThemeServiceFactory::GetForProfile(profile_))); #endif registrar_.Add(this, chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED, content::NotificationService::AllSources()); @@ -699,9 +697,10 @@ // Include the app name in window titles for tabbed browser windows when // requested with |include_app_name|. - return (!is_app() && include_app_name) ? - l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT, title): - title; + return (!is_app() && include_app_name) + ? l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT, + title) + : title; } // static @@ -830,7 +829,7 @@ int total_download_count = DownloadCoreService::NonMaliciousDownloadCountAllProfiles(); if (total_download_count == 0) - return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close. + return DOWNLOAD_CLOSE_OK; // No downloads; can definitely close. // Figure out how many windows are open total, and associated with this // profile, that are relevant for the ok-to-close decision. @@ -925,14 +924,9 @@ ui::SelectFileDialog::FileTypeInfo file_types; file_types.allowed_paths = ui::SelectFileDialog::FileTypeInfo::ANY_PATH_OR_URL; - select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE, - base::string16(), - directory, - &file_types, - 0, - base::FilePath::StringType(), - parent_window, - NULL); + select_file_dialog_->SelectFile( + ui::SelectFileDialog::SELECT_OPEN_FILE, base::string16(), directory, + &file_types, 0, base::FilePath::StringType(), parent_window, NULL); } void Browser::UpdateDownloadShelfVisibility(bool visible) { @@ -1381,9 +1375,9 @@ // navigation, so we don't have to worry about flickering. We do, however, // need to update the command state early on load to always present usable // actions in the face of slow-to-commit pages. - if (changed_flags & (content::INVALIDATE_TYPE_URL | - content::INVALIDATE_TYPE_LOAD | - content::INVALIDATE_TYPE_TAB)) + if (changed_flags & + (content::INVALIDATE_TYPE_URL | content::INVALIDATE_TYPE_LOAD | + content::INVALIDATE_TYPE_TAB)) command_controller_->TabStateChanged(); if (web_app_controller_) @@ -1479,8 +1473,7 @@ chrome::ExecuteCommand(this, zoom_in ? IDC_ZOOM_PLUS : IDC_ZOOM_MINUS); } -bool Browser::TakeFocus(content::WebContents* source, - bool reverse) { +bool Browser::TakeFocus(content::WebContents* source, bool reverse) { content::NotificationService::current()->Notify( chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER, content::Source<Browser>(this), @@ -1491,8 +1484,8 @@ void Browser::BeforeUnloadFired(WebContents* web_contents, bool proceed, bool* proceed_to_fire_unload) { - if (is_devtools() && DevToolsWindow::HandleBeforeUnload(web_contents, - proceed, proceed_to_fire_unload)) + if (is_devtools() && DevToolsWindow::HandleBeforeUnload( + web_contents, proceed, proceed_to_fire_unload)) return; *proceed_to_fire_unload = @@ -1706,8 +1699,8 @@ PermissionRequestManager::FromWebContents(web_contents); if (permission_request_manager) { permission_request_manager->AddRequest( - new RegisterProtocolHandlerPermissionRequest(registry, handler, - url, user_gesture)); + new RegisterProtocolHandlerPermissionRequest(registry, handler, url, + user_gesture)); } } @@ -1739,10 +1732,8 @@ if (!find_tab_helper) return; - find_tab_helper->HandleFindReply(request_id, - number_of_matches, - selection_rect, - active_match_ordinal, + find_tab_helper->HandleFindReply(request_id, number_of_matches, + selection_rect, active_match_ordinal, final_update); } @@ -1929,7 +1920,8 @@ /////////////////////////////////////////////////////////////////////////////// // Browser, ui::SelectFileDialog::Listener implementation: -void Browser::FileSelected(const base::FilePath& path, int index, +void Browser::FileSelected(const base::FilePath& path, + int index, void* params) { FileSelectedWithExtraInfo(ui::SelectedFileInfo(path, path), index, params); } @@ -2034,8 +2026,9 @@ DCHECK(source); if (tab_strip_model_->GetActiveWebContents() == source) { window_->SetTranslateIconToggled( - ChromeTranslateClient::FromWebContents( - source)->GetLanguageState().IsPageTranslated()); + ChromeTranslateClient::FromWebContents(source) + ->GetLanguageState() + .IsPageTranslated()); } } @@ -2261,12 +2254,11 @@ void Browser::UpdateToolbar(bool should_restore_state) { TRACE_EVENT0("ui", "Browser::UpdateToolbar"); - window_->UpdateToolbar(should_restore_state ? - tab_strip_model_->GetActiveWebContents() : NULL); + window_->UpdateToolbar( + should_restore_state ? tab_strip_model_->GetActiveWebContents() : NULL); } -void Browser::ScheduleUIUpdate(WebContents* source, - unsigned changed_flags) { +void Browser::ScheduleUIUpdate(WebContents* source, unsigned changed_flags) { DCHECK(source); int index = tab_strip_model_->GetIndexOfWebContents(source); DCHECK_NE(TabStripModel::kNoTab, index); @@ -2347,12 +2339,14 @@ // Updating the URL happens synchronously in ScheduleUIUpdate. if (flags & content::INVALIDATE_TYPE_LOAD && GetStatusBubble()) { - GetStatusBubble()->SetStatus(CoreTabHelper::FromWebContents( - tab_strip_model_->GetActiveWebContents())->GetStatusText()); + GetStatusBubble()->SetStatus( + CoreTabHelper::FromWebContents( + tab_strip_model_->GetActiveWebContents()) + ->GetStatusText()); } - if (flags & (content::INVALIDATE_TYPE_TAB | - content::INVALIDATE_TYPE_TITLE)) { + if (flags & + (content::INVALIDATE_TYPE_TAB | content::INVALIDATE_TYPE_TITLE)) { window_->UpdateTitleBar(); } } @@ -2410,10 +2404,9 @@ SessionTabHelper::FromWebContents(web_contents); session_service->SetTabIndexInWindow( session_id(), session_tab_helper->session_id(), i); - session_service->SetPinnedState( - session_id(), - session_tab_helper->session_id(), - tab_strip_model_->IsTabPinned(i)); + session_service->SetPinnedState(session_id(), + session_tab_helper->session_id(), + tab_strip_model_->IsTabPinned(i)); } } } @@ -2438,9 +2431,7 @@ // that's ok. cancel_download_confirmation_state_ = WAITING_FOR_RESPONSE; window_->ConfirmBrowserCloseWithPendingDownloads( - num_downloads_blocking, - dialog_type, - false, + num_downloads_blocking, dialog_type, false, base::Bind(&Browser::InProgressDownloadResponse, weak_factory_.GetWeakPtr())); @@ -2491,8 +2482,8 @@ web_contents->SetDelegate(delegate); // ...and all the helpers. - WebContentsModalDialogManager::FromWebContents(web_contents)-> - SetDelegate(delegate); + WebContentsModalDialogManager::FromWebContents(web_contents) + ->SetDelegate(delegate); translate::ContentTranslateDriver& content_translate_driver = ChromeTranslateClient::FromWebContents(web_contents)->translate_driver(); if (delegate) { @@ -2637,9 +2628,9 @@ } bool should_animate = reason == BOOKMARK_BAR_STATE_CHANGE_PREF_CHANGE; - window_->BookmarkBarStateChanged(should_animate ? - BookmarkBar::ANIMATE_STATE_CHANGE : - BookmarkBar::DONT_ANIMATE_STATE_CHANGE); + window_->BookmarkBarStateChanged( + should_animate ? BookmarkBar::ANIMATE_STATE_CHANGE + : BookmarkBar::DONT_ANIMATE_STATE_CHANGE); } bool Browser::ShouldShowBookmarkBar() const {
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index ce0922d..a2364d0 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -90,7 +90,7 @@ class Extension; class ExtensionRegistry; -} +} // namespace extensions namespace gfx { class Image; @@ -269,18 +269,14 @@ initial_show_state_ = initial_show_state; } // Return true if the initial window bounds have been overridden. - bool bounds_overridden() const { - return !override_bounds_.IsEmpty(); - } + bool bounds_overridden() const { return !override_bounds_.IsEmpty(); } // Set indicator that this browser is being created via session restore. // This is used on the Mac (only) to determine animation style when the // browser window is shown. void set_is_session_restore(bool is_session_restore) { is_session_restore_ = is_session_restore; } - bool is_session_restore() const { - return is_session_restore_; - } + bool is_session_restore() const { return is_session_restore_; } bool is_focus_mode() const { return is_focus_mode_; } @@ -315,7 +311,7 @@ } const SessionID& session_id() const { return session_id_; } BrowserContentSettingBubbleModelDelegate* - content_setting_bubble_model_delegate() { + content_setting_bubble_model_delegate() { return content_setting_bubble_model_delegate_.get(); } BrowserLiveTabContext* live_tab_context() { return live_tab_context_.get(); } @@ -853,8 +849,7 @@ // updates), then scheduled_updates_ is updated for the |source| and update // pair and a task is scheduled (assuming it isn't running already) // that invokes ProcessPendingUIUpdates. - void ScheduleUIUpdate(content::WebContents* source, - unsigned changed_flags); + void ScheduleUIUpdate(content::WebContents* source, unsigned changed_flags); // Processes all pending updates to the UI that have been scheduled by // ScheduleUIUpdate in scheduled_updates_.
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index 768ef11..f71ff05 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc
@@ -130,8 +130,8 @@ using app_modal::AppModalDialogQueue; using app_modal::JavaScriptAppModalDialog; using base::ASCIIToUTF16; -using content::InterstitialPage; using content::HostZoomMap; +using content::InterstitialPage; using content::NavigationController; using content::NavigationEntry; using content::OpenURLParams; @@ -173,7 +173,7 @@ int CountRenderProcessHosts() { int result = 0; for (content::RenderProcessHost::iterator i( - content::RenderProcessHost::AllHostsIterator()); + content::RenderProcessHost::AllHostsIterator()); !i.IsAtEnd(); i.Advance()) ++result; return result; @@ -224,17 +224,13 @@ class TestInterstitialPage : public content::InterstitialPageDelegate { public: TestInterstitialPage(WebContents* tab, bool new_navigation, const GURL& url) { - interstitial_page_ = InterstitialPage::Create( - tab, new_navigation, url , this); + interstitial_page_ = + InterstitialPage::Create(tab, new_navigation, url, this); interstitial_page_->Show(); } ~TestInterstitialPage() override {} - void Proceed() { - interstitial_page_->Proceed(); - } - void DontProceed() { - interstitial_page_->DontProceed(); - } + void Proceed() { interstitial_page_->Proceed(); } + void DontProceed() { interstitial_page_->DontProceed(); } std::string GetHTMLContents() override { return "<h1>INTERSTITIAL</h1>"; } @@ -246,15 +242,12 @@ public: RenderViewSizeObserver(content::WebContents* web_contents, BrowserWindow* browser_window) - : WebContentsObserver(web_contents), - browser_window_(browser_window) { - } + : WebContentsObserver(web_contents), browser_window_(browser_window) {} - void GetSizeForRenderViewHost( - content::RenderViewHost* render_view_host, - gfx::Size* rwhv_create_size, - gfx::Size* rwhv_commit_size, - gfx::Size* wcv_commit_size) { + void GetSizeForRenderViewHost(content::RenderViewHost* render_view_host, + gfx::Size* rwhv_create_size, + gfx::Size* rwhv_commit_size, + gfx::Size* wcv_commit_size) { RenderViewSizes::const_iterator result = render_view_sizes_.end(); result = render_view_sizes_.find(render_view_host); if (result != render_view_sizes_.end()) { @@ -386,9 +379,9 @@ browser(), ui_test_utils::GetTestUrl( base::FilePath(base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File))); - EXPECT_EQ(LocaleWindowCaptionFromPageTitle(ASCIIToUTF16("title1.html")), - browser()->GetWindowTitleForCurrentTab( - true /* include_app_name */)); + EXPECT_EQ( + LocaleWindowCaptionFromPageTitle(ASCIIToUTF16("title1.html")), + browser()->GetWindowTitleForCurrentTab(true /* include_app_name */)); base::string16 tab_title; ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title)); EXPECT_EQ(ASCIIToUTF16("title1.html"), tab_title); @@ -446,9 +439,9 @@ base::FilePath(base::FilePath::kCurrentDirectory), base::FilePath(kTitle2File))); const base::string16 test_title(ASCIIToUTF16("Title Of Awesomeness")); - EXPECT_EQ(LocaleWindowCaptionFromPageTitle(test_title), - browser()->GetWindowTitleForCurrentTab( - true /* include_app_name */)); + EXPECT_EQ( + LocaleWindowCaptionFromPageTitle(test_title), + browser()->GetWindowTitleForCurrentTab(true /* include_app_name */)); base::string16 tab_title; ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title)); EXPECT_EQ(test_title, tab_title); @@ -482,8 +475,9 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, NoJavaScriptDialogsActivateTab) { // Set up two tabs, with the tab at index 0 active. - GURL url(ui_test_utils::GetTestUrl(base::FilePath( - base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File))); + GURL url(ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(kTitle1File))); ui_test_utils::NavigateToURL(browser(), url); AddTabAtIndex(0, url, ui::PAGE_TRANSITION_TYPED); EXPECT_EQ(2, browser()->tab_strip_model()->count()); @@ -537,14 +531,14 @@ // Warning: this test can take >30 seconds when running on a slow (low // memory?) Mac builder. IN_PROC_BROWSER_TEST_F(BrowserTest, ThirtyFourTabs) { - GURL url(ui_test_utils::GetTestUrl(base::FilePath( - base::FilePath::kCurrentDirectory), base::FilePath(kTitle2File))); + GURL url(ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(kTitle2File))); // There is one initial tab. const int kTabCount = 34; for (int ix = 0; ix != (kTabCount - 1); ++ix) { - chrome::AddSelectedTabWithURL(browser(), url, - ui::PAGE_TRANSITION_TYPED); + chrome::AddSelectedTabWithURL(browser(), url, ui::PAGE_TRANSITION_TYPED); } EXPECT_EQ(kTabCount, browser()->tab_strip_model()->count()); @@ -579,8 +573,7 @@ { content::WindowedNotificationObserver stop_observer( content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &web_contents->GetController())); + content::Source<NavigationController>(&web_contents->GetController())); browser()->OpenURL(OpenURLParams(abort_url, Referrer(), WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false)); @@ -598,8 +591,7 @@ { content::WindowedNotificationObserver stop_observer( content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &web_contents->GetController())); + content::Source<NavigationController>(&web_contents->GetController())); browser()->OpenURL(OpenURLParams(abort_url, Referrer(), WindowOpenDisposition::CURRENT_TAB, ui::PAGE_TRANSITION_TYPED, false)); @@ -660,8 +652,7 @@ content::RenderProcessHost* child_process = contents->GetMainFrame()->GetProcess(); content::RenderProcessHostWatcher crash_observer( - child_process, - content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + child_process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); child_process->Shutdown(0); crash_observer.Wait(); EXPECT_FALSE(dialog_queue->HasActiveDialog()); @@ -695,8 +686,7 @@ content::RenderProcessHost* child_process = contents->GetMainFrame()->GetProcess(); content::RenderProcessHostWatcher crash_observer( - child_process, - content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); + child_process, content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT); child_process->Shutdown(0); crash_observer.Wait(); EXPECT_FALSE(js_helper->IsShowingDialogForTesting()); @@ -955,8 +945,8 @@ content::WindowedNotificationObserver nav_observer( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); - oldtab->GetMainFrame()-> - ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(redirect_popup)); + oldtab->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( + ASCIIToUTF16(redirect_popup)); // Wait for popup window to appear and finish navigating. popup_observer.Wait(); @@ -989,8 +979,8 @@ content::WindowedNotificationObserver nav_observer2( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); - oldtab->GetMainFrame()-> - ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(refresh_popup)); + oldtab->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( + ASCIIToUTF16(refresh_popup)); // Wait for popup window to appear and finish navigating. popup_observer2.Wait(); @@ -1042,8 +1032,8 @@ content::WindowedNotificationObserver nav_observer( content::NOTIFICATION_NAV_ENTRY_COMMITTED, content::NotificationService::AllSources()); - oldtab->GetMainFrame()-> - ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(dont_fork_popup)); + oldtab->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( + ASCIIToUTF16(dont_fork_popup)); // Wait for popup window to appear and finish navigating. popup_observer.Wait(); @@ -1071,8 +1061,8 @@ navigate_str += "\";"; content::WindowedNotificationObserver nav_observer2( - content::NOTIFICATION_NAV_ENTRY_COMMITTED, - content::NotificationService::AllSources()); + content::NOTIFICATION_NAV_ENTRY_COMMITTED, + content::NotificationService::AllSources()); oldtab->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests( ASCIIToUTF16(navigate_str)); nav_observer2.Wait(); @@ -1122,12 +1112,15 @@ ui_test_utils::NavigateToURL(browser(), url); - NavigationEntry* entry = browser()->tab_strip_model()-> - GetActiveWebContents()->GetController().GetLastCommittedEntry(); + NavigationEntry* entry = browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetController() + .GetLastCommittedEntry(); EXPECT_EQ(expected_favicon_url.spec(), entry->GetFavicon().url.spec()); } -#if defined(OS_MACOSX) || defined(OS_LINUX) || defined (OS_WIN) +#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_WIN) // http://crbug.com/83828. On Mac 10.6, the failure rate is 14% #define MAYBE_FaviconChange DISABLED_FaviconChange #else @@ -1140,17 +1133,21 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_FaviconChange) { static const base::FilePath::CharType* kFile = FILE_PATH_LITERAL("onload_change_favicon.html"); - GURL file_url(ui_test_utils::GetTestUrl(base::FilePath( - base::FilePath::kCurrentDirectory), base::FilePath(kFile))); + GURL file_url(ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(kFile))); ASSERT_TRUE(file_url.SchemeIs(url::kFileScheme)); ui_test_utils::NavigateToURL(browser(), file_url); - NavigationEntry* entry = browser()->tab_strip_model()-> - GetActiveWebContents()->GetController().GetLastCommittedEntry(); - static const base::FilePath::CharType* kIcon = - FILE_PATH_LITERAL("test1.png"); - GURL expected_favicon_url(ui_test_utils::GetTestUrl(base::FilePath( - base::FilePath::kCurrentDirectory), base::FilePath(kIcon))); + NavigationEntry* entry = browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetController() + .GetLastCommittedEntry(); + static const base::FilePath::CharType* kIcon = FILE_PATH_LITERAL("test1.png"); + GURL expected_favicon_url(ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(kIcon))); EXPECT_EQ(expected_favicon_url.spec(), entry->GetFavicon().url.spec()); } @@ -1187,8 +1184,7 @@ extensions::ExtensionSystem::Get(browser()->profile()) ->extension_service(); service->UninstallExtension(GetExtension()->id(), - extensions::UNINSTALL_REASON_FOR_TESTING, - NULL); + extensions::UNINSTALL_REASON_FOR_TESTING, NULL); EXPECT_EQ(1, observer.closing_count()); model->RemoveObserver(&observer); @@ -1211,8 +1207,9 @@ base::CommandLine command_line(base::CommandLine::NO_PROGRAM); command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); - chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN; + chrome::startup::IsFirstRun first_run = + first_run::IsChromeFirstRun() ? chrome::startup::IS_FIRST_RUN + : chrome::startup::IS_NOT_FIRST_RUN; StartupBrowserCreatorImpl launch(base::FilePath(), command_line, first_run); // The app should open as a tab. @@ -1270,8 +1267,7 @@ // App windows can show location bars, for example when they navigate away // from their starting origin. - EXPECT_TRUE( - app_browser->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR)); + EXPECT_TRUE(app_browser->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR)); DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_window); } @@ -1356,8 +1352,9 @@ // Launch again with the same profile. base::CommandLine dummy(base::CommandLine::NO_PROGRAM); - chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? - chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN; + chrome::startup::IsFirstRun first_run = + first_run::IsChromeFirstRun() ? chrome::startup::IS_FIRST_RUN + : chrome::startup::IS_NOT_FIRST_RUN; StartupBrowserCreatorImpl launch(base::FilePath(), dummy, first_run); launch.Launch(browser()->profile(), std::vector<GURL>(), false); @@ -1434,14 +1431,14 @@ // The browser's app name should include the extension's id. std::string app_name = new_browser->app_name_; EXPECT_NE(app_name.find(extension_app->id()), std::string::npos) - << "Name " << app_name << " should contain id "<< extension_app->id(); + << "Name " << app_name << " should contain id " << extension_app->id(); } #endif // !defined(OS_MACOSX) // Makes sure the browser doesn't crash when // set_show_state(ui::SHOW_STATE_MAXIMIZED) has been invoked. IN_PROC_BROWSER_TEST_F(BrowserTest, StartMaximized) { - Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP }; + Browser::Type types[] = {Browser::TYPE_TABBED, Browser::TYPE_POPUP}; for (size_t i = 0; i < base::size(types); ++i) { Browser::CreateParams params(types[i], browser()->profile(), true); params.initial_show_state = ui::SHOW_STATE_MAXIMIZED; @@ -1452,7 +1449,7 @@ // Makes sure the browser doesn't crash when // set_show_state(ui::SHOW_STATE_MINIMIZED) has been invoked. IN_PROC_BROWSER_TEST_F(BrowserTest, StartMinimized) { - Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP }; + Browser::Type types[] = {Browser::TYPE_TABBED, Browser::TYPE_POPUP}; for (size_t i = 0; i < base::size(types); ++i) { Browser::CreateParams params(types[i], browser()->profile(), true); params.initial_show_state = ui::SHOW_STATE_MINIMIZED; @@ -1473,9 +1470,10 @@ content::WindowedNotificationObserver back_nav_load_observer( content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + content::Source<NavigationController>(&browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetController())); chrome::GoBack(browser(), WindowOpenDisposition::CURRENT_TAB); back_nav_load_observer.Wait(); CommandUpdater* command_updater = browser()->command_controller(); @@ -1483,9 +1481,10 @@ content::WindowedNotificationObserver forward_nav_load_observer( content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + content::Source<NavigationController>(&browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetController())); chrome::GoForward(browser(), WindowOpenDisposition::CURRENT_TAB); // This check will happen before the navigation completes, since the browser // won't process the renderer's response until the Wait() call below. @@ -1522,8 +1521,8 @@ CommandUpdater* new_command_updater = new_browser->command_controller(); // It should have Bookmarks & Settings commands disabled by default. EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); - EXPECT_FALSE(new_command_updater->IsCommandEnabled( - IDC_SHOW_BOOKMARK_MANAGER)); + EXPECT_FALSE( + new_command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_OPTIONS)); @@ -1595,8 +1594,8 @@ CommandUpdater* popup_command_updater = popup_browser->command_controller(); EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_OPTIONS)); - EXPECT_TRUE(popup_command_updater->IsCommandEnabled( - IDC_SHOW_BOOKMARK_MANAGER)); + EXPECT_TRUE( + popup_command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); } @@ -1775,7 +1774,6 @@ EXPECT_FALSE(contents->GetMainFrame()->GetProcess()->IsBlocked()); } - IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialCloseTab) { WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); @@ -2010,8 +2008,9 @@ ASSERT_TRUE(browser()->profile()); // Verify that the profile has been added correctly to the // ProfileAttributesStorage. - ASSERT_EQ(1u, g_browser_process->profile_manager()-> - GetProfileAttributesStorage().GetNumberOfProfiles()); + ASSERT_EQ(1u, g_browser_process->profile_manager() + ->GetProfileAttributesStorage() + .GetNumberOfProfiles()); } #endif // defined(OS_WIN) @@ -2041,8 +2040,9 @@ ASSERT_TRUE(browser()->profile()); // Verify that the profile has been added correctly to the // ProfileAttributesStorage. - ASSERT_EQ(1u, g_browser_process->profile_manager()-> - GetProfileAttributesStorage().GetNumberOfProfiles()); + ASSERT_EQ(1u, g_browser_process->profile_manager() + ->GetProfileAttributesStorage() + .GetNumberOfProfiles()); } #endif // defined(OS_WIN) @@ -2133,7 +2133,7 @@ void SetUpCommandLine(base::CommandLine* command_line) override { GURL url = ui_test_utils::GetTestUrl( - base::FilePath(), base::FilePath().AppendASCII("title1.html")); + base::FilePath(), base::FilePath().AppendASCII("title1.html")); command_line->AppendSwitchASCII(switches::kApp, url.spec()); } }; @@ -2152,14 +2152,14 @@ ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("WebKit"), true, true, NULL, NULL), 0); - ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("OS"), true, true, - NULL, NULL), + ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("OS"), true, true, NULL, + NULL), 0); ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("JavaScript"), true, true, NULL, NULL), 0); - ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("Flash"), true, - true, NULL, NULL), + ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("Flash"), true, true, + NULL, NULL), 0); } @@ -2170,31 +2170,26 @@ class ClickModifierTest : public InProcessBrowserTest { public: - ClickModifierTest() { - } + ClickModifierTest() {} // Returns a url that opens a new window or tab when clicked, via javascript. GURL GetWindowOpenURL() { return ui_test_utils::GetTestUrl( - base::FilePath(kTestDir), - base::FilePath(FILE_PATH_LITERAL("window_open.html"))); + base::FilePath(kTestDir), + base::FilePath(FILE_PATH_LITERAL("window_open.html"))); } // Returns a url that follows a simple link when clicked, unless affected by // modifiers. GURL GetHrefURL() { return ui_test_utils::GetTestUrl( - base::FilePath(kTestDir), - base::FilePath(FILE_PATH_LITERAL("href.html"))); + base::FilePath(kTestDir), + base::FilePath(FILE_PATH_LITERAL("href.html"))); } - base::string16 GetFirstPageTitle() { - return ASCIIToUTF16(kFirstPageTitle); - } + base::string16 GetFirstPageTitle() { return ASCIIToUTF16(kFirstPageTitle); } - base::string16 GetSecondPageTitle() { - return ASCIIToUTF16(kSecondPageTitle); - } + base::string16 GetSecondPageTitle() { return ASCIIToUTF16(kSecondPageTitle); } // Loads our test page and simulates a single click using the supplied button // and modifiers. The click will cause either a navigation or the creation of @@ -2387,8 +2382,7 @@ WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); content::RenderViewHost* prev_rvh = web_contents->GetRenderViewHost(); - const gfx::Size initial_wcv_size = - web_contents->GetContainerBounds().size(); + const gfx::Size initial_wcv_size = web_contents->GetContainerBounds().size(); RenderViewSizeObserver observer(web_contents, browser()->window()); // Navigate to a non-NTP page, without resizing WebContentsView. @@ -2400,8 +2394,7 @@ prev_rvh = web_contents->GetRenderViewHost(); gfx::Size rwhv_create_size0, rwhv_commit_size0, wcv_commit_size0; observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(), - &rwhv_create_size0, - &rwhv_commit_size0, + &rwhv_create_size0, &rwhv_commit_size0, &wcv_commit_size0); EXPECT_EQ(gfx::Size(initial_wcv_size.width(), initial_wcv_size.height()), rwhv_create_size0); @@ -2434,8 +2427,7 @@ EXPECT_NE(prev_rvh, web_contents->GetRenderViewHost()); gfx::Size rwhv_create_size1, rwhv_commit_size1, wcv_commit_size1; observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(), - &rwhv_create_size1, - &rwhv_commit_size1, + &rwhv_create_size1, &rwhv_commit_size1, &wcv_commit_size1); EXPECT_EQ(rwhv_create_size1, rwhv_commit_size1); EXPECT_EQ(rwhv_commit_size1, @@ -2452,8 +2444,7 @@ ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state()); gfx::Size rwhv_create_size2, rwhv_commit_size2, wcv_commit_size2; observer.GetSizeForRenderViewHost(web_contents->GetRenderViewHost(), - &rwhv_create_size2, - &rwhv_commit_size2, + &rwhv_create_size2, &rwhv_commit_size2, &wcv_commit_size2); // The behavior on OSX and Views is incorrect in this edge case, but they are @@ -2589,9 +2580,8 @@ // flaky new test: http://crbug.com/471703 IN_PROC_BROWSER_TEST_F(BrowserTest, DISABLED_ChangeDisplayMode) { - CheckDisplayModeMQ( - ASCIIToUTF16("browser"), - browser()->tab_strip_model()->GetActiveWebContents()); + CheckDisplayModeMQ(ASCIIToUTF16("browser"), + browser()->tab_strip_model()->GetActiveWebContents()); Profile* profile = ProfileManager::GetActiveUserProfile(); ui_test_utils::BrowserAddedObserver browser_added_observer;
diff --git a/chrome/browser/ui/browser_close_unittest.cc b/chrome/browser/ui/browser_close_unittest.cc index 1f184d8..68f30a3 100644 --- a/chrome/browser/ui/browser_close_unittest.cc +++ b/chrome/browser/ui/browser_close_unittest.cc
@@ -66,9 +66,7 @@ ADD_FAILURE(); } - bool IsShelfEnabled() override { - return true; - } + bool IsShelfEnabled() override { return true; } // KeyedService void Shutdown() override {}
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index 9143298..085a070 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -97,8 +97,8 @@ #include "ui/ozone/public/ozone_platform.h" #endif -using content::NavigationEntry; using content::NavigationController; +using content::NavigationEntry; using content::WebContents; namespace chrome { @@ -107,8 +107,7 @@ // BrowserCommandController, public: BrowserCommandController::BrowserCommandController(Browser* browser) - : browser_(browser), - command_updater_(nullptr) { + : browser_(browser), command_updater_(nullptr) { browser_->tab_strip_model()->AddObserver(this); PrefService* local_state = g_browser_process->local_state(); if (local_state) { @@ -149,8 +148,7 @@ base::Unretained(this))); #endif pref_signin_allowed_.Init( - prefs::kSigninAllowed, - profile()->GetOriginalProfile()->GetPrefs(), + prefs::kSigninAllowed, profile()->GetOriginalProfile()->GetPrefs(), base::Bind(&BrowserCommandController::OnSigninAllowedPrefChange, base::Unretained(this))); @@ -229,15 +227,11 @@ return false; #endif - return command_id == IDC_CLOSE_TAB || - command_id == IDC_CLOSE_WINDOW || - command_id == IDC_NEW_INCOGNITO_WINDOW || - command_id == IDC_NEW_TAB || - command_id == IDC_NEW_WINDOW || - command_id == IDC_RESTORE_TAB || + return command_id == IDC_CLOSE_TAB || command_id == IDC_CLOSE_WINDOW || + command_id == IDC_NEW_INCOGNITO_WINDOW || command_id == IDC_NEW_TAB || + command_id == IDC_NEW_WINDOW || command_id == IDC_RESTORE_TAB || command_id == IDC_SELECT_NEXT_TAB || - command_id == IDC_SELECT_PREVIOUS_TAB || - command_id == IDC_EXIT; + command_id == IDC_SELECT_PREVIOUS_TAB || command_id == IDC_EXIT; } void BrowserCommandController::TabStateChanged() { @@ -315,8 +309,8 @@ if (browser_->tab_strip_model()->active_index() == TabStripModel::kNoTab) return true; - DCHECK(command_updater_.IsCommandEnabled(id)) << "Invalid/disabled command " - << id; + DCHECK(command_updater_.IsCommandEnabled(id)) + << "Invalid/disabled command " << id; // The order of commands in this switch statement must match the function // declaration order in browser.h! @@ -347,7 +341,7 @@ Stop(browser_); break; - // Window management commands + // Window management commands case IDC_NEW_WINDOW: NewWindow(browser_); break; @@ -733,7 +727,8 @@ } void BrowserCommandController::RemoveCommandObserver( - int id, CommandObserver* observer) { + int id, + CommandObserver* observer) { command_updater_.RemoveCommandObserver(id, observer); } @@ -824,9 +819,7 @@ public: InterstitialObserver(BrowserCommandController* controller, content::WebContents* web_contents) - : WebContentsObserver(web_contents), - controller_(controller) { - } + : WebContentsObserver(web_contents), controller_(controller) {} void DidAttachInterstitialPage() override { controller_->UpdateCommandsForTabState(); @@ -902,8 +895,8 @@ command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, true); // Show various bits of UI - const bool guest_session = profile()->IsGuestSession() || - profile()->IsSystemProfile(); + const bool guest_session = + profile()->IsGuestSession() || profile()->IsSystemProfile(); DCHECK(!profile()->IsSystemProfile()) << "Ought to never have browser for the system profile."; const bool normal_window = browser_->is_type_tabbed(); @@ -917,9 +910,8 @@ command_updater_.UpdateCommandEnabled(IDC_HELP_PAGE_VIA_MENU, true); command_updater_.UpdateCommandEnabled(IDC_SHOW_BETA_FORUM, true); command_updater_.UpdateCommandEnabled(IDC_BOOKMARKS_MENU, !guest_session); - command_updater_.UpdateCommandEnabled(IDC_RECENT_TABS_MENU, - !guest_session && - !profile()->IsOffTheRecord()); + command_updater_.UpdateCommandEnabled( + IDC_RECENT_TABS_MENU, !guest_session && !profile()->IsOffTheRecord()); command_updater_.UpdateCommandEnabled(IDC_CLEAR_BROWSING_DATA, !guest_session); #if defined(OS_CHROMEOS) @@ -951,8 +943,7 @@ // Window management commands command_updater_.UpdateCommandEnabled(IDC_SELECT_NEXT_TAB, normal_window); - command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB, - normal_window); + command_updater_.UpdateCommandEnabled(IDC_SELECT_PREVIOUS_TAB, normal_window); command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_NEXT, normal_window); command_updater_.UpdateCommandEnabled(IDC_MOVE_TAB_PREVIOUS, normal_window); command_updater_.UpdateCommandEnabled(IDC_SELECT_TAB_0, normal_window); @@ -992,8 +983,7 @@ IncognitoModePrefs::Availability incognito_availability = IncognitoModePrefs::GetAvailability(profile->GetPrefs()); command_updater->UpdateCommandEnabled( - IDC_NEW_WINDOW, - incognito_availability != IncognitoModePrefs::FORCED); + IDC_NEW_WINDOW, incognito_availability != IncognitoModePrefs::FORCED); command_updater->UpdateCommandEnabled( IDC_NEW_INCOGNITO_WINDOW, incognito_availability != IncognitoModePrefs::DISABLED && !guest_session); @@ -1051,8 +1041,8 @@ CanReload(browser_)); // Window management commands - command_updater_.UpdateCommandEnabled(IDC_DUPLICATE_TAB, - !browser_->is_app() && CanDuplicateTab(browser_)); + command_updater_.UpdateCommandEnabled( + IDC_DUPLICATE_TAB, !browser_->is_app() && CanDuplicateTab(browser_)); command_updater_.UpdateCommandEnabled(IDC_WINDOW_MUTE_SITE, !browser_->is_app()); command_updater_.UpdateCommandEnabled(IDC_WINDOW_PIN_TAB, @@ -1090,16 +1080,13 @@ } void BrowserCommandController::UpdateCommandsForZoomState() { - WebContents* contents = - browser_->tab_strip_model()->GetActiveWebContents(); + WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents(); if (!contents) return; - command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, - CanZoomIn(contents)); + command_updater_.UpdateCommandEnabled(IDC_ZOOM_PLUS, CanZoomIn(contents)); command_updater_.UpdateCommandEnabled(IDC_ZOOM_NORMAL, CanResetZoom(contents)); - command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, - CanZoomOut(contents)); + command_updater_.UpdateCommandEnabled(IDC_ZOOM_MINUS, CanZoomOut(contents)); } void BrowserCommandController::UpdateCommandsForContentRestrictionState() { @@ -1121,8 +1108,7 @@ bool dev_tools_enabled = DevToolsWindow::AllowDevToolsFor( profile(), browser_->tab_strip_model()->GetActiveWebContents()); - command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS, - dev_tools_enabled); + command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS, dev_tools_enabled); command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_CONSOLE, dev_tools_enabled); command_updater_.UpdateCommandEnabled(IDC_DEV_TOOLS_DEVICES, @@ -1155,12 +1141,12 @@ return; command_updater_.UpdateCommandEnabled( - IDC_SHOW_BOOKMARK_BAR, - browser_defaults::bookmarks_enabled && !profile()->IsGuestSession() && - !profile()->IsSystemProfile() && - !profile()->GetPrefs()->IsManagedPreference( - bookmarks::prefs::kShowBookmarkBar) && - IsShowingMainUI()); + IDC_SHOW_BOOKMARK_BAR, browser_defaults::bookmarks_enabled && + !profile()->IsGuestSession() && + !profile()->IsSystemProfile() && + !profile()->GetPrefs()->IsManagedPreference( + bookmarks::prefs::kShowBookmarkBar) && + IsShowingMainUI()); } void BrowserCommandController::UpdateCommandsForFileSelectionDialogs() { @@ -1186,21 +1172,20 @@ // Window management commands command_updater_.UpdateCommandEnabled( - IDC_SHOW_AS_TAB, - !browser_->is_type_tabbed() && !is_fullscreen); + IDC_SHOW_AS_TAB, !browser_->is_type_tabbed() && !is_fullscreen); // Focus various bits of UI command_updater_.UpdateCommandEnabled(IDC_FOCUS_TOOLBAR, show_main_ui); command_updater_.UpdateCommandEnabled(IDC_FOCUS_LOCATION, show_location_bar); command_updater_.UpdateCommandEnabled(IDC_FOCUS_SEARCH, show_main_ui); - command_updater_.UpdateCommandEnabled( - IDC_FOCUS_MENU_BAR, main_not_fullscreen); - command_updater_.UpdateCommandEnabled( - IDC_FOCUS_NEXT_PANE, main_not_fullscreen); - command_updater_.UpdateCommandEnabled( - IDC_FOCUS_PREVIOUS_PANE, main_not_fullscreen); - command_updater_.UpdateCommandEnabled( - IDC_FOCUS_BOOKMARKS, main_not_fullscreen); + command_updater_.UpdateCommandEnabled(IDC_FOCUS_MENU_BAR, + main_not_fullscreen); + command_updater_.UpdateCommandEnabled(IDC_FOCUS_NEXT_PANE, + main_not_fullscreen); + command_updater_.UpdateCommandEnabled(IDC_FOCUS_PREVIOUS_PANE, + main_not_fullscreen); + command_updater_.UpdateCommandEnabled(IDC_FOCUS_BOOKMARKS, + main_not_fullscreen); command_updater_.UpdateCommandEnabled( IDC_FOCUS_INACTIVE_POPUP_FOR_ACCESSIBILITY, main_not_fullscreen); @@ -1224,7 +1209,8 @@ #if !defined(OS_MACOSX) // Disable toggling into fullscreen mode if disallowed by pref. - const bool fullscreen_enabled = is_fullscreen || + const bool fullscreen_enabled = + is_fullscreen || profile()->GetPrefs()->GetBoolean(prefs::kFullscreenAllowed); #else const bool fullscreen_enabled = true; @@ -1358,14 +1344,14 @@ command_updater_.UpdateCommandEnabled( IDC_RESTORE_TAB, tab_restore_service && - (!tab_restore_service->IsLoaded() || - GetRestoreTabType(browser_) != TabStripModelDelegate::RESTORE_NONE)); + (!tab_restore_service->IsLoaded() || + GetRestoreTabType(browser_) != TabStripModelDelegate::RESTORE_NONE)); } void BrowserCommandController::UpdateCommandsForFind() { TabStripModel* model = browser_->tab_strip_model(); - bool enabled = !model->IsTabBlocked(model->active_index()) && - !browser_->is_devtools(); + bool enabled = + !model->IsTabBlocked(model->active_index()) && !browser_->is_devtools(); command_updater_.UpdateCommandEnabled(IDC_FIND, enabled); command_updater_.UpdateCommandEnabled(IDC_FIND_NEXT, enabled);
diff --git a/chrome/browser/ui/browser_command_controller_browsertest.cc b/chrome/browser/ui/browser_command_controller_browsertest.cc index 6e85720..7978ad48 100644 --- a/chrome/browser/ui/browser_command_controller_browsertest.cc +++ b/chrome/browser/ui/browser_command_controller_browsertest.cc
@@ -43,7 +43,7 @@ namespace chrome { -class BrowserCommandControllerBrowserTest: public InProcessBrowserTest { +class BrowserCommandControllerBrowserTest : public InProcessBrowserTest { public: BrowserCommandControllerBrowserTest() {} ~BrowserCommandControllerBrowserTest() override {} @@ -117,12 +117,12 @@ TemplateURLServiceFactory::GetForProfile(guest)->set_loaded(true); const CommandUpdater* command_updater = browser->command_controller(); - #if defined(OS_CHROMEOS) - // Chrome OS uses system tray menu to handle multi-profiles. - EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU)); - #else - EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU)); - #endif +#if defined(OS_CHROMEOS) + // Chrome OS uses system tray menu to handle multi-profiles. + EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU)); +#else + EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_AVATAR_MENU)); +#endif } #if defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc b/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc index 80998ce..de54f379 100644 --- a/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/browser_command_controller_interactive_browsertest.cc
@@ -100,10 +100,10 @@ #if defined(OS_MACOSX) // Triggers a DCHECK in MacViews: http://crbug.com/823478 #define MAYBE_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11 \ - DISABLED_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11 + DISABLED_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11 #else #define MAYBE_KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11 \ - KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11 + KeyEventsShouldBeConsumedByWebPageInJsFullscreenExceptForF11 #endif IN_PROC_BROWSER_TEST_F( BrowserCommandControllerInteractiveTest, @@ -135,10 +135,10 @@ // TODO(zijiehe): Figure out why this test crashes on Mac OSX. The suspicious // command is "SendFullscreenShortcutAndWait()". See, http://crbug.com/738949. #define MAYBE_ShortcutsShouldTakeEffectInBrowserFullscreen \ - DISABLED_ShortcutsShouldTakeEffectInBrowserFullscreen + DISABLED_ShortcutsShouldTakeEffectInBrowserFullscreen #else #define MAYBE_ShortcutsShouldTakeEffectInBrowserFullscreen \ - ShortcutsShouldTakeEffectInBrowserFullscreen + ShortcutsShouldTakeEffectInBrowserFullscreen #endif IN_PROC_BROWSER_TEST_F(BrowserCommandControllerInteractiveTest, MAYBE_ShortcutsShouldTakeEffectInBrowserFullscreen) { @@ -165,10 +165,10 @@ #if defined(OS_CHROMEOS) // This test is flaky on ChromeOS, see http://crbug.com/754878. #define MAYBE_ShortcutsShouldTakeEffectInJsFullscreen \ - DISABLED_ShortcutsShouldTakeEffectInJsFullscreen + DISABLED_ShortcutsShouldTakeEffectInJsFullscreen #else #define MAYBE_ShortcutsShouldTakeEffectInJsFullscreen \ - ShortcutsShouldTakeEffectInJsFullscreen + ShortcutsShouldTakeEffectInJsFullscreen #endif IN_PROC_BROWSER_TEST_F(BrowserCommandControllerInteractiveTest, MAYBE_ShortcutsShouldTakeEffectInJsFullscreen) {
diff --git a/chrome/browser/ui/browser_command_controller_unittest.cc b/chrome/browser/ui/browser_command_controller_unittest.cc index b61739c..899ace4c 100644 --- a/chrome/browser/ui/browser_command_controller_unittest.cc +++ b/chrome/browser/ui/browser_command_controller_unittest.cc
@@ -161,8 +161,7 @@ testprofile->SetGuestSession(true); chrome::BrowserCommandController :: UpdateSharedCommandsForIncognitoAvailability( - browser()->command_controller(), - testprofile); + browser()->command_controller(), testprofile); EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_OPTIONS)); EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_IMPORT_SETTINGS)); EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_SHOW_SIGNIN)); @@ -172,8 +171,7 @@ IncognitoModePrefs::FORCED); chrome::BrowserCommandController :: UpdateSharedCommandsForIncognitoAvailability( - browser()->command_controller(), - testprofile); + browser()->command_controller(), testprofile); EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_OPTIONS)); EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_IMPORT_SETTINGS)); EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_SHOW_SIGNIN));
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 3e4ebd9..0c29520 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -176,11 +176,11 @@ BookmarkModel* model = BookmarkModelFactory::GetForBrowserContext(browser->profile()); return browser_defaults::bookmarks_enabled && - browser->profile()->GetPrefs()->GetBoolean( - bookmarks::prefs::kEditBookmarksEnabled) && - model && model->loaded() && browser->is_type_tabbed() && - (!check_remove_bookmark_ui || - !chrome::ShouldRemoveBookmarkThisPageUI(browser->profile())); + browser->profile()->GetPrefs()->GetBoolean( + bookmarks::prefs::kEditBookmarksEnabled) && + model && model->loaded() && browser->is_type_tabbed() && + (!check_remove_bookmark_ui || + !chrome::ShouldRemoveBookmarkThisPageUI(browser->profile())); } #if BUILDFLAG(ENABLE_EXTENSIONS) @@ -207,8 +207,7 @@ const extensions::ExtensionSet& extension_set = extensions::ExtensionRegistry::Get(profile)->enabled_extensions(); for (extensions::ExtensionSet::const_iterator i = extension_set.begin(); - i != extension_set.end(); - ++i) { + i != extension_set.end(); ++i) { extensions::Command prospective_command; if (command_service->GetSuggestedExtensionCommand( (*i)->id(), bookmark_page_accelerator, &prospective_command)) { @@ -393,7 +392,7 @@ PrefService* prefs = profile->GetPrefs(); if (incognito) { if (IncognitoModePrefs::GetAvailability(prefs) == - IncognitoModePrefs::DISABLED) { + IncognitoModePrefs::DISABLED) { incognito = false; } } else if (profile->IsGuestSession() || @@ -433,16 +432,16 @@ service->RestoreMostRecentEntry(nullptr); } -void OpenURLOffTheRecord(Profile* profile, - const GURL& url) { +void OpenURLOffTheRecord(Profile* profile, const GURL& url) { ScopedTabbedBrowserDisplayer displayer(profile->GetOffTheRecordProfile()); - AddSelectedTabWithURL(displayer.browser(), url, - ui::PAGE_TRANSITION_LINK); + AddSelectedTabWithURL(displayer.browser(), url, ui::PAGE_TRANSITION_LINK); } bool CanGoBack(const Browser* browser) { - return browser->tab_strip_model()->GetActiveWebContents()-> - GetController().CanGoBack(); + return browser->tab_strip_model() + ->GetActiveWebContents() + ->GetController() + .CanGoBack(); } void GoBack(Browser* browser, WindowOpenDisposition disposition) { @@ -460,15 +459,18 @@ } bool CanGoForward(const Browser* browser) { - return browser->tab_strip_model()->GetActiveWebContents()-> - GetController().CanGoForward(); + return browser->tab_strip_model() + ->GetActiveWebContents() + ->GetController() + .CanGoForward(); } void GoForward(Browser* browser, WindowOpenDisposition disposition) { base::RecordAction(UserMetricsAction("Forward")); if (CanGoForward(browser)) { - GetTabAndRevertIfNecessary(browser, disposition)-> - GetController().GoForward(); + GetTabAndRevertIfNecessary(browser, disposition) + ->GetController() + .GoForward(); } } @@ -506,7 +508,7 @@ PrefService* pref_service = browser->profile()->GetPrefs(); if (pref_service) { if (google_util::IsGoogleHomePageUrl( - GURL(pref_service->GetString(prefs::kHomePage)))) { + GURL(pref_service->GetString(prefs::kHomePage)))) { extra_headers = rlz::RLZTracker::GetAccessPointHttpHeader( rlz::RLZTracker::ChromeHomePage()); } @@ -532,9 +534,8 @@ OpenURLParams params( url, Referrer(), disposition, - ui::PageTransitionFromInt( - ui::PAGE_TRANSITION_AUTO_BOOKMARK | - ui::PAGE_TRANSITION_HOME_PAGE), + ui::PageTransitionFromInt(ui::PAGE_TRANSITION_AUTO_BOOKMARK | + ui::PAGE_TRANSITION_HOME_PAGE), false); params.extra_headers = extra_headers; browser->OpenURL(params); @@ -560,11 +561,12 @@ Navigate(¶ms); #if BUILDFLAG(ENABLE_EXTENSIONS) - DCHECK(extensions::ExtensionSystem::Get( - browser->profile())->extension_service()); + DCHECK(extensions::ExtensionSystem::Get(browser->profile()) + ->extension_service()); const extensions::Extension* extension = extensions::ExtensionRegistry::Get(browser->profile()) - ->enabled_extensions().GetAppByURL(url); + ->enabled_extensions() + .GetAppByURL(url); if (extension) { extensions::RecordAppLaunchType(extension_misc::APP_LAUNCH_OMNIBOX_LOCATION, extension->GetType()); @@ -750,8 +752,9 @@ // Preserve the size of the original window. The new window has already // been given an offset by the OS, so we shouldn't copy the old bounds. BrowserWindow* new_window = new_browser->window(); - new_window->SetBounds(gfx::Rect(new_window->GetRestoredBounds().origin(), - browser->window()->GetRestoredBounds().size())); + new_window->SetBounds( + gfx::Rect(new_window->GetRestoredBounds().origin(), + browser->window()->GetRestoredBounds().size())); // We need to show the browser now. Otherwise ContainerWin assumes the // WebContents is invisible and won't size it. @@ -858,8 +861,8 @@ case extensions::Command::Type::kPageAction: // BookmarkCurrentPage is called through a user gesture, so it is safe // to grant the active tab permission. - extensions::ExtensionActionAPI::Get(browser->profile())-> - ShowExtensionActionPopup(extension, browser, true); + extensions::ExtensionActionAPI::Get(browser->profile()) + ->ShowExtensionActionPopup(extension, browser, true); break; } return; @@ -879,8 +882,8 @@ bool CanBookmarkAllTabs(const Browser* browser) { return browser->tab_strip_model()->count() > 1 && - !chrome::ShouldRemoveBookmarkOpenPagesUI(browser->profile()) && - CanBookmarkCurrentPageInternal(browser, false); + !chrome::ShouldRemoveBookmarkOpenPagesUI(browser->profile()) && + CanBookmarkCurrentPageInternal(browser, false); } void SaveCreditCard(Browser* browser) { @@ -935,8 +938,8 @@ browser->tab_strip_model()->GetActiveWebContents(); ManagePasswordsUIController* controller = ManagePasswordsUIController::FromWebContents(web_contents); - TabDialogs::FromWebContents(web_contents)->ShowManagePasswordsBubble( - !controller->IsAutomaticallyOpeningBubble()); + TabDialogs::FromWebContents(web_contents) + ->ShowManagePasswordsBubble(!controller->IsAutomaticallyOpeningBubble()); } void SavePage(Browser* browser) { @@ -952,11 +955,11 @@ // LocalState can be NULL in tests. if (g_browser_process->local_state() && !g_browser_process->local_state()->GetBoolean( - prefs::kAllowFileSelectionDialogs)) { + prefs::kAllowFileSelectionDialogs)) { return false; } return !browser->is_devtools() && - !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE); + !(GetContentRestrictions(browser) & CONTENT_RESTRICTION_SAVE); } void ShowFindBar(Browser* browser) { @@ -966,9 +969,10 @@ void Print(Browser* browser) { #if BUILDFLAG(ENABLE_PRINTING) auto* web_contents = browser->tab_strip_model()->GetActiveWebContents(); - printing::StartPrint(web_contents, browser->profile()->GetPrefs()->GetBoolean( - prefs::kPrintPreviewDisabled), - false /* has_selection? */); + printing::StartPrint( + web_contents, + browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintPreviewDisabled), + false /* has_selection? */); #endif } @@ -982,9 +986,9 @@ // block it. WebContents* current_tab = browser->tab_strip_model()->GetActiveWebContents(); return browser->profile()->GetPrefs()->GetBoolean(prefs::kPrintingEnabled) && - (current_tab && !current_tab->IsCrashed()) && - !(IsShowingWebContentsModalDialog(browser) || - GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT); + (current_tab && !current_tab->IsCrashed()) && + !(IsShowingWebContentsModalDialog(browser) || + GetContentRestrictions(browser) & CONTENT_RESTRICTION_PRINT); } #if BUILDFLAG(ENABLE_PRINTING) @@ -1028,11 +1032,11 @@ WebContents* wc = browser->tab_strip_model()->GetActiveWebContents(); DCHECK(wc); - std::string title = net::EscapeQueryParamValue( - base::UTF16ToUTF8(wc->GetTitle()), false); + std::string title = + net::EscapeQueryParamValue(base::UTF16ToUTF8(wc->GetTitle()), false); std::string page_url = net::EscapeQueryParamValue(wc->GetURL().spec(), false); - std::string mailto = std::string("mailto:?subject=Fwd:%20") + - title + "&body=%0A%0A" + page_url; + std::string mailto = std::string("mailto:?subject=Fwd:%20") + title + + "&body=%0A%0A" + page_url; platform_util::OpenExternal(browser->profile(), GURL(mailto)); } @@ -1199,7 +1203,7 @@ bool CanRequestTabletSite(WebContents* current_tab) { return current_tab && - current_tab->GetController().GetLastCommittedEntry() != NULL; + current_tab->GetController().GetLastCommittedEntry() != NULL; } bool IsRequestingTabletSite(Browser* browser) { @@ -1251,8 +1255,8 @@ bool IsDebuggerAttachedToCurrentTab(Browser* browser) { WebContents* contents = browser->tab_strip_model()->GetActiveWebContents(); - return contents ? - content::DevToolsAgentHost::IsDebuggerAttached(contents) : false; + return contents ? content::DevToolsAgentHost::IsDebuggerAttached(contents) + : false; } void CopyURL(Browser* browser) { @@ -1283,9 +1287,10 @@ } bool CanViewSource(const Browser* browser) { - return !browser->is_devtools() && - browser->tab_strip_model()->GetActiveWebContents()->GetController(). - CanViewSource(); + return !browser->is_devtools() && browser->tab_strip_model() + ->GetActiveWebContents() + ->GetController() + .CanViewSource(); } #if BUILDFLAG(ENABLE_EXTENSIONS)
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h index 4aa0f36..6df3840 100644 --- a/chrome/browser/ui/browser_commands.h +++ b/chrome/browser/ui/browser_commands.h
@@ -82,8 +82,7 @@ bool CanZoomOut(content::WebContents* contents); bool CanResetZoom(content::WebContents* contents); void RestoreTab(Browser* browser); -TabStripModelDelegate::RestoreTabType GetRestoreTabType( - const Browser* browser); +TabStripModelDelegate::RestoreTabType GetRestoreTabType(const Browser* browser); void SelectNextTab( Browser* browser, TabStripModel::UserGestureDetails gesture_detail =
diff --git a/chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc b/chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc index 88e1f37..a0ca506 100644 --- a/chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc +++ b/chrome/browser/ui/browser_content_setting_bubble_model_delegate.cc
@@ -19,12 +19,11 @@ "https://support.google.com/chrome/?p=unauthenticated"; BrowserContentSettingBubbleModelDelegate:: -BrowserContentSettingBubbleModelDelegate(Browser* browser) : browser_(browser) { -} + BrowserContentSettingBubbleModelDelegate(Browser* browser) + : browser_(browser) {} BrowserContentSettingBubbleModelDelegate:: -~BrowserContentSettingBubbleModelDelegate() { -} + ~BrowserContentSettingBubbleModelDelegate() {} void BrowserContentSettingBubbleModelDelegate::ShowCollectedCookiesDialog( content::WebContents* web_contents) { @@ -34,8 +33,7 @@ void BrowserContentSettingBubbleModelDelegate::ShowMediaSettingsPage() { // Microphone and camera settings appear in the content settings menu right // next to each other, the microphone section is first. - chrome::ShowContentSettings( - browser_, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); + chrome::ShowContentSettings(browser_, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC); } void BrowserContentSettingBubbleModelDelegate::ShowContentSettingsPage(
diff --git a/chrome/browser/ui/browser_finder.cc b/chrome/browser/ui/browser_finder.cc index 93a6940..441237597 100644 --- a/chrome/browser/ui/browser_finder.cc +++ b/chrome/browser/ui/browser_finder.cc
@@ -28,15 +28,14 @@ namespace { - // Type used to indicate to match anything. -const int kMatchAny = 0; +const int kMatchAny = 0; // See BrowserMatches for details. -const int kMatchOriginalProfile = 1 << 0; +const int kMatchOriginalProfile = 1 << 0; const int kMatchCanSupportWindowFeature = 1 << 1; -const int kMatchTabbed = 1 << 2; -const int kMatchDisplayId = 1 << 3; +const int kMatchTabbed = 1 << 2; +const int kMatchDisplayId = 1 << 3; // Returns true if the specified |browser| matches the specified arguments. // |match_types| is a bitmask dictating what parameters to match: @@ -173,10 +172,8 @@ display_id); } -Browser* FindAnyBrowser(Profile* profile, - bool match_original_profiles) { - return FindBrowserWithTabbedOrAnyType(profile, - false, +Browser* FindAnyBrowser(Profile* profile, bool match_original_profiles) { + return FindBrowserWithTabbedOrAnyType(profile, false, match_original_profiles); }
diff --git a/chrome/browser/ui/browser_finder.h b/chrome/browser/ui/browser_finder.h index 7b9ca16..45ecde7 100644 --- a/chrome/browser/ui/browser_finder.h +++ b/chrome/browser/ui/browser_finder.h
@@ -37,8 +37,7 @@ int64_t display_id = display::kInvalidDisplayId); // Finds an existing browser window of any kind. -Browser* FindAnyBrowser(Profile* profile, - bool match_original_profiles); +Browser* FindAnyBrowser(Profile* profile, bool match_original_profiles); // Find an existing browser window with the provided profile. Searches in the // order of last activation. Only browsers that have been active can be
diff --git a/chrome/browser/ui/browser_finder_chromeos_unittest.cc b/chrome/browser/ui/browser_finder_chromeos_unittest.cc index fb60bf8..fa63cd7 100644 --- a/chrome/browser/ui/browser_finder_chromeos_unittest.cc +++ b/chrome/browser/ui/browser_finder_chromeos_unittest.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/browser_finder.h" - #include "base/macros.h" #include "base/memory/ptr_util.h" #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h" @@ -11,6 +9,7 @@ #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client_impl.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_client_impl_test_helper.h" +#include "chrome/browser/ui/browser_finder.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/test_browser_window_aura.h" #include "chrome/test/base/testing_profile_manager.h"
diff --git a/chrome/browser/ui/browser_focus_uitest.cc b/chrome/browser/ui/browser_focus_uitest.cc index 785bc31..1ea385b 100644 --- a/chrome/browser/ui/browser_focus_uitest.cc +++ b/chrome/browser/ui/browser_focus_uitest.cc
@@ -83,15 +83,13 @@ return ui_test_utils::IsViewFocused(browser(), vid); } - void ClickOnView(ViewID vid) { - ui_test_utils::ClickOnView(browser(), vid); - } + void ClickOnView(ViewID vid) { ui_test_utils::ClickOnView(browser(), vid); } void TestFocusTraversal(RenderViewHost* render_view_host, bool reverse) { const char kGetFocusedElementJS[] = "window.domAutomationController.send(getFocusedElement());"; - const char* kExpectedIDs[] = { "textEdit", "searchButton", "luckyButton", - "googleLink", "gmailLink", "gmapLink" }; + const char* kExpectedIDs[] = {"textEdit", "searchButton", "luckyButton", + "googleLink", "gmailLink", "gmapLink"}; SCOPED_TRACE(base::StringPrintf("TestFocusTraversal: reverse=%d", reverse)); ui::KeyboardCode key = ui::VKEY_TAB; #if defined(OS_MACOSX) @@ -109,12 +107,12 @@ // are required to traverse the back/forward buttons and the tab strip. #if defined(OS_MACOSX) if (ui_controls::IsFullKeyboardAccessEnabled()) { - ASSERT_TRUE(ui_test_utils::SendKeyPressSync( - browser(), key, false, reverse, false, false)); + ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), key, false, + reverse, false, false)); if (reverse) { for (int j = 0; j < 3; ++j) { - ASSERT_TRUE(ui_test_utils::SendKeyPressSync( - browser(), key, false, reverse, false, false)); + ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), key, false, + reverse, false, false)); } } } @@ -273,16 +271,13 @@ // Create several tabs. for (int i = 0; i < 4; ++i) { - chrome::AddSelectedTabWithURL(browser(), url, - ui::PAGE_TRANSITION_TYPED); + chrome::AddSelectedTabWithURL(browser(), url, ui::PAGE_TRANSITION_TYPED); } // Alternate focus for the tab. - const bool kFocusPage[3][5] = { - { true, true, true, true, false }, - { false, false, false, false, false }, - { false, true, false, true, false } - }; + const bool kFocusPage[3][5] = {{true, true, true, true, false}, + {false, false, false, false, false}, + {false, true, false, true, false}}; for (int i = 0; i < 3; i++) { for (int j = 0; j < 5; j++) { @@ -313,24 +308,24 @@ // Try the above, but with ctrl+tab. Since tab normally changes focus, // this has regressed in the past. Loop through several times to be sure. for (int j = 0; j < 15; j++) { - ViewID vid = kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER : - VIEW_ID_OMNIBOX; + ViewID vid = + kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER : VIEW_ID_OMNIBOX; ASSERT_TRUE(IsViewFocused(vid)); - ASSERT_TRUE(ui_test_utils::SendKeyPressSync( - browser(), ui::VKEY_TAB, true, false, false, false)); + ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_TAB, true, + false, false, false)); } // As above, but with ctrl+shift+tab. browser()->tab_strip_model()->ActivateTabAt( 4, {TabStripModel::GestureType::kOther}); for (int j = 14; j >= 0; --j) { - ViewID vid = kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER : - VIEW_ID_OMNIBOX; + ViewID vid = + kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER : VIEW_ID_OMNIBOX; ASSERT_TRUE(IsViewFocused(vid)); - ASSERT_TRUE(ui_test_utils::SendKeyPressSync( - browser(), ui::VKEY_TAB, true, true, false, false)); + ASSERT_TRUE(ui_test_utils::SendKeyPressSync(browser(), ui::VKEY_TAB, true, + true, false, false)); } } } @@ -425,8 +420,7 @@ chrome::FocusLocationBar(browser()); ASSERT_TRUE(content::ExecuteScript( - browser()->tab_strip_model()->GetActiveWebContents(), - "stealFocus();")); + browser()->tab_strip_model()->GetActiveWebContents(), "stealFocus();")); // Make sure the location bar is still focused. ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); @@ -547,8 +541,8 @@ EXPECT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); // Open about:blank, focus should be on the location bar. - chrome::AddSelectedTabWithURL( - browser(), GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_LINK); + chrome::AddSelectedTabWithURL(browser(), GURL(url::kAboutBlankURL), + ui::PAGE_TRANSITION_LINK); ASSERT_NO_FATAL_FAILURE(content::WaitForLoadStop( browser()->tab_strip_model()->GetActiveWebContents())); EXPECT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); @@ -570,8 +564,10 @@ content::WindowedNotificationObserver observer( content::NOTIFICATION_LOAD_STOP, content::Source<content::NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + &browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetController())); chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); observer.Wait(); } @@ -587,8 +583,10 @@ content::WindowedNotificationObserver observer( content::NOTIFICATION_LOAD_STOP, content::Source<content::NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + &browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetController())); chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); observer.Wait(); } @@ -616,8 +614,10 @@ content::WindowedNotificationObserver observer( content::NOTIFICATION_LOAD_STOP, content::Source<content::NavigationController>( - &browser()->tab_strip_model()->GetActiveWebContents()-> - GetController())); + &browser() + ->tab_strip_model() + ->GetActiveWebContents() + ->GetController())); chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB); observer.Wait(); } @@ -654,8 +654,12 @@ // Focus the omnibox. chrome::FocusLocationBar(browser()); - OmniboxEditController* controller = browser()->window()->GetLocationBar()-> - GetOmniboxView()->model()->controller(); + OmniboxEditController* controller = browser() + ->window() + ->GetLocationBar() + ->GetOmniboxView() + ->model() + ->controller(); // Simulate an alt-enter. controller->OnAutocompleteAccept( @@ -686,8 +690,9 @@ // Navigate to another page. const base::FilePath::CharType* kEmptyFile = FILE_PATH_LITERAL("empty.html"); - GURL file_url(ui_test_utils::GetTestUrl(base::FilePath( - base::FilePath::kCurrentDirectory), base::FilePath(kEmptyFile))); + GURL file_url(ui_test_utils::GetTestUrl( + base::FilePath(base::FilePath::kCurrentDirectory), + base::FilePath(kEmptyFile))); ui_test_utils::NavigateToURL(browser(), file_url); ClickOnView(VIEW_ID_TAB_CONTAINER); @@ -731,7 +736,8 @@ const GURL url2 = embedded_test_server()->GetURL("/title2.html"); const std::string spoof = "var w = window.open('about:blank'); w.opener = null;" - "w.document.location = '" + url2.spec() + "';"; + "w.document.location = '" + + url2.spec() + "';"; ASSERT_TRUE(content::ExecuteScript(web_contents, spoof)); EXPECT_EQ(url1, web_contents->GetVisibleURL());
diff --git a/chrome/browser/ui/browser_instant_controller_unittest.cc b/chrome/browser/ui/browser_instant_controller_unittest.cc index 60c8139..14adffe4 100644 --- a/chrome/browser/ui/browser_instant_controller_unittest.cc +++ b/chrome/browser/ui/browser_instant_controller_unittest.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 "chrome/browser/ui/browser_instant_controller.h" + #include <stddef.h> #include <vector> @@ -14,7 +16,6 @@ #include "chrome/browser/search/instant_service.h" #include "chrome/browser/search/instant_unittest_base.h" #include "chrome/browser/search/search.h" -#include "chrome/browser/ui/browser_instant_controller.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/url_constants.h" #include "content/public/browser/navigation_handle.h" @@ -76,20 +77,15 @@ const GURL& current_url() const { return contents_->GetURL(); } - int num_reloads() const { - return num_reloads_; - } + int num_reloads() const { return num_reloads_; } - bool can_go_back() const { - return contents_->GetController().CanGoBack(); - } + bool can_go_back() const { return contents_->GetController().CanGoBack(); } protected: friend class BrowserInstantControllerTest; FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest, DefaultSearchProviderChanged); - FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest, - GoogleBaseURLUpdated); + FRIEND_TEST_ALL_PREFIXES(BrowserInstantControllerTest, GoogleBaseURLUpdated); private: content::WebContents* contents_; @@ -106,7 +102,7 @@ kTabReloadTestCasesFinalProviderNotGoogle[i]; AddTab(browser(), GURL(test.start_url)); content::WebContents* contents = - browser()->tab_strip_model()->GetActiveWebContents(); + browser()->tab_strip_model()->GetActiveWebContents(); // Validate initial instant state. EXPECT_EQ(test.start_in_instant_process, @@ -137,7 +133,7 @@ base::RunLoop loop; loop.RunUntilIdle(); EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads()) - << test.description; + << test.description; if (test.end_in_local_ntp) { EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), observer->current_url()) @@ -153,7 +149,7 @@ const TabReloadTestCase& test = kTabReloadTestCasesFinalProviderGoogle[i]; AddTab(browser(), GURL(test.start_url)); content::WebContents* contents = - browser()->tab_strip_model()->GetActiveWebContents(); + browser()->tab_strip_model()->GetActiveWebContents(); // Validate initial instant state. EXPECT_EQ(test.start_in_instant_process, @@ -181,7 +177,7 @@ base::RunLoop loop; loop.RunUntilIdle(); EXPECT_EQ(test.should_reload ? 1 : 0, observer->num_reloads()) - << test.description; + << test.description; if (test.end_in_local_ntp) { EXPECT_EQ(GURL(chrome::kChromeSearchLocalNtpUrl), observer->current_url())
diff --git a/chrome/browser/ui/browser_list.cc b/chrome/browser/ui/browser_list.cc index 76f2d70a..ed1a235 100644 --- a/chrome/browser/ui/browser_list.cc +++ b/chrome/browser/ui/browser_list.cc
@@ -82,8 +82,7 @@ browser->RegisterKeepAlive(); content::NotificationService::current()->Notify( - chrome::NOTIFICATION_BROWSER_OPENED, - content::Source<Browser>(browser), + chrome::NOTIFICATION_BROWSER_OPENED, content::Source<Browser>(browser), content::NotificationService::NoDetails()); for (BrowserListObserver& observer : observers_.Get()) @@ -101,8 +100,7 @@ browser_list->currently_closing_browsers_.erase(browser); content::NotificationService::current()->Notify( - chrome::NOTIFICATION_BROWSER_CLOSED, - content::Source<Browser>(browser), + chrome::NOTIFICATION_BROWSER_CLOSED, content::Source<Browser>(browser), content::NotificationService::NoDetails()); RemoveBrowserFrom(browser, &browser_list->browsers_); @@ -332,11 +330,9 @@ //////////////////////////////////////////////////////////////////////////////// // BrowserList, private: -BrowserList::BrowserList() { -} +BrowserList::BrowserList() {} -BrowserList::~BrowserList() { -} +BrowserList::~BrowserList() {} // static void BrowserList::RemoveBrowserFrom(Browser* browser,
diff --git a/chrome/browser/ui/browser_list_observer.h b/chrome/browser/ui/browser_list_observer.h index d8ec51c..6879a58 100644 --- a/chrome/browser/ui/browser_list_observer.h +++ b/chrome/browser/ui/browser_list_observer.h
@@ -8,7 +8,7 @@ class Browser; class BrowserListObserver { - public: + public: // Called immediately after a browser is added to the list virtual void OnBrowserAdded(Browser* browser) {}
diff --git a/chrome/browser/ui/browser_navigator_browsertest.cc b/chrome/browser/ui/browser_navigator_browsertest.cc index 91346dd..b146eb9 100644 --- a/chrome/browser/ui/browser_navigator_browsertest.cc +++ b/chrome/browser/ui/browser_navigator_browsertest.cc
@@ -111,7 +111,9 @@ } bool BrowserNavigatorTest::OpenPOSTURLInNewForegroundTabAndGetTitle( - const GURL& url, const std::string& post_data, bool is_browser_initiated, + const GURL& url, + const std::string& post_data, + bool is_browser_initiated, base::string16* title) { NavigateParams param(MakeNavigateParams()); param.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; @@ -163,8 +165,7 @@ WebContents* base_web_contents = browser()->tab_strip_model()->GetActiveWebContents(); if (base_web_contents) { - create_params.initial_size = - base_web_contents->GetContainerBounds().size(); + create_params.initial_size = base_web_contents->GetContainerBounds().size(); } return WebContents::Create(create_params); } @@ -323,8 +324,7 @@ EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); EXPECT_EQ(2, browser()->tab_strip_model()->active_index()); - unsigned int previous_tab_contents_count = - created_tab_contents_count_ = 0; + unsigned int previous_tab_contents_count = created_tab_contents_count_ = 0; // Navigate to singleton_url1. NavigateParams params(MakeNavigateParams()); @@ -337,8 +337,7 @@ EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); // No tab contents should have been created - EXPECT_EQ(previous_tab_contents_count, - created_tab_contents_count_); + EXPECT_EQ(previous_tab_contents_count, created_tab_contents_count_); } IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, @@ -370,8 +369,7 @@ NavigateParams params(MakeNavigateParams()); params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; Navigate(¶ms); - EXPECT_NE(old_contents, - browser()->tab_strip_model()->GetActiveWebContents()); + EXPECT_NE(old_contents, browser()->tab_strip_model()->GetActiveWebContents()); EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents(), params.navigated_or_inserted_contents); EXPECT_EQ(2, browser()->tab_strip_model()->count()); @@ -400,8 +398,8 @@ Disposition_IncompatibleWindow_Existing) { // Open a foreground tab in a window that cannot open popups when there is an // existing compatible window somewhere else that they can be opened within. - Browser* popup = CreateEmptyBrowserForType(Browser::TYPE_POPUP, - browser()->profile()); + Browser* popup = + CreateEmptyBrowserForType(Browser::TYPE_POPUP, browser()->profile()); NavigateParams params(MakeNavigateParams(popup)); params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; Navigate(¶ms); @@ -433,8 +431,7 @@ // need a different profile, and creating a popup window with an incognito // profile is a quick and dirty way of achieving this. Browser* popup = CreateEmptyBrowserForType( - Browser::TYPE_POPUP, - browser()->profile()->GetOffTheRecordProfile()); + Browser::TYPE_POPUP, browser()->profile()->GetOffTheRecordProfile()); NavigateParams params(MakeNavigateParams(popup)); params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; Navigate(¶ms); @@ -558,8 +555,7 @@ // This test verifies that navigating with WindowOpenDisposition = NEW_POPUP // from an app popup results in a new Browser also of TYPE_POPUP. -IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, - Disposition_NewPopupFromAppPopup) { +IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewPopupFromAppPopup) { Browser* app_browser = CreateEmptyBrowserForApp(browser()->profile()); // Open an app popup. NavigateParams params1(MakeNavigateParams(app_browser)); @@ -630,7 +626,6 @@ EXPECT_TRUE(params.browser->is_trusted_source()); } - // This test verifies that navigating with WindowOpenDisposition = NEW_WINDOW // always opens a new window. IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_NewWindow) { @@ -1026,9 +1021,8 @@ // This test verifies that navigating with WindowOpenDisposition = INCOGNITO // reuses an existing incognito window when possible. IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, Disposition_IncognitoRefocus) { - Browser* incognito_browser = - CreateEmptyBrowserForType(Browser::TYPE_TABBED, - browser()->profile()->GetOffTheRecordProfile()); + Browser* incognito_browser = CreateEmptyBrowserForType( + Browser::TYPE_TABBED, browser()->profile()->GetOffTheRecordProfile()); NavigateParams params(MakeNavigateParams()); params.disposition = WindowOpenDisposition::OFF_THE_RECORD; Navigate(¶ms); @@ -1204,9 +1198,10 @@ EXPECT_EQ(browser(), params.browser); EXPECT_EQ(3, browser()->tab_strip_model()->count()); EXPECT_EQ(2, browser()->tab_strip_model()->active_index()); - EXPECT_EQ(GetContentSettingsURL(), - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + GetContentSettingsURL(), + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } // This test verifies that constructing params with disposition = SINGLETON_TAB @@ -1238,9 +1233,10 @@ EXPECT_EQ(browser(), params.browser); EXPECT_EQ(3, browser()->tab_strip_model()->count()); EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); - EXPECT_EQ(GetContentSettingsURL(), - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + GetContentSettingsURL(), + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } // This test verifies that constructing params with disposition = SINGLETON_TAB @@ -1272,9 +1268,10 @@ EXPECT_EQ(browser(), params.browser); EXPECT_EQ(3, browser()->tab_strip_model()->count()); EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); - EXPECT_EQ(GetClearBrowsingDataURL(), - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + GetClearBrowsingDataURL(), + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } // This test verifies that constructing params with disposition = SINGLETON_TAB @@ -1304,9 +1301,10 @@ EXPECT_EQ(browser(), params.browser); EXPECT_EQ(2, browser()->tab_strip_model()->count()); EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); - EXPECT_EQ(singleton_url_target, - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + singleton_url_target, + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } // This test verifies that constructing params with disposition = SINGLETON_TAB @@ -1384,9 +1382,10 @@ } EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); - EXPECT_EQ(GetSettingsURL(), - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + GetSettingsURL(), + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } // Settings page is expected to always open in normal mode regardless @@ -1450,9 +1449,10 @@ observer.Wait(); } EXPECT_EQ(1, browser()->tab_strip_model()->count()); - EXPECT_EQ(GetSettingsURL(), - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + GetSettingsURL(), + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, @@ -1469,9 +1469,10 @@ observer.Wait(); } EXPECT_EQ(1, browser()->tab_strip_model()->count()); - EXPECT_EQ(GetSettingsURL(), - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + GetSettingsURL(), + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, @@ -1491,9 +1492,10 @@ observer.Wait(); } EXPECT_EQ(1, browser()->tab_strip_model()->count()); - EXPECT_EQ(GetSettingsURL(), - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + GetSettingsURL(), + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, @@ -1513,9 +1515,10 @@ observer.Wait(); } EXPECT_EQ(2, browser()->tab_strip_model()->count()); - EXPECT_EQ(GetSettingsURL(), - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + GetSettingsURL(), + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, @@ -1540,9 +1543,10 @@ observer.Wait(); } EXPECT_EQ(2, browser()->tab_strip_model()->count()); - EXPECT_EQ(GetSettingsURL(), - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + GetSettingsURL(), + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, @@ -1597,9 +1601,10 @@ ShowSettings(browser()); EXPECT_EQ(2, browser()->tab_strip_model()->count()); - EXPECT_EQ(GetSettingsURL(), - ShortenUberURL(browser()->tab_strip_model()-> - GetActiveWebContents()->GetURL())); + EXPECT_EQ( + GetSettingsURL(), + ShortenUberURL( + browser()->tab_strip_model()->GetActiveWebContents()->GetURL())); } IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, CloseSingletonTab) { @@ -1645,10 +1650,10 @@ // TODO(linux_aura) http://crbug.com/163931 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) #define MAYBE_NavigateFromDefaultToBookmarksInSameTab \ - DISABLED_NavigateFromDefaultToBookmarksInSameTab + DISABLED_NavigateFromDefaultToBookmarksInSameTab #else #define MAYBE_NavigateFromDefaultToBookmarksInSameTab \ - NavigateFromDefaultToBookmarksInSameTab + NavigateFromDefaultToBookmarksInSameTab #endif IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, MAYBE_NavigateFromDefaultToBookmarksInSameTab) { @@ -1679,8 +1684,7 @@ browser()->tab_strip_model()->GetActiveWebContents()->GetURL()); } -IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, - NavigateWithoutBrowser) { +IN_PROC_BROWSER_TEST_F(BrowserNavigatorTest, NavigateWithoutBrowser) { // First navigate using the profile of the existing browser window, and // check that the window is reused. NavigateParams params(browser()->profile(), GetGoogleURL(),
diff --git a/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc b/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc index 5052dc6..d545e09 100644 --- a/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc +++ b/chrome/browser/ui/browser_navigator_browsertest_chromeos.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/browser_navigator_browsertest.h" - #include "ash/public/cpp/window_properties.h" #include "ash/public/interfaces/window_pin_type.mojom.h" #include "base/command_line.h" @@ -13,6 +11,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/browser_navigator_browsertest.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" @@ -106,17 +105,15 @@ } // Subclass that tests navigation while in the Guest session. -class BrowserGuestSessionNavigatorTest: public BrowserNavigatorTest { +class BrowserGuestSessionNavigatorTest : public BrowserNavigatorTest { protected: void SetUpCommandLine(base::CommandLine* command_line) override { base::CommandLine command_line_copy = *command_line; - command_line_copy.AppendSwitchASCII( - chromeos::switches::kLoginProfile, "user"); + command_line_copy.AppendSwitchASCII(chromeos::switches::kLoginProfile, + "user"); command_line_copy.AppendSwitch(chromeos::switches::kGuestSession); - chromeos::GetOffTheRecordCommandLine(GetGoogleURL(), - true, - command_line_copy, - command_line); + chromeos::GetOffTheRecordCommandLine(GetGoogleURL(), true, + command_line_copy, command_line); } }; @@ -142,9 +139,9 @@ EXPECT_NE(browser(), params.browser); EXPECT_EQ(incognito_browser, params.browser); EXPECT_EQ(2, incognito_browser->tab_strip_model()->count()); - EXPECT_EQ(GURL("chrome://chrome/settings"), - incognito_browser->tab_strip_model()->GetActiveWebContents()-> - GetURL()); + EXPECT_EQ( + GURL("chrome://chrome/settings"), + incognito_browser->tab_strip_model()->GetActiveWebContents()->GetURL()); } // Test that in multi user environments a newly created browser gets created
diff --git a/chrome/browser/ui/browser_navigator_params.h b/chrome/browser/ui/browser_navigator_params.h index 88dc7eeb..7e46721 100644 --- a/chrome/browser/ui/browser_navigator_params.h +++ b/chrome/browser/ui/browser_navigator_params.h
@@ -31,7 +31,7 @@ class RenderFrameHost; class WebContents; struct OpenURLParams; -} +} // namespace content // Parameters that tell Navigate() what to do. //
diff --git a/chrome/browser/ui/browser_otr_state_android.cc b/chrome/browser/ui/browser_otr_state_android.cc index 526f228..3a1eb86 100644 --- a/chrome/browser/ui/browser_otr_state_android.cc +++ b/chrome/browser/ui/browser_otr_state_android.cc
@@ -2,9 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/browser_otr_state.h" - #include "chrome/browser/ui/android/tab_model/tab_model_list.h" +#include "chrome/browser/ui/browser_otr_state.h" namespace chrome {
diff --git a/chrome/browser/ui/browser_tab_strip_model_delegate.cc b/chrome/browser/ui/browser_tab_strip_model_delegate.cc index 189a628f..fa4dccfa 100644 --- a/chrome/browser/ui/browser_tab_strip_model_delegate.cc +++ b/chrome/browser/ui/browser_tab_strip_model_delegate.cc
@@ -34,12 +34,9 @@ // BrowserTabStripModelDelegate, public: BrowserTabStripModelDelegate::BrowserTabStripModelDelegate(Browser* browser) - : browser_(browser), - weak_factory_(this) { -} + : browser_(browser), weak_factory_(this) {} -BrowserTabStripModelDelegate::~BrowserTabStripModelDelegate() { -} +BrowserTabStripModelDelegate::~BrowserTabStripModelDelegate() {} //////////////////////////////////////////////////////////////////////////////// // BrowserTabStripModelDelegate, TabStripModelDelegate implementation: @@ -96,8 +93,9 @@ int BrowserTabStripModelDelegate::GetDragActions() const { return TabStripModelDelegate::TAB_TEAROFF_ACTION | - (browser_->tab_strip_model()->count() > 1 - ? TabStripModelDelegate::TAB_MOVE_ACTION : 0); + (browser_->tab_strip_model()->count() > 1 + ? TabStripModelDelegate::TAB_MOVE_ACTION + : 0); } bool BrowserTabStripModelDelegate::CanDuplicateContentsAt(int index) {
diff --git a/chrome/browser/ui/browser_tabrestore.cc b/chrome/browser/ui/browser_tabrestore.cc index eecb1eb..055965a 100644 --- a/chrome/browser/ui/browser_tabrestore.cc +++ b/chrome/browser/ui/browser_tabrestore.cc
@@ -23,9 +23,9 @@ #include "content/public/browser/session_storage_namespace.h" #include "content/public/browser/web_contents.h" +using content::NavigationEntry; using content::RestoreType; using content::WebContents; -using content::NavigationEntry; using sessions::ContentSerializedNavigationBuilder; using sessions::SerializedNavigationEntry; @@ -70,8 +70,7 @@ WebContents* base_web_contents = browser->tab_strip_model()->GetActiveWebContents(); if (base_web_contents) { - create_params.initial_size = - base_web_contents->GetContainerBounds().size(); + create_params.initial_size = base_web_contents->GetContainerBounds().size(); } std::unique_ptr<WebContents> web_contents = WebContents::CreateWithSessionStorage(create_params, @@ -113,8 +112,7 @@ from_last_session, last_active_time, session_storage_namespace, user_agent_override, !select, from_session_restore); - int add_types = select ? TabStripModel::ADD_ACTIVE - : TabStripModel::ADD_NONE; + int add_types = select ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE; if (pin) { tab_index = std::min( tab_index, browser->tab_strip_model()->IndexOfFirstNonPinnedTab());
diff --git a/chrome/browser/ui/browser_tabrestore.h b/chrome/browser/ui/browser_tabrestore.h index 8311ed21..451ead1 100644 --- a/chrome/browser/ui/browser_tabrestore.h +++ b/chrome/browser/ui/browser_tabrestore.h
@@ -15,7 +15,7 @@ namespace content { class SessionStorageNamespace; class WebContents; -} +} // namespace content namespace sessions { class SerializedNavigationEntry;
diff --git a/chrome/browser/ui/browser_tabrestore_browsertest.cc b/chrome/browser/ui/browser_tabrestore_browsertest.cc index d5c2064..fb8846b8 100644 --- a/chrome/browser/ui/browser_tabrestore_browsertest.cc +++ b/chrome/browser/ui/browser_tabrestore_browsertest.cc
@@ -32,7 +32,8 @@ for (int i = 0; i < tab_strip_model->count(); ++i) { content::WebContents* contents = tab_strip_model->GetWebContentsAt(i); std::string document_visibility_state; - const char kGetStateJS[] = "window.domAutomationController.send(" + const char kGetStateJS[] = + "window.domAutomationController.send(" "window.document.visibilityState);"; EXPECT_TRUE(content::ExecuteScriptAndExtractString( contents, kGetStateJS, &document_visibility_state)); @@ -45,7 +46,8 @@ } void CreateTestTabs(Browser* browser) { - GURL test_page(ui_test_utils::GetTestUrl(base::FilePath(), + GURL test_page(ui_test_utils::GetTestUrl( + base::FilePath(), base::FilePath(FILE_PATH_LITERAL("tab-restore-visibility.html")))); ui_test_utils::NavigateToURLWithDisposition( browser, test_page, WindowOpenDisposition::NEW_FOREGROUND_TAB, @@ -75,8 +77,7 @@ content::DOMMessageQueue queue; Browser* browser = active_browser_list->get(0); RecentTabsSubMenuModel menu(nullptr, browser); - menu.ExecuteCommand( - RecentTabsSubMenuModel::GetFirstRecentTabsCommandId(), 0); + menu.ExecuteCommand(RecentTabsSubMenuModel::GetFirstRecentTabsCommandId(), 0); AwaitTabsReady(&queue, 2); // There should be 3 restored tabs in the new browser.
diff --git a/chrome/browser/ui/browser_tabstrip.cc b/chrome/browser/ui/browser_tabstrip.cc index 4aff3ef..43ffee3 100644 --- a/chrome/browser/ui/browser_tabstrip.cc +++ b/chrome/browser/ui/browser_tabstrip.cc
@@ -41,10 +41,9 @@ core_tab_helper->set_new_tab_start_time(new_tab_start_time); } -content::WebContents* AddSelectedTabWithURL( - Browser* browser, - const GURL& url, - ui::PageTransition transition) { +content::WebContents* AddSelectedTabWithURL(Browser* browser, + const GURL& url, + ui::PageTransition transition) { NavigateParams params(browser, url, transition); params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB; Navigate(¶ms); @@ -83,9 +82,8 @@ } browser->tab_strip_model()->CloseWebContentsAt( - index, - add_to_history ? TabStripModel::CLOSE_CREATE_HISTORICAL_TAB - : TabStripModel::CLOSE_NONE); + index, add_to_history ? TabStripModel::CLOSE_CREATE_HISTORICAL_TAB + : TabStripModel::CLOSE_NONE); } } // namespace chrome
diff --git a/chrome/browser/ui/browser_ui_prefs.cc b/chrome/browser/ui/browser_ui_prefs.cc index fd2e2a1b..41be29e 100644 --- a/chrome/browser/ui/browser_ui_prefs.cc +++ b/chrome/browser/ui/browser_ui_prefs.cc
@@ -50,10 +50,8 @@ } void RegisterBrowserUserPrefs(user_prefs::PrefRegistrySyncable* registry) { - registry->RegisterBooleanPref( - prefs::kHomePageIsNewTabPage, - true, - GetHomeButtonAndHomePageIsNewTabPageFlags()); + registry->RegisterBooleanPref(prefs::kHomePageIsNewTabPage, true, + GetHomeButtonAndHomePageIsNewTabPageFlags()); registry->RegisterBooleanPref(prefs::kShowHomeButton, false, GetHomeButtonAndHomePageIsNewTabPageFlags()); @@ -77,8 +75,7 @@ registry->RegisterDictionaryPref(prefs::kBrowserWindowPlacementPopup); registry->RegisterDictionaryPref(prefs::kAppWindowPlacement); registry->RegisterBooleanPref( - prefs::kEnableDoNotTrack, - false, + prefs::kEnableDoNotTrack, false, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID) registry->RegisterBooleanPref(prefs::kPrintPreviewUseSystemDefaultPrinter, @@ -115,8 +112,7 @@ // that use this preference. registry->RegisterBooleanPref(prefs::kShowUpdatePromotionInfoBar, true); registry->RegisterBooleanPref( - prefs::kShowFullscreenToolbar, - true, + prefs::kShowFullscreenToolbar, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); registry->RegisterBooleanPref( prefs::kAllowJavascriptAppleEvents, false,
diff --git a/chrome/browser/ui/browser_unittest.cc b/chrome/browser/ui/browser_unittest.cc index 06802f6..61f33a3 100644 --- a/chrome/browser/ui/browser_unittest.cc +++ b/chrome/browser/ui/browser_unittest.cc
@@ -135,8 +135,8 @@ WebContentsTester::For(raw_contents)->NavigateAndCommit(GURL("about:blank")); zoom::ZoomController* zoom_controller = zoom::ZoomController::FromWebContents(raw_contents); - EXPECT_TRUE(zoom_controller->SetZoomLevel(zoom_controller-> - GetDefaultZoomLevel())); + EXPECT_TRUE( + zoom_controller->SetZoomLevel(zoom_controller->GetDefaultZoomLevel())); CommandUpdater* command_updater = browser()->command_controller(); @@ -275,15 +275,15 @@ protected: BookmarkBar::State window_bookmark_bar_state() const { - return static_cast<BookmarkBarStateTestBrowserWindow*>( - browser()->window())->bookmark_bar_state(); + return static_cast<BookmarkBarStateTestBrowserWindow*>(browser()->window()) + ->bookmark_bar_state(); } // BrowserWithTestWindowTest: void SetUp() override { BrowserWithTestWindowTest::SetUp(); - static_cast<BookmarkBarStateTestBrowserWindow*>( - browser()->window())->set_browser(browser()); + static_cast<BookmarkBarStateTestBrowserWindow*>(browser()->window()) + ->set_browser(browser()); } BrowserWindow* CreateBrowserWindow() override { @@ -294,8 +294,7 @@ class BookmarkBarStateTestBrowserWindow : public TestBrowserWindow { public: BookmarkBarStateTestBrowserWindow() - : browser_(NULL), - bookmark_bar_state_(BookmarkBar::HIDDEN) {} + : browser_(NULL), bookmark_bar_state_(BookmarkBar::HIDDEN) {} ~BookmarkBarStateTestBrowserWindow() override {} void set_browser(Browser* browser) { browser_ = browser; }
diff --git a/chrome/browser/ui/browser_window.h b/chrome/browser/ui/browser_window.h index 2773d42..c040125 100644 --- a/chrome/browser/ui/browser_window.h +++ b/chrome/browser/ui/browser_window.h
@@ -50,18 +50,18 @@ class LocalCardMigrationBubble; class SaveCardBubbleController; class SaveCardBubbleView; -} +} // namespace autofill namespace content { class WebContents; struct NativeWebKeyboardEvent; enum class KeyboardEventProcessingResult; -} +} // namespace content namespace extensions { class Command; class Extension; -} +} // namespace extensions namespace gfx { class Size; @@ -410,7 +410,7 @@ // modal dialogs within the browser window. This can sometimes be NULL (for // instance during tab drag on Views/Win32). virtual web_modal::WebContentsModalDialogHost* - GetWebContentsModalDialogHost() = 0; + GetWebContentsModalDialogHost() = 0; // Construct a BrowserWindow implementation for the specified |browser|. static BrowserWindow* CreateBrowserWindow(std::unique_ptr<Browser> browser,
diff --git a/chrome/browser/ui/browser_window_state.cc b/chrome/browser/ui/browser_window_state.cc index 175d95ae..d741811b 100644 --- a/chrome/browser/ui/browser_window_state.cc +++ b/chrome/browser/ui/browser_window_state.cc
@@ -76,8 +76,8 @@ std::string GetWindowName(const Browser* browser) { if (browser->app_name().empty()) { - return browser->is_type_popup() ? - prefs::kBrowserWindowPlacementPopup : prefs::kBrowserWindowPlacement; + return browser->is_type_popup() ? prefs::kBrowserWindowPlacementPopup + : prefs::kBrowserWindowPlacement; } return browser->app_name(); } @@ -114,7 +114,8 @@ // Only save the window placement of popups if the window is from a trusted // source (v1 app, devtools, or system window). return (browser->type() == Browser::TYPE_TABBED) || - ((browser->type() == Browser::TYPE_POPUP) && browser->is_trusted_source()); + ((browser->type() == Browser::TYPE_POPUP) && + browser->is_trusted_source()); } bool SavedBoundsAreContentBounds(const Browser* browser) { @@ -151,11 +152,8 @@ DCHECK(bounds); DCHECK(show_state); *bounds = browser->override_bounds(); - WindowSizer::GetBrowserWindowBoundsAndShowState(browser->app_name(), - *bounds, - browser, - bounds, - show_state); + WindowSizer::GetBrowserWindowBoundsAndShowState(browser->app_name(), *bounds, + browser, bounds, show_state); const base::CommandLine& parsed_command_line = *base::CommandLine::ForCurrentProcess();
diff --git a/chrome/browser/ui/browser_window_state.h b/chrome/browser/ui/browser_window_state.h index 49b4534..a4e782d 100644 --- a/chrome/browser/ui/browser_window_state.h +++ b/chrome/browser/ui/browser_window_state.h
@@ -16,7 +16,7 @@ namespace base { class CommandLine; class DictionaryValue; -} +} // namespace base namespace gfx { class Rect;
diff --git a/chrome/browser/ui/certificate_dialogs.cc b/chrome/browser/ui/certificate_dialogs.cc index 780867d..2f4d0fa0 100644 --- a/chrome/browser/ui/certificate_dialogs.cc +++ b/chrome/browser/ui/certificate_dialogs.cc
@@ -42,12 +42,12 @@ void WriterCallback(const base::FilePath& path, const std::string& data) { int bytes_written = base::WriteFile(path, data.data(), data.size()); if (bytes_written != static_cast<ssize_t>(data.size())) { - LOG(ERROR) << "Writing " << path.value() << " (" - << data.size() << "B) returned " << bytes_written; + LOG(ERROR) << "Writing " << path.value() << " (" << data.size() + << "B) returned " << bytes_written; } } -std::string WrapAt64(const std::string &str) { +std::string WrapAt64(const std::string& str) { std::string result; for (size_t i = 0; i < str.size(); i += 64) { result.append(str, i, 64); // Append clamps the len arg internally. @@ -62,9 +62,8 @@ return std::string(); std::string base64; base::Base64Encode(der_cert, &base64); - return "-----BEGIN CERTIFICATE-----\r\n" + - WrapAt64(base64) + - "-----END CERTIFICATE-----\r\n"; + return "-----BEGIN CERTIFICATE-----\r\n" + WrapAt64(base64) + + "-----END CERTIFICATE-----\r\n"; } //////////////////////////////////////////////////////////////////////////////// @@ -127,7 +126,8 @@ select_file_dialog_->ListenerDestroyed(); } -void Exporter::FileSelected(const base::FilePath& path, int index, +void Exporter::FileSelected(const base::FilePath& path, + int index, void* params) { std::string data; switch (index - 1) { @@ -142,8 +142,8 @@ data = x509_certificate_model::GetCMSString(cert_chain_list_, 0, 1); break; case kPkcs7Chain: - data = x509_certificate_model::GetCMSString( - cert_chain_list_, 0, cert_chain_list_.size()); + data = x509_certificate_model::GetCMSString(cert_chain_list_, 0, + cert_chain_list_.size()); break; case kBase64: default: @@ -191,11 +191,9 @@ l10n_util::GetStringUTF16(IDS_CERT_EXPORT_TYPE_PKCS7_CHAIN)); file_type_info.include_all_files = true; select_file_dialog->SelectFile( - type, base::string16(), - suggested_path, &file_type_info, + type, base::string16(), suggested_path, &file_type_info, 1, // 1-based index for |file_type_info.extensions| to specify default. - FILE_PATH_LITERAL("crt"), - parent, params); + FILE_PATH_LITERAL("crt"), parent, params); } void ShowCertExportDialog(content::WebContents* web_contents,
diff --git a/chrome/browser/ui/chrome_bubble_manager.cc b/chrome/browser/ui/chrome_bubble_manager.cc index eb2ae5a..ae074c8b 100644 --- a/chrome/browser/ui/chrome_bubble_manager.cc +++ b/chrome/browser/ui/chrome_bubble_manager.cc
@@ -154,7 +154,8 @@ } void ChromeBubbleManager::DidToggleFullscreenModeForTab( - bool entered_fullscreen, bool will_cause_resize) { + bool entered_fullscreen, + bool will_cause_resize) { CloseAllBubbles(BUBBLE_CLOSE_FULLSCREEN_TOGGLED); // Any bubble that didn't close should update its anchor position. UpdateAllBubbleAnchors(); @@ -172,7 +173,8 @@ } void ChromeBubbleManager::ChromeBubbleMetrics::OnBubbleClosed( - BubbleReference bubble, BubbleCloseReason reason) { + BubbleReference bubble, + BubbleCloseReason reason) { // Log the amount of time the bubble was visible. base::TimeDelta visible_time = bubble->GetVisibleTime(); UMA_HISTOGRAM_LONG_TIMES("Bubbles.DisplayTime.All", visible_time);
diff --git a/chrome/browser/ui/chrome_pages.cc b/chrome/browser/ui/chrome_pages.cc index d8c619d5..2e631b6 100644 --- a/chrome/browser/ui/chrome_pages.cc +++ b/chrome/browser/ui/chrome_pages.cc
@@ -275,7 +275,6 @@ return url.SchemeIs(scheme); } - void ShowSettings(Browser* browser) { ShowSettingsSubPage(browser, std::string()); }
diff --git a/chrome/browser/ui/chrome_select_file_policy.cc b/chrome/browser/ui/chrome_select_file_policy.cc index b842531..b9bc0b80 100644 --- a/chrome/browser/ui/chrome_select_file_policy.cc +++ b/chrome/browser/ui/chrome_select_file_policy.cc
@@ -18,8 +18,7 @@ ChromeSelectFilePolicy::ChromeSelectFilePolicy( content::WebContents* source_contents) - : source_contents_(source_contents) { -} + : source_contents_(source_contents) {} ChromeSelectFilePolicy::~ChromeSelectFilePolicy() {}
diff --git a/chrome/browser/ui/chrome_select_file_policy_unittest.cc b/chrome/browser/ui/chrome_select_file_policy_unittest.cc index 3b32d13..8171d00 100644 --- a/chrome/browser/ui/chrome_select_file_policy_unittest.cc +++ b/chrome/browser/ui/chrome_select_file_policy_unittest.cc
@@ -22,7 +22,8 @@ #if defined(USE_AURA) // http://crbug.com/105200 -#define MAYBE_ExpectAsynchronousListenerCall DISABLED_ExpectAsynchronousListenerCall +#define MAYBE_ExpectAsynchronousListenerCall \ + DISABLED_ExpectAsynchronousListenerCall #else #define MAYBE_ExpectAsynchronousListenerCall ExpectAsynchronousListenerCall #endif @@ -31,9 +32,7 @@ class FileSelectionUser : public ui::SelectFileDialog::Listener { public: - FileSelectionUser() - : file_selection_initialisation_in_progress(false) { - } + FileSelectionUser() : file_selection_initialisation_in_progress(false) {} ~FileSelectionUser() override { if (select_file_dialog_.get()) @@ -50,13 +49,8 @@ file_selection_initialisation_in_progress = true; select_file_dialog_->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE, - title, - file_path, - NULL, - 0, - base::FilePath::StringType(), - NULL, - NULL); + title, file_path, NULL, 0, + base::FilePath::StringType(), NULL, NULL); file_selection_initialisation_in_progress = false; } @@ -89,8 +83,7 @@ TEST_F(ChromeSelectFilePolicyTest, MAYBE_ExpectAsynchronousListenerCall) { content::TestBrowserThreadBundle test_browser_thread_bundle; - ScopedTestingLocalState local_state( - TestingBrowserProcess::GetGlobal()); + ScopedTestingLocalState local_state(TestingBrowserProcess::GetGlobal()); std::unique_ptr<FileSelectionUser> file_selection_user( new FileSelectionUser());
diff --git a/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc b/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc index 33fd605..64d1639 100644 --- a/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc +++ b/chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.cc
@@ -7,11 +7,9 @@ #include "chrome/browser/platform_util.h" #include "content/public/browser/web_contents.h" -ChromeWebModalDialogManagerDelegate::ChromeWebModalDialogManagerDelegate() { -} +ChromeWebModalDialogManagerDelegate::ChromeWebModalDialogManagerDelegate() {} -ChromeWebModalDialogManagerDelegate::~ChromeWebModalDialogManagerDelegate() { -} +ChromeWebModalDialogManagerDelegate::~ChromeWebModalDialogManagerDelegate() {} bool ChromeWebModalDialogManagerDelegate::IsWebContentsVisible( content::WebContents* web_contents) {
diff --git a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.h b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.h index aab52b7..da3f60c 100644 --- a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.h +++ b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.h
@@ -29,6 +29,12 @@ // True if the current page is starred. Used by star touch bar button. @property(nonatomic, assign) BOOL isStarred; +// True if the back button is enabled. +@property(nonatomic, assign) BOOL canGoBack; + +// True if the forward button is enabled. +@property(nonatomic, assign) BOOL canGoForward; + // Designated initializer. - (instancetype)initWithBrowser:(Browser*)browser controller:(BrowserWindowTouchBarController*)controller; @@ -38,10 +44,6 @@ - (void)updateWebContents:(content::WebContents*)contents; -// Updates the back/forward button. Called when creating the touch bar or when -// the back and forward commands have changed. -- (void)updateBackForwardControl; - - (BrowserWindowTouchBarController*)controller; @end @@ -49,6 +51,11 @@ // Private methods exposed for testing. @interface BrowserWindowDefaultTouchBar (ExposedForTesting) +@property(readonly, class) NSString* reloadOrStopItemIdentifier; +@property(readonly, class) NSString* backItemIdentifier; +@property(readonly, class) NSString* forwardItemIdentifier; +@property(readonly, class) NSString* fullscreenOriginItemIdentifier; + // Updates the reload/stop button. Called when creating the touch bar or the // page load state has been updated. - (void)updateReloadStopButton; @@ -56,10 +63,6 @@ // Returns the reload/stop button on the touch bar. Creates it if it's null. - (NSButton*)reloadStopButton; -// Returns the back/forward segmented control on the touch bar. Creates it if -// it's null. -- (NSSegmentedControl*)backForwardControl; - // Returns the bridge object that BrowserWindowDefaultTouchBar uses to receive // notifications. - (BookmarkTabHelperObserver*)bookmarkTabObserver;
diff --git a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.mm b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.mm index 84099212..d4f5f37 100644 --- a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.mm +++ b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar.mm
@@ -51,7 +51,8 @@ NSString* const kTabFullscreenTouchBarId = @"tab-fullscreen"; // Touch bar items identifiers. -NSString* const kBackForwardTouchId = @"BACK-FWD"; +NSString* const kBackTouchId = @"BACK"; +NSString* const kForwardTouchId = @"FORWARD"; NSString* const kReloadOrStopTouchId = @"RELOAD-STOP"; NSString* const kHomeTouchId = @"HOME"; NSString* const kSearchTouchId = @"SEARCH"; @@ -59,9 +60,11 @@ NSString* const kNewTabTouchId = @"NEW-TAB"; NSString* const kFullscreenOriginLabelTouchId = @"FULLSCREEN-ORIGIN-LABEL"; -// The button indexes in the back and forward segment control. -const int kBackSegmentIndex = 0; -const int kForwardSegmentIndex = 1; +// This is a combined back and forward control which can no longer be selected +// but may be in an existing customized Touch Bar. It now represents a group +// containing the back and forward buttons, and adding the back or forward +// buttons to the Touch Bar individually magically decomposes the group. +NSString* const kBackForwardTouchId = @"BACK-FWD"; // Touch bar icon colors values. const SkColor kTouchBarDefaultIconColor = SK_ColorWHITE; @@ -95,7 +98,7 @@ target:owner action:@selector(executeCommand:)]; button.tag = command; - [button setAccessibilityLabel:l10n_util::GetNSString(tooltip_id)]; + button.accessibilityTitle = l10n_util::GetNSString(tooltip_id); return button; } @@ -176,7 +179,10 @@ // CommandObserver: void EnabledStateChangedForCommand(int command, bool enabled) override { DCHECK(command == IDC_BACK || command == IDC_FORWARD); - [owner_ updateBackForwardControl]; + if (command == IDC_BACK) + owner_.canGoBack = enabled; + else if (command == IDC_FORWARD) + owner_.canGoForward = enabled; } // WebContentsObserver: @@ -203,10 +209,6 @@ DISALLOW_COPY_AND_ASSIGN(TouchBarNotificationBridge); }; -id<NSAccessibility> ToNSAccessibility(id object) { - return [object conformsToProtocol:@protocol(NSAccessibility)] ? object : nil; -} - } // namespace @interface BrowserWindowDefaultTouchBar () { @@ -230,9 +232,6 @@ // The stop/reload button in the touch bar. base::scoped_nsobject<NSButton> reloadStopButton_; - // The back/forward segmented control in the touch bar. - base::scoped_nsobject<NSSegmentedControl> backForwardControl_; - // The starred button in the touch bar. base::scoped_nsobject<NSButton> starredButton_; } @@ -240,9 +239,6 @@ // Creates and returns a touch bar for tab fullscreen mode. - (NSTouchBar*)createTabFullscreenTouchBar; -// Sets up the back and forward segmented control. -- (void)setupBackForwardControl; - // Updates the starred button in the touch bar. - (void)updateStarredButton; @@ -255,6 +251,8 @@ @synthesize isPageLoading = isPageLoading_; @synthesize isStarred = isStarred_; +@synthesize canGoBack = canGoBack_; +@synthesize canGoForward = canGoForward_; - (instancetype)initWithBrowser:(Browser*)browser controller:(BrowserWindowTouchBarController*)controller { @@ -266,8 +264,12 @@ notificationBridge_.reset(new TouchBarNotificationBridge(self, browser)); commandUpdater_ = browser->command_controller(); + commandUpdater_->AddCommandObserver(IDC_BACK, notificationBridge_.get()); + self.canGoBack = commandUpdater_->IsCommandEnabled(IDC_BACK); + commandUpdater_->AddCommandObserver(IDC_FORWARD, notificationBridge_.get()); + self.canGoForward = commandUpdater_->IsCommandEnabled(IDC_FORWARD); PrefService* prefs = browser->profile()->GetPrefs(); showHomeButton_.Init( @@ -301,12 +303,12 @@ setCustomizationIdentifier:ui::GetTouchBarId(kBrowserWindowTouchBarId)]; [touchBar setDelegate:self]; - NSMutableArray* customIdentifiers = [NSMutableArray arrayWithCapacity:7]; - NSMutableArray* defaultIdentifiers = [NSMutableArray arrayWithCapacity:6]; + NSMutableArray<NSString*>* customIdentifiers = [NSMutableArray array]; + NSMutableArray<NSString*>* defaultIdentifiers = [NSMutableArray array]; - NSArray* touchBarItems = @[ - kBackForwardTouchId, kReloadOrStopTouchId, kHomeTouchId, kSearchTouchId, - kStarTouchId, kNewTabTouchId + NSArray<NSString*>* touchBarItems = @[ + kBackTouchId, kForwardTouchId, kReloadOrStopTouchId, kHomeTouchId, + kSearchTouchId, kStarTouchId, kNewTabTouchId ]; for (NSString* item in touchBarItems) { @@ -332,14 +334,41 @@ if (!touchBar) return nil; + if ([identifier hasSuffix:kBackForwardTouchId]) { + auto* items = @[ + [touchBar itemForIdentifier:ui::GetTouchBarItemId( + kBrowserWindowTouchBarId, kBackTouchId)], + [touchBar + itemForIdentifier:ui::GetTouchBarItemId(kBrowserWindowTouchBarId, + kForwardTouchId)], + ]; + auto groupItem = [NSGroupTouchBarItem groupItemWithIdentifier:identifier + items:items]; + [groupItem setCustomizationLabel: + l10n_util::GetNSString( + IDS_TOUCH_BAR_BACK_FORWARD_CUSTOMIZATION_LABEL)]; + return groupItem; + } + base::scoped_nsobject<NSCustomTouchBarItem> touchBarItem( [[ui::NSCustomTouchBarItem() alloc] initWithIdentifier:identifier]); - if ([identifier hasSuffix:kBackForwardTouchId]) { - [self updateBackForwardControl]; - [touchBarItem setView:backForwardControl_.get()]; - [touchBarItem setCustomizationLabel: - l10n_util::GetNSString( - IDS_TOUCH_BAR_BACK_FORWARD_CUSTOMIZATION_LABEL)]; + if ([identifier hasSuffix:kBackTouchId]) { + auto* button = CreateTouchBarButton(vector_icons::kBackArrowIcon, self, + IDC_BACK, IDS_ACCNAME_BACK); + [button bind:@"enabled" toObject:self withKeyPath:@"canGoBack" options:nil]; + [touchBarItem setView:button]; + [touchBarItem + setCustomizationLabel:l10n_util::GetNSString(IDS_ACCNAME_BACK)]; + } else if ([identifier hasSuffix:kForwardTouchId]) { + auto* button = CreateTouchBarButton(vector_icons::kForwardArrowIcon, self, + IDC_FORWARD, IDS_ACCNAME_FORWARD); + [button bind:@"enabled" + toObject:self + withKeyPath:@"canGoForward" + options:nil]; + [touchBarItem setView:button]; + [touchBarItem + setCustomizationLabel:l10n_util::GetNSString(IDS_ACCNAME_FORWARD)]; } else if ([identifier hasSuffix:kReloadOrStopTouchId]) { [self updateReloadStopButton]; [touchBarItem setView:reloadStopButton_.get()]; @@ -398,6 +427,8 @@ [touchBarItem setView:[NSTextField labelWithAttributedString:attributedString.get()]]; + } else { + return nil; } return touchBarItem.autorelease(); @@ -412,63 +443,10 @@ return touchBar.autorelease(); } -- (void)setupBackForwardControl { - NSMutableArray* images = [NSMutableArray arrayWithArray:@[ - CreateNSImageFromIcon(vector_icons::kBackArrowIcon), - CreateNSImageFromIcon(vector_icons::kForwardArrowIcon) - ]]; - - // Offset the icons so that it matches the height of the other Touch Bar - // items. - const int kIconYOffset = 2; - for (NSUInteger i = 0; i < [images count]; i++) { - NSImage* image = [images objectAtIndex:i]; - NSSize size = [image size]; - size.height += kIconYOffset; - - NSImage* offsettedImage = [[[NSImage alloc] initWithSize:size] autorelease]; - [offsettedImage lockFocus]; - [image drawInRect:NSMakeRect(0, 0, size.width, size.height - kIconYOffset)]; - [offsettedImage unlockFocus]; - [images replaceObjectAtIndex:i withObject:offsettedImage]; - } - - NSSegmentedControl* control = [NSSegmentedControl - segmentedControlWithImages:images - trackingMode:NSSegmentSwitchTrackingMomentary - target:self - action:@selector(backOrForward:)]; - - // Use the accessibility protocol to get the children. - // Use NSAccessibilityUnignoredDescendant to be sure we start with - // the correct object. - id<NSAccessibility> segmentElement = - ToNSAccessibility(NSAccessibilityUnignoredDescendant(control)); - DCHECK(segmentElement); - NSArray<id<NSAccessibility>>* segments = segmentElement.accessibilityChildren; - ToNSAccessibility(segments[0]).accessibilityTitle = - l10n_util::GetNSString(IDS_ACCNAME_BACK); - ToNSAccessibility(segments[1]).accessibilityTitle = - l10n_util::GetNSString(IDS_ACCNAME_FORWARD); - - backForwardControl_.reset([control retain]); -} - - (void)updateWebContents:(content::WebContents*)contents { notificationBridge_->UpdateWebContents(contents); } -- (void)updateBackForwardControl { - if (!backForwardControl_) - [self setupBackForwardControl]; - - [backForwardControl_ setSegmentStyle:NSSegmentStyleSeparated]; - [backForwardControl_ setEnabled:commandUpdater_->IsCommandEnabled(IDC_BACK) - forSegment:kBackSegmentIndex]; - [backForwardControl_ setEnabled:commandUpdater_->IsCommandEnabled(IDC_FORWARD) - forSegment:kForwardSegmentIndex]; -} - - (void)updateStarredButton { const gfx::VectorIcon& icon = isStarred_ ? omnibox::kStarActiveIcon : omnibox::kStarIcon; @@ -532,14 +510,6 @@ return searchButton; } -- (void)backOrForward:(id)sender { - NSSegmentedControl* control = sender; - int command = - [control selectedSegment] == kBackSegmentIndex ? IDC_BACK : IDC_FORWARD; - LogTouchBarUMA(TouchBarActionFromCommand(command)); - commandUpdater_->ExecuteCommand(command); -} - - (void)executeCommand:(id)sender { int command = [sender tag]; ui::LogTouchBarUMA(TouchBarActionFromCommand(command)); @@ -561,6 +531,23 @@ // Private methods exposed for testing. @implementation BrowserWindowDefaultTouchBar (ExposedForTesting) ++ (NSString*)reloadOrStopItemIdentifier { + return ui::GetTouchBarItemId(kBrowserWindowTouchBarId, kReloadOrStopTouchId); +} + ++ (NSString*)backItemIdentifier { + return ui::GetTouchBarItemId(kBrowserWindowTouchBarId, kBackTouchId); +} + ++ (NSString*)forwardItemIdentifier { + return ui::GetTouchBarItemId(kBrowserWindowTouchBarId, kForwardTouchId); +} + ++ (NSString*)fullscreenOriginItemIdentifier { + return ui::GetTouchBarItemId(kTabFullscreenTouchBarId, + kFullscreenOriginLabelTouchId); +} + - (void)updateReloadStopButton { const gfx::VectorIcon& icon = isPageLoading_ ? kNavigateStopIcon : vector_icons::kReloadIcon; @@ -586,13 +573,6 @@ return reloadStopButton_.get(); } -- (NSSegmentedControl*)backForwardControl { - if (!backForwardControl_) - [self updateBackForwardControl]; - - return backForwardControl_.get(); -} - - (BookmarkTabHelperObserver*)bookmarkTabObserver { return notificationBridge_.get(); }
diff --git a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm index ec36da0d..7f679ff 100644 --- a/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm +++ b/chrome/browser/ui/cocoa/touchbar/browser_window_default_touch_bar_unittest.mm
@@ -18,33 +18,14 @@ #include "chrome/common/pref_names.h" #include "components/prefs/pref_service.h" #include "components/strings/grit/components_strings.h" +#include "content/public/test/test_renderer_host.h" +#include "content/public/test/web_contents_tester.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" #import "third_party/ocmock/OCMock/OCMock.h" #import "ui/base/cocoa/touch_bar_util.h" #include "ui/base/l10n/l10n_util_mac.h" -namespace { - -// Touch bar identifiers. -NSString* const kBrowserWindowTouchBarId = @"browser-window"; -NSString* const kTabFullscreenTouchBarId = @"tab-fullscreen"; - -// Touch bar items identifiers. -NSString* const kBackForwardTouchId = @"BACK-FWD"; -NSString* const kReloadOrStopTouchId = @"RELOAD-STOP"; -NSString* const kHomeTouchId = @"HOME"; -NSString* const kSearchTouchId = @"SEARCH"; -NSString* const kStarTouchId = @"BOOKMARK"; -NSString* const kNewTabTouchId = @"NEW-TAB"; -NSString* const kFullscreenOriginLabelTouchId = @"FULLSCREEN-ORIGIN-LABEL"; - -// The button indexes in the back and forward segment control. -const int kBackSegmentIndex = 0; -const int kForwardSegmentIndex = 1; - -} // namespace - class BrowserWindowDefaultTouchBarUnitTest : public CocoaProfileTest { public: void SetUp() override { @@ -53,6 +34,10 @@ command_updater_ = browser()->command_controller(); + browser()->tab_strip_model()->AppendWebContents( + content::WebContentsTester::CreateTestWebContents(profile(), nullptr), + true); + if (@available(macOS 10.12.2, *)) { touch_bar_.reset([[BrowserWindowDefaultTouchBar alloc] initWithBrowser:browser() @@ -60,68 +45,107 @@ } } - NSString* GetFullscreenTouchBarItemId(NSString* id) { - return ui::GetTouchBarItemId(kTabFullscreenTouchBarId, id); - } - - NSString* GetBrowserTouchBarItemId(NSString* id) { - return ui::GetTouchBarItemId(kBrowserWindowTouchBarId, id); - } - void UpdateCommandEnabled(int id, bool enabled) { command_updater_->UpdateCommandEnabled(id, enabled); } void TearDown() override { - if (@available(macOS 10.12.2, *)) + if (@available(macOS 10.12.2, *)) { + [touch_bar_ updateWebContents:nullptr]; touch_bar_.reset(); + } CocoaProfileTest::TearDown(); } CommandUpdater* command_updater_; // Weak, owned by Browser. + content::RenderViewHostTestEnabler rvh_test_enabler_; API_AVAILABLE(macos(10.12.2)) base::scoped_nsobject<BrowserWindowDefaultTouchBar> touch_bar_; }; -// Tests to check if the touch bar contains the correct items. +// Test if any known identifiers no longer work. See the message in the test; +// these identifiers may be written out to disk on users' computers if they +// customize the Touch Bar, and the corresponding items will disappear if they +// can no longer be created. +TEST_F(BrowserWindowDefaultTouchBarUnitTest, HistoricTouchBarItems) { + if (@available(macOS 10.12.2, *)) { + NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; + for (NSString* item_identifier : { + @"BACK-FWD", + @"BACK", + @"FORWARD", + @"RELOAD-STOP", + @"HOME", + @"SEARCH", + @"BOOKMARK", + @"NEW-TAB", + }) { + auto identifier = + ui::GetTouchBarItemId(@"browser-window", item_identifier); + EXPECT_NE(nil, [touch_bar itemForIdentifier:identifier]) + << "BrowserWindowDefaultTouchBar didn't return a Touch Bar item for " + "an identifier that was once available (" + << identifier.UTF8String + << "). If a user's customized Touch Bar includes this item, it will " + "disappear! Do not update or remove entries in this list just to " + "make the test pass; keep supporting old identifiers when " + "possible, even if they're no longer part of the set of " + "default/customizable items."; + } + } +} + +// Tests if BrowserWindowDefaultTouchBar can produce the items it says it can +// and, for each kind of bar, also verify that the advertised/customizable lists +// include some representative items (if not, the lists might be wrong.) TEST_F(BrowserWindowDefaultTouchBarUnitTest, TouchBarItems) { if (@available(macOS 10.12.2, *)) { + auto test_default_identifiers = + [&](NSSet* expected_identifiers) API_AVAILABLE(macos(10.12.2)) { + NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; + NSMutableSet<NSString*>* advertised_identifiers = [NSMutableSet set]; + [advertised_identifiers + addObjectsFromArray:touch_bar.defaultItemIdentifiers]; + [advertised_identifiers + addObjectsFromArray:touch_bar + .customizationAllowedItemIdentifiers]; + [advertised_identifiers + addObjectsFromArray:touch_bar + .customizationRequiredItemIdentifiers]; + EXPECT_TRUE( + [expected_identifiers isSubsetOfSet:advertised_identifiers]) + << "Didn't find the expected identifiers " + << expected_identifiers.description.UTF8String + << " in the set of advertised identifiers " + << advertised_identifiers.description.UTF8String << "."; + for (NSString* identifier in advertised_identifiers) { + EXPECT_NE(nil, [touch_bar itemForIdentifier:identifier]) + << "Didn't get a touch bar item for " << identifier.UTF8String; + } + }; + // Set to tab fullscreen. FullscreenController* fullscreen_controller = browser()->exclusive_access_manager()->fullscreen_controller(); fullscreen_controller->set_is_tab_fullscreen_for_testing(true); EXPECT_TRUE(fullscreen_controller->IsTabFullscreen()); - // The touch bar should only contain an item that displays the origin of the - // tab content fullscreen. - NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; - NSArray* touch_bar_items = [touch_bar itemIdentifiers]; - EXPECT_TRUE( - [touch_bar_items containsObject:GetFullscreenTouchBarItemId( - kFullscreenOriginLabelTouchId)]); - EXPECT_EQ(1u, [touch_bar_items count]); + // The fullscreen Touch Bar should include *at least* these items. + test_default_identifiers([NSSet setWithArray:@[ + BrowserWindowDefaultTouchBar.fullscreenOriginItemIdentifier, + ]]); // Exit fullscreen. fullscreen_controller->set_is_tab_fullscreen_for_testing(false); EXPECT_FALSE(fullscreen_controller->IsTabFullscreen()); - PrefService* prefs = profile()->GetPrefs(); - DCHECK(prefs); - prefs->SetBoolean(prefs::kShowHomeButton, true); - touch_bar_items = [[touch_bar_ makeTouchBar] itemIdentifiers]; - EXPECT_TRUE([touch_bar_items - containsObject:GetBrowserTouchBarItemId(kBackForwardTouchId)]); - EXPECT_TRUE([touch_bar_items - containsObject:GetBrowserTouchBarItemId(kReloadOrStopTouchId)]); - EXPECT_TRUE([touch_bar_items - containsObject:GetBrowserTouchBarItemId(kHomeTouchId)]); - EXPECT_TRUE([touch_bar_items - containsObject:GetBrowserTouchBarItemId(kSearchTouchId)]); - EXPECT_TRUE([touch_bar_items - containsObject:GetBrowserTouchBarItemId(kStarTouchId)]); - EXPECT_TRUE([touch_bar_items - containsObject:GetBrowserTouchBarItemId(kNewTabTouchId)]); + // The default Touch Bar should include *at least* these items. + test_default_identifiers([NSSet setWithArray:@[ + BrowserWindowDefaultTouchBar.backItemIdentifier, + BrowserWindowDefaultTouchBar.forwardItemIdentifier, + BrowserWindowDefaultTouchBar.reloadOrStopItemIdentifier, + ]]); } } @@ -131,56 +155,69 @@ NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; [touch_bar_ setIsPageLoading:NO]; - NSTouchBarItem* item = [touch_bar_ - touchBar:touch_bar - makeItemForIdentifier:GetBrowserTouchBarItemId(kReloadOrStopTouchId)]; + NSTouchBarItem* item = + [touch_bar itemForIdentifier:BrowserWindowDefaultTouchBar + .reloadOrStopItemIdentifier]; EXPECT_EQ(IDC_RELOAD, [[item view] tag]); [touch_bar_ setIsPageLoading:YES]; - item = [touch_bar_ touchBar:touch_bar - makeItemForIdentifier:GetBrowserTouchBarItemId(kReloadOrStopTouchId)]; + item = [touch_bar itemForIdentifier:BrowserWindowDefaultTouchBar + .reloadOrStopItemIdentifier]; EXPECT_EQ(IDC_STOP, [[item view] tag]); } } -// Tests to see if the back/forward items on the touch bar is in sync with the -// back and forward commands. -TEST_F(BrowserWindowDefaultTouchBarUnitTest, BackForwardCommandUpdate) { +// Tests if the back button on the touch bar is in sync with the back command. +TEST_F(BrowserWindowDefaultTouchBarUnitTest, BackCommandUpdate) { if (@available(macOS 10.12.2, *)) { - NSSegmentedControl* back_forward_control = [touch_bar_ backForwardControl]; + NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; + NSTouchBarItem* item = [touch_bar + itemForIdentifier:BrowserWindowDefaultTouchBar.backItemIdentifier]; + NSButton* button = base::mac::ObjCCast<NSButton>(item.view); UpdateCommandEnabled(IDC_BACK, true); - UpdateCommandEnabled(IDC_FORWARD, true); - EXPECT_TRUE([back_forward_control isEnabledForSegment:kBackSegmentIndex]); - EXPECT_TRUE( - [back_forward_control isEnabledForSegment:kForwardSegmentIndex]); - + EXPECT_TRUE(button.enabled); UpdateCommandEnabled(IDC_BACK, false); - EXPECT_FALSE([back_forward_control isEnabledForSegment:kBackSegmentIndex]); - EXPECT_TRUE( - [back_forward_control isEnabledForSegment:kForwardSegmentIndex]); - - UpdateCommandEnabled(IDC_FORWARD, false); - EXPECT_FALSE([back_forward_control isEnabledForSegment:kBackSegmentIndex]); - EXPECT_FALSE( - [back_forward_control isEnabledForSegment:kForwardSegmentIndex]); + EXPECT_FALSE(button.enabled); } } -TEST_F(BrowserWindowDefaultTouchBarUnitTest, BackForwardAccessibilityLabels) { +// Tests if the forward button on the touch bar is in sync with the forward +// command. +TEST_F(BrowserWindowDefaultTouchBarUnitTest, ForwardCommandUpdate) { if (@available(macOS 10.12.2, *)) { - NSSegmentedControl* control = touch_bar_.get().backForwardControl; - id<NSAccessibility> cell = NSAccessibilityUnignoredDescendant(control); - ASSERT_TRUE([cell conformsToProtocol:@protocol(NSAccessibility)]); + NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; + NSTouchBarItem* item = [touch_bar + itemForIdentifier:BrowserWindowDefaultTouchBar.forwardItemIdentifier]; + NSButton* button = base::mac::ObjCCast<NSButton>(item.view); - id<NSAccessibility> back = cell.accessibilityChildren[0]; - EXPECT_TRUE([back conformsToProtocol:@protocol(NSAccessibility)]); - EXPECT_NSEQ(back.accessibilityTitle, + UpdateCommandEnabled(IDC_FORWARD, true); + EXPECT_TRUE(button.enabled); + UpdateCommandEnabled(IDC_FORWARD, false); + EXPECT_FALSE(button.enabled); + } +} + +TEST_F(BrowserWindowDefaultTouchBarUnitTest, BackAccessibilityLabel) { + if (@available(macOS 10.12.2, *)) { + NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; + NSTouchBarItem* item = [touch_bar + itemForIdentifier:BrowserWindowDefaultTouchBar.backItemIdentifier]; + id<NSAccessibility> view = item.view; + ASSERT_TRUE([view conformsToProtocol:@protocol(NSAccessibility)]); + EXPECT_NSEQ(view.accessibilityTitle, l10n_util::GetNSString(IDS_ACCNAME_BACK)); + } +} - id<NSAccessibility> forward = cell.accessibilityChildren[1]; - EXPECT_TRUE([forward conformsToProtocol:@protocol(NSAccessibility)]); - EXPECT_NSEQ(forward.accessibilityTitle, +TEST_F(BrowserWindowDefaultTouchBarUnitTest, ForwardAccessibilityLabel) { + if (@available(macOS 10.12.2, *)) { + NSTouchBar* touch_bar = [touch_bar_ makeTouchBar]; + NSTouchBarItem* item = [touch_bar + itemForIdentifier:BrowserWindowDefaultTouchBar.forwardItemIdentifier]; + id<NSAccessibility> view = item.view; + ASSERT_TRUE([view conformsToProtocol:@protocol(NSAccessibility)]); + EXPECT_NSEQ(view.accessibilityTitle, l10n_util::GetNSString(IDS_ACCNAME_FORWARD)); } }
diff --git a/chrome/browser/ui/collected_cookies_browsertest.cc b/chrome/browser/ui/collected_cookies_browsertest.cc index 71e509f..8fc4ee63 100644 --- a/chrome/browser/ui/collected_cookies_browsertest.cc +++ b/chrome/browser/ui/collected_cookies_browsertest.cc
@@ -66,6 +66,6 @@ ShowUi(std::string()); // Navigate to another page. - ui_test_utils::NavigateToURL( - browser(), embedded_test_server()->GetURL("/cookie2.html")); + ui_test_utils::NavigateToURL(browser(), + embedded_test_server()->GetURL("/cookie2.html")); }
diff --git a/chrome/browser/ui/collected_cookies_infobar_delegate.cc b/chrome/browser/ui/collected_cookies_infobar_delegate.cc index 0feb0af..0318da1 100644 --- a/chrome/browser/ui/collected_cookies_infobar_delegate.cc +++ b/chrome/browser/ui/collected_cookies_infobar_delegate.cc
@@ -21,11 +21,9 @@ } CollectedCookiesInfoBarDelegate::CollectedCookiesInfoBarDelegate() - : ConfirmInfoBarDelegate() { -} + : ConfirmInfoBarDelegate() {} -CollectedCookiesInfoBarDelegate::~CollectedCookiesInfoBarDelegate() { -} +CollectedCookiesInfoBarDelegate::~CollectedCookiesInfoBarDelegate() {} infobars::InfoBarDelegate::InfoBarIdentifier CollectedCookiesInfoBarDelegate::GetIdentifier() const {
diff --git a/chrome/browser/ui/color_chooser.h b/chrome/browser/ui/color_chooser.h index 732e8af..4b9fa4d 100644 --- a/chrome/browser/ui/color_chooser.h +++ b/chrome/browser/ui/color_chooser.h
@@ -10,7 +10,7 @@ namespace content { class ColorChooser; class WebContents; -} +} // namespace content namespace chrome { // Shows a color chooser that reports to the given WebContents.
diff --git a/chrome/browser/ui/confirm_bubble_model.cc b/chrome/browser/ui/confirm_bubble_model.cc index e2b860e..1c6e44e 100644 --- a/chrome/browser/ui/confirm_bubble_model.cc +++ b/chrome/browser/ui/confirm_bubble_model.cc
@@ -8,11 +8,9 @@ #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" -ConfirmBubbleModel::ConfirmBubbleModel() { -} +ConfirmBubbleModel::ConfirmBubbleModel() {} -ConfirmBubbleModel::~ConfirmBubbleModel() { -} +ConfirmBubbleModel::~ConfirmBubbleModel() {} int ConfirmBubbleModel::GetButtons() const { return BUTTON_OK | BUTTON_CANCEL; @@ -22,11 +20,9 @@ return l10n_util::GetStringUTF16((button == BUTTON_OK) ? IDS_OK : IDS_CANCEL); } -void ConfirmBubbleModel::Accept() { -} +void ConfirmBubbleModel::Accept() {} -void ConfirmBubbleModel::Cancel() { -} +void ConfirmBubbleModel::Cancel() {} base::string16 ConfirmBubbleModel::GetLinkText() const { return base::string16();
diff --git a/chrome/browser/ui/confirm_bubble_model.h b/chrome/browser/ui/confirm_bubble_model.h index 03a80c52..76c5bc8 100644 --- a/chrome/browser/ui/confirm_bubble_model.h +++ b/chrome/browser/ui/confirm_bubble_model.h
@@ -16,8 +16,8 @@ class ConfirmBubbleModel { public: enum BubbleButton { - BUTTON_NONE = 0, - BUTTON_OK = 1 << 0, + BUTTON_NONE = 0, + BUTTON_OK = 1 << 0, BUTTON_CANCEL = 1 << 1, };
diff --git a/chrome/browser/ui/crypto_module_delegate_nss.cc b/chrome/browser/ui/crypto_module_delegate_nss.cc index 591dc6ba..88f1aef 100644 --- a/chrome/browser/ui/crypto_module_delegate_nss.cc +++ b/chrome/browser/ui/crypto_module_delegate_nss.cc
@@ -33,11 +33,10 @@ if (base::PostTaskWithTraits( FROM_HERE, {BrowserThread::UI}, - base::BindOnce( - &ChromeNSSCryptoModuleDelegate::ShowDialog, - // This method blocks on |event_| until the task completes, - // so there's no need to ref-count. - base::Unretained(this), slot_name, retry))) { + base::BindOnce(&ChromeNSSCryptoModuleDelegate::ShowDialog, + // This method blocks on |event_| until the task + // completes, so there's no need to ref-count. + base::Unretained(this), slot_name, retry))) { event_.Wait(); } *cancelled = cancelled_; @@ -48,10 +47,7 @@ bool retry) { DCHECK_CURRENTLY_ON(BrowserThread::UI); ShowCryptoModulePasswordDialog( - slot_name, - retry, - reason_, - server_.host(), + slot_name, retry, reason_, server_.host(), NULL, // TODO(mattm): Supply parent window. base::Bind(&ChromeNSSCryptoModuleDelegate::GotPassword, // RequestPassword is blocked on |event_| until GotPassword is
diff --git a/chrome/browser/ui/cryptuiapi_shim.h b/chrome/browser/ui/cryptuiapi_shim.h index a6470d90..876753b 100644 --- a/chrome/browser/ui/cryptuiapi_shim.h +++ b/chrome/browser/ui/cryptuiapi_shim.h
@@ -10,8 +10,8 @@ // which undefines the OpenSSL macros which conflict. Any Chromium headers // which want to include cryptuiapi should instead include this header. -#include <windows.h> #include <cryptuiapi.h> +#include <windows.h> #include "base/win/wincrypt_shim.h"
diff --git a/chrome/browser/ui/external_protocol_dialog_delegate.cc b/chrome/browser/ui/external_protocol_dialog_delegate.cc index 5fbb500..8f201e7 100644 --- a/chrome/browser/ui/external_protocol_dialog_delegate.cc +++ b/chrome/browser/ui/external_protocol_dialog_delegate.cc
@@ -33,8 +33,7 @@ render_view_routing_id_(render_view_routing_id), program_name_(shell_integration::GetApplicationNameForProtocol(url)) {} -ExternalProtocolDialogDelegate::~ExternalProtocolDialogDelegate() { -} +ExternalProtocolDialogDelegate::~ExternalProtocolDialogDelegate() {} base::string16 ExternalProtocolDialogDelegate::GetDialogButtonLabel( ui::DialogButton button) const {
diff --git a/chrome/browser/ui/hung_plugin_tab_helper.cc b/chrome/browser/ui/hung_plugin_tab_helper.cc index 047bb6e..25ccf39 100644 --- a/chrome/browser/ui/hung_plugin_tab_helper.cc +++ b/chrome/browser/ui/hung_plugin_tab_helper.cc
@@ -52,7 +52,6 @@ } // namespace - // HungPluginTabHelper::PluginState ------------------------------------------- // Per-plugin state (since there could be more than one plugin hung). The @@ -96,17 +95,14 @@ infobar(NULL), next_reshow_delay(base::TimeDelta::FromSeconds(kInitialReshowDelaySec)) {} -HungPluginTabHelper::PluginState::~PluginState() { -} - +HungPluginTabHelper::PluginState::~PluginState() {} // HungPluginTabHelper -------------------------------------------------------- HungPluginTabHelper::HungPluginTabHelper(content::WebContents* contents) : content::WebContentsObserver(contents), infobar_observer_(this) {} -HungPluginTabHelper::~HungPluginTabHelper() { -} +HungPluginTabHelper::~HungPluginTabHelper() {} void HungPluginTabHelper::PluginCrashed(const base::FilePath& plugin_path, base::ProcessId plugin_pid) { @@ -171,9 +167,8 @@ // Schedule the timer to re-show the infobar if the plugin continues to be // hung. state->timer.Start(FROM_HERE, state->next_reshow_delay, - base::Bind(&HungPluginTabHelper::OnReshowTimer, - base::Unretained(this), - i->first)); + base::BindOnce(&HungPluginTabHelper::OnReshowTimer, + base::Unretained(this), i->first)); // Next time we do this, delay it twice as long to avoid being annoying. state->next_reshow_delay *= 2;
diff --git a/chrome/browser/ui/navigation_correction_tab_observer.cc b/chrome/browser/ui/navigation_correction_tab_observer.cc index 70ca14ac..40256d42 100644 --- a/chrome/browser/ui/navigation_correction_tab_observer.cc +++ b/chrome/browser/ui/navigation_correction_tab_observer.cc
@@ -50,14 +50,12 @@ } } -NavigationCorrectionTabObserver::~NavigationCorrectionTabObserver() { -} +NavigationCorrectionTabObserver::~NavigationCorrectionTabObserver() {} // static void NavigationCorrectionTabObserver::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* prefs) { - prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled, - true, + prefs->RegisterBooleanPref(prefs::kAlternateErrorPagesEnabled, true, user_prefs::PrefRegistrySyncable::SYNCABLE_PREF); }
diff --git a/chrome/browser/ui/network_profile_bubble.cc b/chrome/browser/ui/network_profile_bubble.cc index 155a8c1..0174a14 100644 --- a/chrome/browser/ui/network_profile_bubble.cc +++ b/chrome/browser/ui/network_profile_bubble.cc
@@ -4,9 +4,8 @@ #include "chrome/browser/ui/network_profile_bubble.h" -#include <windows.h> #include <stdint.h> - +#include <windows.h> #include <wtsapi32.h> #include "base/bind.h" @@ -113,8 +112,8 @@ // Checking for RDP is cheaper than checking for a network drive so do this // one first. if (!::WTSQuerySessionInformation(WTS_CURRENT_SERVER, WTS_CURRENT_SESSION, - WTSClientProtocolType, - &buffer, &buffer_length)) { + WTSClientProtocolType, &buffer, + &buffer_length)) { RecordUmaEvent(METRIC_CHECK_FAILED); return; } @@ -167,8 +166,7 @@ // static void NetworkProfileBubble::RecordUmaEvent(MetricNetworkedProfileCheck event) { - UMA_HISTOGRAM_ENUMERATION(kMetricNetworkedProfileCheck, - event, + UMA_HISTOGRAM_ENUMERATION(kMetricNetworkedProfileCheck, event, METRIC_NETWORKED_PROFILE_CHECK_SIZE); }
diff --git a/chrome/browser/ui/network_profile_bubble.h b/chrome/browser/ui/network_profile_bubble.h index d88e813..fac6a906 100644 --- a/chrome/browser/ui/network_profile_bubble.h +++ b/chrome/browser/ui/network_profile_bubble.h
@@ -23,27 +23,27 @@ class NetworkProfileBubble { public: enum MetricNetworkedProfileCheck { - // Check was suppressed by command line flag. - METRIC_CHECK_SUPPRESSED, - // WTSQuerySessionInformation call failed. - METRIC_CHECK_FAILED, - // File access in profile dir failed. - METRIC_CHECK_IO_FAILED, + // Check was suppressed by command line flag. + METRIC_CHECK_SUPPRESSED, + // WTSQuerySessionInformation call failed. + METRIC_CHECK_FAILED, + // File access in profile dir failed. + METRIC_CHECK_IO_FAILED, - // Profile on a network share detected. - METRIC_PROFILE_ON_NETWORK, - // Profile not on a network share detected. - METRIC_PROFILE_NOT_ON_NETWORK, + // Profile on a network share detected. + METRIC_PROFILE_ON_NETWORK, + // Profile not on a network share detected. + METRIC_PROFILE_NOT_ON_NETWORK, - // Check was suppressed because of remote session. - METRIC_REMOTE_SESSION, + // Check was suppressed because of remote session. + METRIC_REMOTE_SESSION, - // User has clicked learn more on the notification bubble. - METRIC_LEARN_MORE_CLICKED, - // User has clicked OK on the notification bubble. - METRIC_ACKNOWLEDGED, + // User has clicked learn more on the notification bubble. + METRIC_LEARN_MORE_CLICKED, + // User has clicked OK on the notification bubble. + METRIC_ACKNOWLEDGED, - METRIC_NETWORKED_PROFILE_CHECK_SIZE // Must be the last. + METRIC_NETWORKED_PROFILE_CHECK_SIZE // Must be the last. }; // Returns true if the check for network located profile should be done. This
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc index 86ca5f5..3597fef 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -35,6 +35,7 @@ #include "components/password_manager/core/browser/password_bubble_experiment.h" #include "components/password_manager/core/browser/password_form_manager_for_ui.h" #include "components/password_manager/core/browser/password_manager_constants.h" +#include "components/password_manager/core/browser/password_ui_utils.h" #include "components/password_manager/core/browser/statistics_table.h" #include "components/password_manager/core/common/credential_manager_types.h" #include "content/public/browser/navigation_handle.h" @@ -390,35 +391,9 @@ void ManagePasswordsUIController::SavePassword(const base::string16& username, const base::string16& password) { - const auto& pending_credentials = - passwords_data_.form_manager()->GetPendingCredentials(); - bool username_edited = pending_credentials.username_value != username; - bool password_changed = pending_credentials.password_value != password; - if (username_edited) { - passwords_data_.form_manager()->UpdateUsername(username); - if (GetPasswordFormMetricsRecorder()) { - GetPasswordFormMetricsRecorder()->RecordDetailedUserAction( - password_manager::PasswordFormMetricsRecorder::DetailedUserAction:: - kEditedUsernameInBubble); - } - } - if (password_changed) { - passwords_data_.form_manager()->UpdatePasswordValue(password); - if (GetPasswordFormMetricsRecorder()) { - GetPasswordFormMetricsRecorder()->RecordDetailedUserAction( - password_manager::PasswordFormMetricsRecorder::DetailedUserAction:: - kSelectedDifferentPasswordInBubble); - } - } + UpdatePasswordFormUsernameAndPassword(username, password, + passwords_data_.form_manager()); - // Values of this histogram are a bit mask. Only the lower two bits are used: - // 0001 to indicate that the user has edited the username in the password - // save bubble. - // 0010 to indicate that the user has changed the password in the password - // save bubble. - // The maximum possible value is defined by OR-ing these values. - UMA_HISTOGRAM_ENUMERATION("PasswordManager.EditsInSaveBubble", - username_edited + 2 * password_changed, 4); UMA_HISTOGRAM_BOOLEAN("PasswordManager.PasswordSavedWithManualFallback", BubbleIsManualFallbackForSaving()); if (GetPasswordFormMetricsRecorder() && BubbleIsManualFallbackForSaving()) {
diff --git a/chrome/browser/ui/platform_keys_certificate_selector_chromeos.h b/chrome/browser/ui/platform_keys_certificate_selector_chromeos.h index cfee8bc..052ddb7f 100644 --- a/chrome/browser/ui/platform_keys_certificate_selector_chromeos.h +++ b/chrome/browser/ui/platform_keys_certificate_selector_chromeos.h
@@ -18,7 +18,7 @@ namespace net { class X509Certificate; typedef std::vector<scoped_refptr<X509Certificate>> CertificateList; -} +} // namespace net namespace chromeos {
diff --git a/chrome/browser/ui/sad_tab.cc b/chrome/browser/ui/sad_tab.cc index 2c24e97..567d7d09 100644 --- a/chrome/browser/ui/sad_tab.cc +++ b/chrome/browser/ui/sad_tab.cc
@@ -266,8 +266,8 @@ UMA_SAD_TAB_COUNTER("Tabs.SadTab.KillCreated.OOM"); { const std::string spec = web_contents->GetURL().GetOrigin().spec(); - memory::OomMemoryDetails::Log( - "Tab OOM-Killed Memory details: " + spec + ", "); + memory::OomMemoryDetails::Log("Tab OOM-Killed Memory details: " + spec + + ", "); } FALLTHROUGH; #endif
diff --git a/chrome/browser/ui/sad_tab_helper.cc b/chrome/browser/ui/sad_tab_helper.cc index 52b80f6e..82496b4 100644 --- a/chrome/browser/ui/sad_tab_helper.cc +++ b/chrome/browser/ui/sad_tab_helper.cc
@@ -30,12 +30,10 @@ } // namespace -SadTabHelper::~SadTabHelper() { -} +SadTabHelper::~SadTabHelper() {} SadTabHelper::SadTabHelper(content::WebContents* web_contents) - : content::WebContentsObserver(web_contents) { -} + : content::WebContentsObserver(web_contents) {} void SadTabHelper::ReinstallInWebView() { if (sad_tab_)
diff --git a/chrome/browser/ui/sad_tab_types.h b/chrome/browser/ui/sad_tab_types.h index f889a4c..44f20a0 100644 --- a/chrome/browser/ui/sad_tab_types.h +++ b/chrome/browser/ui/sad_tab_types.h
@@ -8,12 +8,12 @@ #include "build/build_config.h" enum SadTabKind { - SAD_TAB_KIND_CRASHED, // Tab crashed. + SAD_TAB_KIND_CRASHED, // Tab crashed. #if defined(OS_CHROMEOS) SAD_TAB_KIND_KILLED_BY_OOM, // Tab killed by oom killer. #endif - SAD_TAB_KIND_OOM, // Tab ran out of memory. - SAD_TAB_KIND_KILLED // Tab killed. + SAD_TAB_KIND_OOM, // Tab ran out of memory. + SAD_TAB_KIND_KILLED // Tab killed. }; #endif // CHROME_BROWSER_UI_SAD_TAB_TYPES_H_
diff --git a/chrome/browser/ui/scoped_tabbed_browser_displayer.h b/chrome/browser/ui/scoped_tabbed_browser_displayer.h index bf6bc98..14fa037 100644 --- a/chrome/browser/ui/scoped_tabbed_browser_displayer.h +++ b/chrome/browser/ui/scoped_tabbed_browser_displayer.h
@@ -21,9 +21,7 @@ explicit ScopedTabbedBrowserDisplayer(Profile* profile); ~ScopedTabbedBrowserDisplayer(); - Browser* browser() { - return browser_; - } + Browser* browser() { return browser_; } private: Browser* browser_;
diff --git a/chrome/browser/ui/screen_capture_notification_ui_stub.cc b/chrome/browser/ui/screen_capture_notification_ui_stub.cc index fcef998..92ea27f 100644 --- a/chrome/browser/ui/screen_capture_notification_ui_stub.cc +++ b/chrome/browser/ui/screen_capture_notification_ui_stub.cc
@@ -2,9 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/screen_capture_notification_ui.h" - #include "base/logging.h" +#include "chrome/browser/ui/screen_capture_notification_ui.h" // Stub implementation of the ScreenCaptureNotificationUI interface. class ScreenCaptureNotificationUIStub : public ScreenCaptureNotificationUI {
diff --git a/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc b/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc index fddb40d..e3f58f2 100644 --- a/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc +++ b/chrome/browser/ui/settings_window_manager_browsertest_chromeos.cc
@@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/settings_window_manager_chromeos.h" - #include <stddef.h> #include "base/bind.h" @@ -20,6 +18,7 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" +#include "chrome/browser/ui/settings_window_manager_chromeos.h" #include "chrome/browser/ui/settings_window_manager_observer_chromeos.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/url_constants.h"
diff --git a/chrome/browser/ui/signin_view_controller.h b/chrome/browser/ui/signin_view_controller.h index 3dcd2a3..056192b 100644 --- a/chrome/browser/ui/signin_view_controller.h +++ b/chrome/browser/ui/signin_view_controller.h
@@ -26,7 +26,7 @@ enum class AccessPoint; enum class PromoAction; enum class Reason; -} +} // namespace signin_metrics // Class responsible for showing and hiding all sign-in related UIs // (modal sign-in, DICE full-tab sign-in page, sync confirmation dialog, sign-in @@ -81,7 +81,6 @@ // Sets the height of the modal signin dialog. void SetModalSigninHeight(int height); - // Notifies this object that it's |delegate_| member has become invalid. void ResetModalSigninDelegate();
diff --git a/chrome/browser/ui/simple_message_box.h b/chrome/browser/ui/simple_message_box.h index 7077891..eb86ca9 100644 --- a/chrome/browser/ui/simple_message_box.h +++ b/chrome/browser/ui/simple_message_box.h
@@ -26,8 +26,8 @@ }; enum MessageBoxType { - MESSAGE_BOX_TYPE_WARNING, // Shows an OK button. - MESSAGE_BOX_TYPE_QUESTION, // Shows YES and NO buttons. + MESSAGE_BOX_TYPE_WARNING, // Shows an OK button. + MESSAGE_BOX_TYPE_QUESTION, // Shows YES and NO buttons. }; // Shows a dialog box with the given |title| and |message|. If |parent| is
diff --git a/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc b/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc index de392c0..3333339a 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_corrupt_profiles_browsertest_win.cc
@@ -418,8 +418,9 @@ return RemoveCreateDirectoryPermissionForUserDataDirectory(); } +// Flaky: https://crbug.com/951787 IN_PROC_BROWSER_TEST_F(StartupBrowserCreatorCorruptProfileTest, - DeletedProfileFallbackToUserManager) { + DISABLED_DeletedProfileFallbackToUserManager) { CheckBrowserWindows({}); ExpectUserManagerToShow(); }
diff --git a/chrome/browser/ui/tab_dialogs.cc b/chrome/browser/ui/tab_dialogs.cc index 64c6569..90c1ccf 100644 --- a/chrome/browser/ui/tab_dialogs.cc +++ b/chrome/browser/ui/tab_dialogs.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "chrome/browser/ui/tab_dialogs.h" + #include "content/public/browser/web_contents.h" namespace {
diff --git a/chrome/browser/ui/tab_dialogs.h b/chrome/browser/ui/tab_dialogs.h index 5a53144c..c54feea 100644 --- a/chrome/browser/ui/tab_dialogs.h +++ b/chrome/browser/ui/tab_dialogs.h
@@ -18,7 +18,7 @@ namespace content { class RenderWidgetHost; class WebContents; -} +} // namespace content namespace ui { class ProfileSigninConfirmationDelegate;
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 4a5e070d..a2c8e8f 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -320,12 +320,12 @@ } #endif -// --- Feature tab helpers behind flags --- + // --- Feature tab helpers behind flags --- #if BUILDFLAG(ENABLE_OFFLINE_PAGES) -offline_pages::OfflinePageTabHelper::CreateForWebContents(web_contents); -offline_pages::RecentTabHelper::CreateForWebContents(web_contents); -offline_pages::AutoFetchPageLoadWatcher::CreateForWebContents(web_contents); + offline_pages::OfflinePageTabHelper::CreateForWebContents(web_contents); + offline_pages::RecentTabHelper::CreateForWebContents(web_contents); + offline_pages::AutoFetchPageLoadWatcher::CreateForWebContents(web_contents); #endif #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION)
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc index 5e7902ac2..bb56ae9 100644 --- a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc +++ b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.cc
@@ -22,12 +22,9 @@ MockTabModalConfirmDialogDelegate::MockTabModalConfirmDialogDelegate( content::WebContents* web_contents, Delegate* delegate) - : TabModalConfirmDialogDelegate(web_contents), - delegate_(delegate) { -} + : TabModalConfirmDialogDelegate(web_contents), delegate_(delegate) {} -MockTabModalConfirmDialogDelegate::~MockTabModalConfirmDialogDelegate() { -} +MockTabModalConfirmDialogDelegate::~MockTabModalConfirmDialogDelegate() {} base::string16 MockTabModalConfirmDialogDelegate::GetTitle() { return base::string16(); @@ -57,8 +54,7 @@ dialog_(NULL), accepted_count_(0), canceled_count_(0), - closed_count_(0) { -} + closed_count_(0) {} void TabModalConfirmDialogTest::SetUpOnMainThread() { delegate_ = new MockTabModalConfirmDialogDelegate(
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h index 3c111623..dd259cdb 100644 --- a/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h +++ b/chrome/browser/ui/tab_modal_confirm_dialog_browsertest.h
@@ -18,6 +18,7 @@ virtual void OnAccepted() = 0; virtual void OnCanceled() = 0; virtual void OnClosed() = 0; + protected: virtual ~Delegate() {} };
diff --git a/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc b/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc index b7f8591d..e032634 100644 --- a/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc +++ b/chrome/browser/ui/tab_modal_confirm_dialog_delegate.cc
@@ -16,8 +16,7 @@ TabModalConfirmDialogDelegate::TabModalConfirmDialogDelegate( WebContents* web_contents) - : close_delegate_(NULL), - closing_(false) { + : close_delegate_(NULL), closing_(false) { NavigationController* controller = &web_contents->GetController(); registrar_.Add(this, content::NOTIFICATION_LOAD_START, content::Source<NavigationController>(controller)); @@ -100,18 +99,14 @@ return NULL; } -void TabModalConfirmDialogDelegate::OnAccepted() { -} +void TabModalConfirmDialogDelegate::OnAccepted() {} -void TabModalConfirmDialogDelegate::OnCanceled() { -} +void TabModalConfirmDialogDelegate::OnCanceled() {} void TabModalConfirmDialogDelegate::OnLinkClicked( - WindowOpenDisposition disposition) { -} + WindowOpenDisposition disposition) {} -void TabModalConfirmDialogDelegate::OnClosed() { -} +void TabModalConfirmDialogDelegate::OnClosed() {} void TabModalConfirmDialogDelegate::CloseDialog() { if (close_delegate_)
diff --git a/chrome/browser/ui/uma_browsing_activity_observer.cc b/chrome/browser/ui/uma_browsing_activity_observer.cc index 0e526234..a2b94fc 100644 --- a/chrome/browser/ui/uma_browsing_activity_observer.cc +++ b/chrome/browser/ui/uma_browsing_activity_observer.cc
@@ -38,13 +38,12 @@ UMABrowsingActivityObserver::UMABrowsingActivityObserver() { registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, - content::NotificationService::AllSources()); + content::NotificationService::AllSources()); registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, - content::NotificationService::AllSources()); + content::NotificationService::AllSources()); } -UMABrowsingActivityObserver::~UMABrowsingActivityObserver() { -} +UMABrowsingActivityObserver::~UMABrowsingActivityObserver() {} void UMABrowsingActivityObserver::Observe( int type, @@ -55,7 +54,7 @@ *content::Details<content::LoadCommittedDetails>(details).ptr(); content::NavigationController* controller = - content::Source<content::NavigationController>(source).ptr(); + content::Source<content::NavigationController>(source).ptr(); // Track whether the page loaded is a search results page (SRP). Track // the non-SRP navigations as well so there is a control. base::RecordAction(base::UserMetricsAction("NavEntryCommitted")); @@ -65,8 +64,8 @@ // See http://crbug.com/291348. CHECK(load.entry); if (TemplateURLServiceFactory::GetForProfile( - Profile::FromBrowserContext(controller->GetBrowserContext()))-> - IsSearchResultsPageFromDefaultSearchProvider( + Profile::FromBrowserContext(controller->GetBrowserContext())) + ->IsSearchResultsPageFromDefaultSearchProvider( load.entry->GetURL())) { base::RecordAction(base::UserMetricsAction("NavEntryCommitted.SRP")); } @@ -85,11 +84,10 @@ void UMABrowsingActivityObserver::LogRenderProcessHostCount() const { int hosts_count = 0; for (content::RenderProcessHost::iterator i( - content::RenderProcessHost::AllHostsIterator()); - !i.IsAtEnd(); i.Advance()) + content::RenderProcessHost::AllHostsIterator()); + !i.IsAtEnd(); i.Advance()) ++hosts_count; - UMA_HISTOGRAM_CUSTOM_COUNTS("MPArch.RPHCountPerLoad", hosts_count, - 1, 50, 50); + UMA_HISTOGRAM_CUSTOM_COUNTS("MPArch.RPHCountPerLoad", hosts_count, 1, 50, 50); } void UMABrowsingActivityObserver::LogBrowserTabCount() const { @@ -100,15 +98,15 @@ for (auto* browser : *BrowserList::GetInstance()) { // Record how many tabs each window has open. UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountPerWindow", - browser->tab_strip_model()->count(), - 1, 200, 50); + browser->tab_strip_model()->count(), 1, 200, + 50); tab_count += browser->tab_strip_model()->count(); if (browser->window()->IsActive()) { // Record how many tabs the active window has open. UMA_HISTOGRAM_CUSTOM_COUNTS("Tabs.TabCountActiveWindow", - browser->tab_strip_model()->count(), - 1, 200, 50); + browser->tab_strip_model()->count(), 1, 200, + 50); } if (browser->is_app())
diff --git a/chrome/browser/ui/unload_controller.cc b/chrome/browser/ui/unload_controller.cc index 4fcc174..4e5fcfa3 100644 --- a/chrome/browser/ui/unload_controller.cc +++ b/chrome/browser/ui/unload_controller.cc
@@ -45,7 +45,7 @@ if (is_attempting_to_close_browser_) ClearUnloadState(contents, true); return !is_attempting_to_close_browser_ || - is_calling_before_unload_handlers(); + is_calling_before_unload_handlers(); } bool UnloadController::ShouldRunUnloadEventsHelper( @@ -194,7 +194,8 @@ for (int i = 0; i < browser_->tab_strip_model()->count(); ++i) { content::WebContents* contents = browser_->tab_strip_model()->GetWebContentsAt(i); - bool should_fire_beforeunload = contents->NeedToFireBeforeUnload() || + bool should_fire_beforeunload = + contents->NeedToFireBeforeUnload() || DevToolsWindow::NeedsToInterceptBeforeUnload(contents); if (!ContainsKey(tabs_needing_unload_fired_, contents) && should_fire_beforeunload) { @@ -286,17 +287,14 @@ void UnloadController::TabAttachedImpl(content::WebContents* contents) { // If the tab crashes in the beforeunload or unload handler, it won't be // able to ack. But we know we can close it. - registrar_.Add( - this, - content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, - content::Source<content::WebContents>(contents)); + registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, + content::Source<content::WebContents>(contents)); } void UnloadController::TabDetachedImpl(content::WebContents* contents) { if (is_attempting_to_close_browser_) ClearUnloadState(contents, false); - registrar_.Remove(this, - content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, + registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DISCONNECTED, content::Source<content::WebContents>(contents)); } @@ -374,8 +372,8 @@ bool UnloadController::HasCompletedUnloadProcessing() const { return is_attempting_to_close_browser_ && - tabs_needing_before_unload_fired_.empty() && - tabs_needing_unload_fired_.empty(); + tabs_needing_before_unload_fired_.empty() && + tabs_needing_unload_fired_.empty(); } bool UnloadController::RemoveFromSet(UnloadListenerSet* set,
diff --git a/chrome/browser/ui/unload_controller.h b/chrome/browser/ui/unload_controller.h index b100a1f..f067acc 100644 --- a/chrome/browser/ui/unload_controller.h +++ b/chrome/browser/ui/unload_controller.h
@@ -22,7 +22,7 @@ class NotificationSource; class NotificationDetails; class WebContents; -} +} // namespace content class UnloadController : public content::NotificationObserver, public TabStripModelObserver {
diff --git a/chrome/browser/ui/views/profiles/profile_chooser_view.cc b/chrome/browser/ui/views/profiles/profile_chooser_view.cc index 7bb98e17..135ba56 100644 --- a/chrome/browser/ui/views/profiles/profile_chooser_view.cc +++ b/chrome/browser/ui/views/profiles/profile_chooser_view.cc
@@ -51,6 +51,7 @@ #include "services/identity/public/cpp/primary_account_mutator.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/image/canvas_image_source.h" #include "ui/gfx/image/image_skia_operations.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/views/controls/button/label_button.h" @@ -99,6 +100,27 @@ Navigate(¶ms); } +#if defined(GOOGLE_CHROME_BUILD) +// Returns the Google G icon in grey and with a padding of 2. The padding is +// needed to make the icon look smaller, otherwise it looks too big compared to +// the other icons. See crbug.com/951751 for more information. +gfx::ImageSkia GetGoogleIconForUserMenu(int icon_size) { + constexpr int kIconPadding = 2; + SkColor icon_color = + ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor( + ui::NativeTheme::kColorId_DefaultIconColor); + // |CreateVectorIcon()| doesn't override colors specified in the .icon file, + // therefore the image has to be colored manually with |CreateColorMask()|. + gfx::ImageSkia google_icon = gfx::CreateVectorIcon( + kGoogleGLogoIcon, icon_size - 2 * kIconPadding, gfx::kPlaceholderColor); + gfx::ImageSkia grey_google_icon = + gfx::ImageSkiaOperations::CreateColorMask(google_icon, icon_color); + + return gfx::CanvasImageSource::CreatePadded(grey_google_icon, + gfx::Insets(kIconPadding)); +} +#endif + } // namespace // ProfileChooserView --------------------------------------------------------- @@ -894,24 +916,13 @@ #if defined(GOOGLE_CHROME_BUILD) void ProfileChooserView::AddManageGoogleAccountButton() { - ProfileMenuViewBase::MenuItems menu_items; - - SkColor icon_color = - ui::NativeTheme::GetInstanceForNativeUi()->GetSystemColor( - ui::NativeTheme::kColorId_DefaultIconColor); - // |CreateVectorIcon()| doesn't override colors specified in the .icon file, - // therefore the image has to be colored manually with |CreateColorMask()|. - gfx::ImageSkia google_logo = gfx::CreateVectorIcon( - kGoogleGLogoIcon, GetDefaultIconSize(), gfx::kPlaceholderColor); - gfx::ImageSkia grey_google_logo = - gfx::ImageSkiaOperations::CreateColorMask(google_logo, icon_color); - std::unique_ptr<HoverButton> button = std::make_unique<HoverButton>( - this, grey_google_logo, + this, GetGoogleIconForUserMenu(GetDefaultIconSize()), l10n_util::GetStringUTF16(IDS_SETTINGS_MANAGE_GOOGLE_ACCOUNT)); manage_google_account_button_ = button.get(); - menu_items.push_back(std::move(button)); + ProfileMenuViewBase::MenuItems menu_items; + menu_items.push_back(std::move(button)); AddMenuItems(menu_items, /*new_group=*/false); } #endif
diff --git a/chrome/browser/ui/views/tabs/tab_strip.cc b/chrome/browser/ui/views/tabs/tab_strip.cc index 9580e58..444b883 100644 --- a/chrome/browser/ui/views/tabs/tab_strip.cc +++ b/chrome/browser/ui/views/tabs/tab_strip.cc
@@ -2668,7 +2668,7 @@ const int pinned_tab_count = GetPinnedTabCount(); const int normal_count = tab_count() - pinned_tab_count; - if (normal_count <= 1 || normal_count == pinned_tab_count) + if (normal_count <= 1) return false; const int tab_overlap = TabStyle::GetTabOverlap();
diff --git a/chrome/browser/ui/web_app_browser_controller.cc b/chrome/browser/ui/web_app_browser_controller.cc index f58fad2..1d80cb3c 100644 --- a/chrome/browser/ui/web_app_browser_controller.cc +++ b/chrome/browser/ui/web_app_browser_controller.cc
@@ -3,7 +3,6 @@ // found in the LICENSE file. #include "chrome/browser/ui/web_app_browser_controller.h" -#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/extension_util.h" @@ -12,6 +11,7 @@ #include "chrome/browser/ssl/security_state_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h" #include "chrome/browser/ui/location_bar/location_bar.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/web_applications/components/web_app_helpers.h"
diff --git a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc index eb22e97..e3026c0 100644 --- a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc +++ b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.cc
@@ -22,8 +22,9 @@ #include "base/strings/stringprintf.h" #include "base/task/post_task.h" #include "base/values.h" -#include "chrome/browser/chromeos/arc/tracing/arc_cpu_model.h" #include "chrome/browser/chromeos/arc/tracing/arc_graphics_jank_detector.h" +#include "chrome/browser/chromeos/arc/tracing/arc_system_model.h" +#include "chrome/browser/chromeos/arc/tracing/arc_system_stat_collector.h" #include "chrome/browser/chromeos/arc/tracing/arc_tracing_graphics_model.h" #include "chrome/browser/chromeos/arc/tracing/arc_tracing_model.h" #include "chrome/browser/chromeos/file_manager/path_util.h" @@ -120,7 +121,7 @@ // Helper that clarifies thread and process names. Tracing events may not have // enough data for this. Also it determines the process pid the thread belongs // to. -void UpdateThreads(arc::ArcCpuModel::ThreadMap* threads) { +void UpdateThreads(arc::ArcSystemModel::ThreadMap* threads) { ProcessFilterPassAll filter_pass_all; base::ProcessIterator process_iterator(&filter_pass_all); @@ -151,9 +152,12 @@ std::pair<base::Value, std::string> BuildGraphicsModel( const std::string& data, base::DictionaryValue tasks_info, + std::unique_ptr<arc::ArcSystemStatCollector> system_stat_collector, const base::TimeTicks& time_min, const base::TimeTicks& time_max, const base::FilePath& last_model_path) { + DCHECK(system_stat_collector); + arc::ArcTracingModel common_model; const base::TimeTicks time_min_clamped = std::max(time_min, time_max - kMaxIntervalToDisplay); @@ -164,11 +168,14 @@ if (!common_model.Build(data)) return std::make_pair(base::Value(), "Failed to process tracing data"); + system_stat_collector->Flush(time_min, time_max, + &common_model.system_model()); + arc::ArcTracingGraphicsModel graphics_model; if (!graphics_model.Build(common_model)) return std::make_pair(base::Value(), "Failed to build tracing model"); - UpdateThreads(&graphics_model.cpu_model().thread_map()); + UpdateThreads(&graphics_model.system_model().thread_map()); std::unique_ptr<base::DictionaryValue> model = graphics_model.Serialize(); model->SetKey(kKeyTasks, std::move(tasks_info)); @@ -337,6 +344,8 @@ tracing_active_ = true; if (jank_detector_) jank_detector_->Reset(); + system_stat_colletor_ = std::make_unique<arc::ArcSystemStatCollector>(); + system_stat_colletor_->Start(kMaxIntervalToDisplay); content::TracingController::GetInstance()->StartTracing( config, base::BindOnce(&ArcGraphicsTracingHandler::OnTracingStarted, weak_ptr_factory_.GetWeakPtr())); @@ -349,6 +358,9 @@ tracing_time_max_ = TRACE_TIME_TICKS_NOW(); + if (system_stat_colletor_) + system_stat_colletor_->Stop(); + content::TracingController* const controller = content::TracingController::GetInstance(); @@ -378,12 +390,11 @@ base::RefCountedString* trace_data) { std::string string_data; string_data.swap(trace_data->data()); - base::PostTaskWithTraitsAndReplyWithResult( FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT}, base::BindOnce(&BuildGraphicsModel, std::move(string_data), - std::move(tasks_info_), tracing_time_min_, - tracing_time_max_, + std::move(tasks_info_), std::move(system_stat_colletor_), + tracing_time_min_, tracing_time_max_, GetLastTracingModelPath(Profile::FromWebUI(web_ui()))), base::BindOnce(&ArcGraphicsTracingHandler::OnGraphicsModelReady, weak_ptr_factory_.GetWeakPtr()));
diff --git a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h index c923a5b..b2b7ab2 100644 --- a/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h +++ b/chrome/browser/ui/webui/chromeos/arc_graphics_tracing/arc_graphics_tracing_handler.h
@@ -18,6 +18,7 @@ namespace arc { class ArcGraphicsJankDetector; +class ArcSystemStatCollector; } // namespace arc namespace base { @@ -107,6 +108,9 @@ // Used to detect janks for the currently active ARC++ window. std::unique_ptr<arc::ArcGraphicsJankDetector> jank_detector_; + // Collects system stat runtime. + std::unique_ptr<arc::ArcSystemStatCollector> system_stat_colletor_; + // Information about tasks, title and icon. base::DictionaryValue tasks_info_;
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc index 2defed7..9ac4079 100644 --- a/chrome/browser/ui/webui/extensions/extensions_ui.cc +++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -128,7 +128,7 @@ {"searchResultsPlural", IDS_SEARCH_RESULTS_PLURAL}, {"searchResultsSingular", IDS_SEARCH_RESULTS_SINGULAR}, - // Multi-use strings defined in md_extensions_strings.grdp. + // Multi-use strings defined in extensions_strings.grdp. {"remove", IDS_EXTENSIONS_REMOVE}, // Add extension-specific strings.
diff --git a/chrome/common/mac/staging_watcher.h b/chrome/common/mac/staging_watcher.h index 592c1c0..586ceecd 100644 --- a/chrome/common/mac/staging_watcher.h +++ b/chrome/common/mac/staging_watcher.h
@@ -41,14 +41,11 @@ @interface CrStagingKeyWatcher (TestingInterface) // The designated initializer. Allows a non-default NSUserDefaults to be -// specified. +// specified. Also allows the use of KVO to be disabled to allow the macOS 10.11 +// and earlier code path to be tested on 10.12 and later. - (instancetype)initWithUserDefaults:(NSUserDefaults*)defaults - pollingTime:(NSTimeInterval)pollingTime; - -// KVO works for NSUserDefaults on 10.12 and later. This method turns off the -// use of KVO to allow the macOS 10.11 and earlier code path to be tested on -// 10.12 and later. -- (void)disableKVOForTesting; + pollingTime:(NSTimeInterval)pollingTime + disableKVOForTesting:(BOOL)disableKVOForTesting; // Returns whether the last call to -waitForStagingKeyToClear blocked or // returned immediately.
diff --git a/chrome/common/mac/staging_watcher.mm b/chrome/common/mac/staging_watcher.mm index 0d58e93..cf81325 100644 --- a/chrome/common/mac/staging_watcher.mm +++ b/chrome/common/mac/staging_watcher.mm
@@ -18,6 +18,14 @@ // with that rewrite in 10.12. In macOS 10.11 and earlier, polling is the only // option. Note that NSUserDefaultsDidChangeNotification never notifies about // changes made by other programs, not even in 10.12 and later. +// +// On the other hand, KVO notification was broken in the NSUserDefaults rewrite +// for 10.14; see: +// - https://twitter.com/Catfish_Man/status/1116185288257105925 +// - rdar://49812220 +// The bug is that a change from "no value" to "value present" doesn't notify. +// To work around that, a default is registered to ensure that there never is +// a "no value" situation. namespace { @@ -33,7 +41,6 @@ base::mac::ScopedBlock<StagingKeyChangedObserver> callback_; BOOL lastStagingKeyValue_; - BOOL kvoDisabledForTesting_; BOOL lastWaitWasBlockedForTesting_; } @@ -43,16 +50,19 @@ - (instancetype)initWithPollingTime:(NSTimeInterval)pollingTime { return [self initWithUserDefaults:[NSUserDefaults standardUserDefaults] - pollingTime:pollingTime]; + pollingTime:pollingTime + disableKVOForTesting:NO]; } - (instancetype)initWithUserDefaults:(NSUserDefaults*)defaults - pollingTime:(NSTimeInterval)pollingTime { + pollingTime:(NSTimeInterval)pollingTime + disableKVOForTesting:(BOOL)disableKVOForTesting { if ((self = [super init])) { pollingTime_ = pollingTime; defaults_.reset(defaults, base::scoped_policy::RETAIN); + [defaults_ registerDefaults:@{kStagingKey : @[]}]; lastStagingKeyValue_ = [self isStagingKeySet]; - if (base::mac::IsAtLeastOS10_12() && !kvoDisabledForTesting_) { + if (base::mac::IsAtLeastOS10_12() && !disableKVOForTesting) { // If a change is made in another process (which is the use case here), // the prior value is never provided in the observation callback change // dictionary, whether or not NSKeyValueObservingOptionPrior is specified. @@ -137,10 +147,6 @@ [super dealloc]; } -- (void)disableKVOForTesting { - kvoDisabledForTesting_ = YES; -} - - (BOOL)lastWaitWasBlockedForTesting { return lastWaitWasBlockedForTesting_; }
diff --git a/chrome/common/mac/staging_watcher_unittest.mm b/chrome/common/mac/staging_watcher_unittest.mm index ba0a18a..469494a 100644 --- a/chrome/common/mac/staging_watcher_unittest.mm +++ b/chrome/common/mac/staging_watcher_unittest.mm
@@ -36,10 +36,10 @@ base::scoped_nsobject<CrStagingKeyWatcher> CreateKeyWatcher() { base::scoped_nsobject<CrStagingKeyWatcher> keyWatcher( - [[CrStagingKeyWatcher alloc] initWithUserDefaults:defaults_ - pollingTime:0.5]); - if (GetParam() == KVOOrNot::kDontUseKVO) - [keyWatcher disableKVOForTesting]; + [[CrStagingKeyWatcher alloc] + initWithUserDefaults:defaults_ + pollingTime:0.5 + disableKVOForTesting:(GetParam() == KVOOrNot::kDontUseKVO)]); return keyWatcher; } @@ -133,16 +133,20 @@ base::scoped_nsobject<CrStagingKeyWatcher> watcher = CreateKeyWatcher(); NSRunLoop* runloop = [NSRunLoop currentRunLoop]; + __block bool observerCalled = false; [watcher setStagingKeyChangedObserver:^(BOOL stagingKeySet) { + observerCalled = true; CFRunLoopStop([runloop getCFRunLoop]); }]; SetDefaultsValueInSeparateProcess(); - while (![watcher isStagingKeySet] && - [runloop runMode:NSDefaultRunLoopMode - beforeDate:[NSDate distantFuture]]) { + ASSERT_FALSE([watcher isStagingKeySet]); + while (!observerCalled && [runloop runMode:NSDefaultRunLoopMode + beforeDate:[NSDate distantFuture]]) { /* run! */ } + + EXPECT_TRUE([watcher isStagingKeySet]); } TEST_P(StagingKeyWatcherTest, CallbackOnKeyUnset) { @@ -152,14 +156,18 @@ base::scoped_nsobject<CrStagingKeyWatcher> watcher = CreateKeyWatcher(); NSRunLoop* runloop = [NSRunLoop currentRunLoop]; + __block bool observerCalled = false; [watcher setStagingKeyChangedObserver:^(BOOL stagingKeySet) { + observerCalled = true; CFRunLoopStop([runloop getCFRunLoop]); }]; ClearDefaultsValueInSeparateProcess(); - while ([watcher isStagingKeySet] && - [runloop runMode:NSDefaultRunLoopMode - beforeDate:[NSDate distantFuture]]) { + ASSERT_TRUE([watcher isStagingKeySet]); + while (!observerCalled && [runloop runMode:NSDefaultRunLoopMode + beforeDate:[NSDate distantFuture]]) { /* run! */ } + + EXPECT_FALSE([watcher isStagingKeySet]); }
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index ebb9105..0250b01 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -871,6 +871,18 @@ const char kTPMFirmwareUpdateCleanupDismissed[] = "tpm_firmware_update.cleanup_dismissed"; +// Int64 pref indicating the time in microseconds since Windows epoch +// (1601-01-01 00:00:00 UTC) when the notification informing the user about a +// planned TPM update that will clear all user data was shown. If the +// notification was not yet shown the pref holds the value Time::Min(). +const char kTPMUpdatePlannedNotificationShownTime[] = + "tpm_auto_update.planned_notification_shown_time"; + +// Boolean pref indicating whether the notification informing the user that an +// auto-update that will clear all the user data at next reboot was shown. +const char kTPMUpdateOnNextRebootNotificationShown[] = + "tpm_auto_update.update_on_reboot_notification_shown"; + // Boolean pref indicating whether the NetBios Name Query Request Protocol is // used for discovering shares on the user's network by the Network File // Shares for Chrome OS feature. @@ -1988,6 +2000,11 @@ // set for child users only, and kept on the known user storage. const char kKnownUserParentAccessCodeConfig[] = "child_user.parent_access_code.config"; + +// Enable chrome://password-change page for in-session change of SAML passwords. +// Also enables SAML password expiry notifications, if we have that information. +const char kSamlInSessionPasswordChangeEnabled[] = + "saml.in_session_password_change_enabled"; #endif // defined(OS_CHROMEOS) // Whether there is a Flash version installed that supports clearing LSO data.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index cba8345..7232152ad 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -281,6 +281,8 @@ extern const char kNetworkFileSharesAllowed[]; extern const char kManagedSessionEnabled[]; extern const char kTPMFirmwareUpdateCleanupDismissed[]; +extern const char kTPMUpdatePlannedNotificationShownTime[]; +extern const char kTPMUpdateOnNextRebootNotificationShown[]; extern const char kNetBiosShareDiscoveryEnabled[]; extern const char kChildScreenTimeMilliseconds[]; extern const char kLastChildScreenTimeSaved[]; @@ -657,6 +659,7 @@ extern const char kAutoScreenBrightnessMetricsUnsupportedAlsUserAdjustmentCount[]; extern const char kKnownUserParentAccessCodeConfig[]; +extern const char kSamlInSessionPasswordChangeEnabled[]; #endif // defined(OS_CHROMEOS) extern const char kClearPluginLSODataEnabled[];
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 1ccb50f..de64448b 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc
@@ -540,8 +540,13 @@ FullBrowserTransitionManager::Get()->OnProfileDestroyed(this); - browser_context_dependency_manager_->DestroyBrowserContextServices(this); - simple_dependency_manager_->DestroyKeyedServices(GetSimpleFactoryKey()); + // The SimpleDependencyManager should always be passed after the + // BrowserContextDependencyManager. This is because the KeyedService instances + // in the BrowserContextDependencyManager's dependency graph can depend on the + // ones in the SimpleDependencyManager's graph. + DependencyManager::PerformInterlockedTwoPhaseShutdown( + browser_context_dependency_manager_, this, simple_dependency_manager_, + GetSimpleFactoryKey()); if (host_content_settings_map_.get()) host_content_settings_map_->ShutdownOnUIThread();
diff --git a/chrome/test/chromedriver/test/test_expectations b/chrome/test/chromedriver/test/test_expectations index df3845f5..c1477264 100644 --- a/chrome/test/chromedriver/test/test_expectations +++ b/chrome/test/chromedriver/test/test_expectations
@@ -23,6 +23,33 @@ # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2661 'WindowTest.testSetsTheSizeOfTheCurrentWindowFromIframe', + + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2854 + 'ChromeOptionsFunctionalTest.canSetAcceptInsecureCerts', + + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2835 + 'CookieImplementationTest.deleteAllCookies', + 'CookieImplementationTest.canHandleHttpOnlyCookie', + + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2858 + 'ElementFindingTest.testFindingMultipleElementsByInvalidClassNameShouldThrow', + 'ElementFindingTest.testFindingMultipleElementsByCompoundClassNameShouldThrow', + 'ElementFindingTest.testFindingMultipleElementsByEmptyIdShouldReturnEmptyList', + 'FormHandlingTest.testShouldNotBeAbleToSubmitAFormThatDoesNotExist', + 'PositionAndSizeTest.testShouldGetCoordinatesInViewPortOfAnElementInAFrame', + 'PositionAndSizeTest.testShouldGetCoordinatesInViewPortOfAnElementInANestedFrame', + 'BasicKeyboardInterfaceTest.testSelectionSelectBySymbol', + 'BasicKeyboardInterfaceTest.testSelectionSelectByWord', + 'BasicMouseInterfaceTest.testMovingMouseToRelativeElementOffset', + 'BasicMouseInterfaceTest.testMovingMouseToRelativeZeroElementOffset', + 'BasicMouseInterfaceTest.testCanMoveOverAndOutOfAnElement', + 'BasicMouseInterfaceTest.testMoveMouseByOffsetOverAndOutOfAnElement', + 'CombinedInputActionsTest.testClickAfterMoveToAnElementWithAnOffsetShouldUseLastMousePosition', + 'CombinedInputActionsTest.testChordControlCutAndPaste', + 'DragAndDropTest.testDragAndDropElementWithOffsetInScrolledDiv', + 'DragAndDropTest.canDragAnElementNotVisibleInTheCurrentViewportDueToAParentOverflow', + 'LocationContextTest.testShouldSetAndGetLatitude', + 'LocationContextTest.testShouldSetAndGetLongitude', ] _READY_TO_RUN_FILTER = [ @@ -31,6 +58,12 @@ _OS_NEGATIVE_FILTER = {} _OS_NEGATIVE_FILTER['win'] = [ + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2855 + 'WindowTest.canFullscreenTheWindow', + 'WindowTest.canFullscreenTheWindowFromIframe', + 'WindowTest.testCanMaximizeTheWindowFromIframe', + 'WindowTest.testCanMaximizeTheWindow', + 'BasicMouseInterfaceTest.testMovingMouseByRelativeOffset', ] _OS_NEGATIVE_FILTER['linux'] = [ ] @@ -42,7 +75,14 @@ 'WindowTest.canFullscreenTheWindowFromFrame', 'WindowTest.canFullscreenTheWindowFromIframe', 'WindowTest.testSetsTheSizeOfTheCurrentWindow', + 'WindowTest.testCanMaximizeTheWindowFromFrame', + 'WindowTest.testCanMaximizeTheWindowFromIframe', + 'WindowTest.testCanMaximizeTheWindow', 'BasicMouseInterfaceTest.testMovingMouseByRelativeOffset', + + # https://bugs.chromium.org/p/chromedriver/issues/detail?id=2856 + 'ClickScrollingTest.testShouldBeAbleToClickElementThatIsOutOfViewInANestedFrameThatIsOutOfView', + 'ClickScrollingTest.testShouldBeAbleToClickElementThatIsOutOfViewInANestedFrame', ] _OS_NEGATIVE_FILTER['android:chrome'] = [
diff --git a/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_buffers.json b/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_buffers.json index c22f730..f6e448e 100644 --- a/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_buffers.json +++ b/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_buffers.json
@@ -4,7 +4,7 @@ "global_events": [ ] }, "chrome": { "buffers": [ [ [ 500, 1667.0 ], [ 501, 1808.0 ] ] ], "global_events": [ ] }, - "cpu": { "threads": {}, "events": []}, + "system": { "threads": {}, "cpu": [], "memory": []}, "duration": 1053800.0, "views": [ { "activity": "com.android.vending/com.android.vending.AssetBrowserActivity",
diff --git a/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_desc.json b/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_desc.json index f9006a0..4e9382f 100644 --- a/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_desc.json +++ b/chrome/test/data/arc_graphics_tracing/gm_bad_no_view_desc.json
@@ -5,7 +5,7 @@ "chrome": { "buffers": [ [ [ 500, 1667.0 ], [ 501, 1808.0 ] ] ], "global_events": [ ] }, "duration": 1053800.0, - "cpu": { "threads": {}, "events": []}, + "system": { "threads": {}, "cpu": [], "memory": []}, "views": [ { "buffers": [ [ [ 200, 0.0 ], [ 201, 149.0 ] ], [ [ 300, 168.0 ], [ 202, 173.0 ] ] ], "global_events": [ ],
diff --git a/chrome/test/data/arc_graphics_tracing/gm_bad_wrong_timestamp.json b/chrome/test/data/arc_graphics_tracing/gm_bad_wrong_timestamp.json index 36ba418..195ed0aa 100644 --- a/chrome/test/data/arc_graphics_tracing/gm_bad_wrong_timestamp.json +++ b/chrome/test/data/arc_graphics_tracing/gm_bad_wrong_timestamp.json
@@ -4,7 +4,7 @@ "global_events": [ ] }, "chrome": { "buffers": [ [ [ 500, 1667.0 ], [ 501, 1808.0 ] ] ], "global_events": [ ] }, - "cpu": { "threads": {}, "events": []}, + "system": { "threads": {}, "cpu": [], "memory": []}, "duration": 1053800.0, "views": [ { "activity": "com.android.vending/com.android.vending.AssetBrowserActivity",
diff --git a/chrome/test/data/arc_graphics_tracing/gm_good.json b/chrome/test/data/arc_graphics_tracing/gm_good.json index 93def21f..adeed59 100644 --- a/chrome/test/data/arc_graphics_tracing/gm_good.json +++ b/chrome/test/data/arc_graphics_tracing/gm_good.json
@@ -4,7 +4,7 @@ "global_events": [ ] }, "chrome": { "buffers": [ [ [ 500, 1667.0 ], [ 501, 1808.0 ] ] ], "global_events": [ ] }, - "cpu": { "threads": {}, "events": []}, + "system": { "threads": {}, "cpu": [], "memory": []}, "duration": 1053800.0, "views": [ { "activity": "com.android.vending/com.android.vending.AssetBrowserActivity",
diff --git a/chrome/test/data/arc_graphics_tracing/proc_meminfo b/chrome/test/data/arc_graphics_tracing/proc_meminfo new file mode 100644 index 0000000..aed7637 --- /dev/null +++ b/chrome/test/data/arc_graphics_tracing/proc_meminfo
@@ -0,0 +1,38 @@ +MemTotal: 8058940 kB +MemFree: 314184 kB +MemAvailable: 2714260 kB +Buffers: 701012 kB +Cached: 4108044 kB +SwapCached: 0 kB +Active: 3734844 kB +Inactive: 3288772 kB +Active(anon): 2307120 kB +Inactive(anon): 1971184 kB +Active(file): 1427724 kB +Inactive(file): 1317588 kB +Unevictable: 119252 kB +Mlocked: 30720 kB +SwapTotal: 11805084 kB +SwapFree: 11758420 kB +Dirty: 57024 kB +Writeback: 0 kB +AnonPages: 2333820 kB +Mapped: 1717224 kB +Shmem: 2063760 kB +Slab: 296624 kB +SReclaimable: 131788 kB +SUnreclaim: 164836 kB +KernelStack: 30432 kB +PageTables: 73772 kB +NFS_Unstable: 0 kB +Bounce: 0 kB +WritebackTmp: 0 kB +CommitLimit: 15834552 kB +Committed_AS: 47032264 kB +VmallocTotal: 34359738367 kB +VmallocUsed: 0 kB +VmallocChunk: 0 kB +AnonHugePages: 30720 kB +DirectMap4k: 378408 kB +DirectMap2M: 7905280 kB +DirectMap1G: 0 kB
diff --git a/chrome/test/data/arc_graphics_tracing/zram_stat b/chrome/test/data/arc_graphics_tracing/zram_stat new file mode 100644 index 0000000..9d4a0e0 --- /dev/null +++ b/chrome/test/data/arc_graphics_tracing/zram_stat Binary files differ
diff --git a/chrome/test/data/policy/policy_test_cases.json b/chrome/test/data/policy/policy_test_cases.json index 1a8204ad..0e20df0 100644 --- a/chrome/test/data/policy/policy_test_cases.json +++ b/chrome/test/data/policy/policy_test_cases.json
@@ -3521,6 +3521,14 @@ "pref_mappings": [{ "pref": "web_package.signed_exchange.enabled" }] }, + "SamlInSessionPasswordChangeEnabled": { + "os": [], + "test_policy": { "SamlInSessionPasswordChangeEnabled": true }, + "pref_mappings": [ + { "pref": "saml.in_session_password_change_enabled"} + ] + }, + "----- Chrome OS device policies ---------------------------------------": {}, "DevicePolicyRefreshRate": {
diff --git a/components/autofill/core/browser/address_contact_form_label_formatter.cc b/components/autofill/core/browser/address_contact_form_label_formatter.cc index 13036f9..ffcb115a 100644 --- a/components/autofill/core/browser/address_contact_form_label_formatter.cc +++ b/components/autofill/core/browser/address_contact_form_label_formatter.cc
@@ -11,8 +11,9 @@ AddressContactFormLabelFormatter::AddressContactFormLabelFormatter( const std::string& app_locale, ServerFieldType focused_field_type, + uint32_t groups, const std::vector<ServerFieldType>& field_types) - : LabelFormatter(app_locale, focused_field_type, field_types), + : LabelFormatter(app_locale, focused_field_type, groups, field_types), form_has_street_address_(HasStreetAddress(field_types_for_labels())) {} AddressContactFormLabelFormatter::~AddressContactFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_contact_form_label_formatter.h b/components/autofill/core/browser/address_contact_form_label_formatter.h index d2fc7e3..a34e8a7d 100644 --- a/components/autofill/core/browser/address_contact_form_label_formatter.h +++ b/components/autofill/core/browser/address_contact_form_label_formatter.h
@@ -22,6 +22,7 @@ AddressContactFormLabelFormatter( const std::string& app_locale, ServerFieldType focused_field_type, + uint32_t groups, const std::vector<ServerFieldType>& field_types); ~AddressContactFormLabelFormatter() override;
diff --git a/components/autofill/core/browser/address_email_form_label_formatter.cc b/components/autofill/core/browser/address_email_form_label_formatter.cc index dcc46e2..675bf30 100644 --- a/components/autofill/core/browser/address_email_form_label_formatter.cc +++ b/components/autofill/core/browser/address_email_form_label_formatter.cc
@@ -11,8 +11,9 @@ AddressEmailFormLabelFormatter::AddressEmailFormLabelFormatter( const std::string& app_locale, ServerFieldType focused_field_type, + uint32_t groups, const std::vector<ServerFieldType>& field_types) - : LabelFormatter(app_locale, focused_field_type, field_types), + : LabelFormatter(app_locale, focused_field_type, groups, field_types), form_has_street_address_(HasStreetAddress(field_types_for_labels())) {} AddressEmailFormLabelFormatter::~AddressEmailFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_email_form_label_formatter.h b/components/autofill/core/browser/address_email_form_label_formatter.h index 606bf0a..5c44dba5 100644 --- a/components/autofill/core/browser/address_email_form_label_formatter.h +++ b/components/autofill/core/browser/address_email_form_label_formatter.h
@@ -22,6 +22,7 @@ AddressEmailFormLabelFormatter( const std::string& app_locale, ServerFieldType focused_field_type, + uint32_t groups, const std::vector<ServerFieldType>& field_types); ~AddressEmailFormLabelFormatter() override;
diff --git a/components/autofill/core/browser/address_form_label_formatter.cc b/components/autofill/core/browser/address_form_label_formatter.cc index a3b9786..ec88eda 100644 --- a/components/autofill/core/browser/address_form_label_formatter.cc +++ b/components/autofill/core/browser/address_form_label_formatter.cc
@@ -11,8 +11,9 @@ AddressFormLabelFormatter::AddressFormLabelFormatter( const std::string& app_locale, ServerFieldType focused_field_type, + uint32_t groups, const std::vector<ServerFieldType>& field_types) - : LabelFormatter(app_locale, focused_field_type, field_types), + : LabelFormatter(app_locale, focused_field_type, groups, field_types), form_has_street_address_(HasStreetAddress(field_types_for_labels())) {} AddressFormLabelFormatter::~AddressFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_form_label_formatter.h b/components/autofill/core/browser/address_form_label_formatter.h index e477dfe..e4a97dcd 100644 --- a/components/autofill/core/browser/address_form_label_formatter.h +++ b/components/autofill/core/browser/address_form_label_formatter.h
@@ -21,6 +21,7 @@ public: AddressFormLabelFormatter(const std::string& app_locale, ServerFieldType focused_field_type, + uint32_t groups, const std::vector<ServerFieldType>& field_types); ~AddressFormLabelFormatter() override;
diff --git a/components/autofill/core/browser/address_phone_form_label_formatter.cc b/components/autofill/core/browser/address_phone_form_label_formatter.cc index 670f1e8..97e374b 100644 --- a/components/autofill/core/browser/address_phone_form_label_formatter.cc +++ b/components/autofill/core/browser/address_phone_form_label_formatter.cc
@@ -11,8 +11,9 @@ AddressPhoneFormLabelFormatter::AddressPhoneFormLabelFormatter( const std::string& app_locale, ServerFieldType focused_field_type, + uint32_t groups, const std::vector<ServerFieldType>& field_types) - : LabelFormatter(app_locale, focused_field_type, field_types), + : LabelFormatter(app_locale, focused_field_type, groups, field_types), form_has_street_address_(HasStreetAddress(field_types_for_labels())) {} AddressPhoneFormLabelFormatter::~AddressPhoneFormLabelFormatter() {}
diff --git a/components/autofill/core/browser/address_phone_form_label_formatter.h b/components/autofill/core/browser/address_phone_form_label_formatter.h index 32f162a8..231ca9e 100644 --- a/components/autofill/core/browser/address_phone_form_label_formatter.h +++ b/components/autofill/core/browser/address_phone_form_label_formatter.h
@@ -22,6 +22,7 @@ AddressPhoneFormLabelFormatter( const std::string& app_locale, ServerFieldType focused_field_type, + uint32_t groups, const std::vector<ServerFieldType>& field_types); ~AddressPhoneFormLabelFormatter() override;
diff --git a/components/autofill/core/browser/contact_form_label_formatter.cc b/components/autofill/core/browser/contact_form_label_formatter.cc index 05a7a0e..a375da5 100644 --- a/components/autofill/core/browser/contact_form_label_formatter.cc +++ b/components/autofill/core/browser/contact_form_label_formatter.cc
@@ -13,8 +13,7 @@ ServerFieldType focused_field_type, uint32_t groups, const std::vector<ServerFieldType>& field_types) - : LabelFormatter(app_locale, focused_field_type, field_types), - groups_(groups) {} + : LabelFormatter(app_locale, focused_field_type, groups, field_types) {} ContactFormLabelFormatter::~ContactFormLabelFormatter() {} @@ -42,14 +41,14 @@ base::string16 ContactFormLabelFormatter::MaybeGetEmail( const AutofillProfile& profile) const { - return ContainsEmail(groups_) ? GetLabelEmail(profile, app_locale()) - : base::string16(); + return ContainsEmail(groups()) ? GetLabelEmail(profile, app_locale()) + : base::string16(); } base::string16 ContactFormLabelFormatter::MaybeGetPhone( const AutofillProfile& profile) const { - return ContainsPhone(groups_) ? GetLabelPhone(profile, app_locale()) - : base::string16(); + return ContainsPhone(groups()) ? GetLabelPhone(profile, app_locale()) + : base::string16(); } } // namespace autofill
diff --git a/components/autofill/core/browser/contact_form_label_formatter.h b/components/autofill/core/browser/contact_form_label_formatter.h index ca23a7fe..be4eb1ca 100644 --- a/components/autofill/core/browser/contact_form_label_formatter.h +++ b/components/autofill/core/browser/contact_form_label_formatter.h
@@ -38,9 +38,6 @@ // Returns |profile|'s phone number if |profile| has a phone number and if // this formatter's associated form has a phone field. base::string16 MaybeGetPhone(const AutofillProfile& profile) const; - - // A bitmask indicating which fields the form contains. - uint32_t groups_; }; } // namespace autofill
diff --git a/components/autofill/core/browser/label_formatter.cc b/components/autofill/core/browser/label_formatter.cc index 689e250..303fcdc9 100644 --- a/components/autofill/core/browser/label_formatter.cc +++ b/components/autofill/core/browser/label_formatter.cc
@@ -24,25 +24,30 @@ LabelFormatter::LabelFormatter(const std::string& app_locale, ServerFieldType focused_field_type, + uint32_t groups, const std::vector<ServerFieldType>& field_types) - : app_locale_(app_locale), focused_field_type_(focused_field_type) { + : app_locale_(app_locale), + focused_field_type_(focused_field_type), + groups_(groups) { const FieldTypeGroup focused_group = GetFocusedNonBillingGroup(); - std::set<FieldTypeGroup> groups{NAME, ADDRESS_HOME, EMAIL, PHONE_HOME}; + std::set<FieldTypeGroup> groups_for_labels{NAME, ADDRESS_HOME, EMAIL, + PHONE_HOME}; // If a user is focused on an address field, then parts of the address may be // shown in the label. For example, if the user is focusing on a street // address field, then it may be helpful to show the city in the label. // Otherwise, the focused field should not appear in the label. if (focused_group != ADDRESS_HOME) { - groups.erase(focused_group); + groups_for_labels.erase(focused_group); } // Countries are excluded to prevent them from appearing in labels with // national addresses. - auto can_be_shown_in_label = [&groups](ServerFieldType type) -> bool { - return groups.find( + auto can_be_shown_in_label = + [&groups_for_labels](ServerFieldType type) -> bool { + return groups_for_labels.find( AutofillType(AutofillType(type).GetStorableType()).group()) != - groups.end() && + groups_for_labels.end() && type != ADDRESS_HOME_COUNTRY && type != ADDRESS_BILLING_COUNTRY; }; @@ -79,13 +84,13 @@ return nullptr; case kName | kAddress | kPhone: return std::make_unique<AddressPhoneFormLabelFormatter>( - app_locale, focused_field_type, field_types); + app_locale, focused_field_type, groups, field_types); case kName | kAddress | kEmail: return std::make_unique<AddressEmailFormLabelFormatter>( - app_locale, focused_field_type, field_types); + app_locale, focused_field_type, groups, field_types); case kName | kAddress: return std::make_unique<AddressFormLabelFormatter>( - app_locale, focused_field_type, field_types); + app_locale, focused_field_type, groups, field_types); case kName | kEmail | kPhone: case kName | kEmail: case kName | kPhone:
diff --git a/components/autofill/core/browser/label_formatter.h b/components/autofill/core/browser/label_formatter.h index 5879599..d2dd4bf 100644 --- a/components/autofill/core/browser/label_formatter.h +++ b/components/autofill/core/browser/label_formatter.h
@@ -20,9 +20,14 @@ public: LabelFormatter(const std::string& app_locale, ServerFieldType focused_field_type, + uint32_t groups, const std::vector<ServerFieldType>& field_types); virtual ~LabelFormatter(); + // Returns the bitmask indicating which FieldTypeGroups are represented in + // this formatter's associated form. + uint32_t groups() const { return groups_; } + // Returns a collection of labels formed by extracting useful disambiguating // information from a collection of |profiles|. std::vector<base::string16> GetLabels( @@ -69,6 +74,10 @@ // The type of field on which the user is focused, e.g. NAME_FIRST. ServerFieldType focused_field_type_; + // The bitmask indicating which FieldTypeGroups are represented in this + // formatter's associated form. + uint32_t groups_; + // A collection of field types that can be used to make labels. It includes // only types related to names, addresses, email addresses, and phone // numbers. It excludes types related to countries.
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc index 1d34ad6..8362c98 100644 --- a/components/autofill/core/browser/personal_data_manager.cc +++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1168,12 +1168,15 @@ matched_profiles, suggestions, &unique_matched_profiles); - std::unique_ptr<LabelFormatter> formatter = - base::FeatureList::IsEnabled( - autofill::features::kAutofillUseImprovedLabelDisambiguation) - ? LabelFormatter::Create(app_locale_, type.GetStorableType(), - field_types) - : nullptr; + std::unique_ptr<LabelFormatter> formatter; + +#if !defined(OS_ANDROID) && !defined(OS_IOS) + formatter = base::FeatureList::IsEnabled( + autofill::features::kAutofillUseImprovedLabelDisambiguation) + ? LabelFormatter::Create(app_locale_, type.GetStorableType(), + field_types) + : nullptr; +#endif // Generate disambiguating labels based on the list of matches. std::vector<base::string16> labels; @@ -1184,7 +1187,10 @@ type.GetStorableType(), 1, app_locale_, &labels); } - suggestion_selection::PrepareSuggestions(labels, &unique_suggestions); + + suggestion_selection::PrepareSuggestions( + formatter && ContainsAddress(formatter->groups()), labels, + &unique_suggestions); return unique_suggestions; } @@ -2491,12 +2497,16 @@ } void PersonalDataManager::RemoveProfileFromDB(const std::string& guid) { - bool profile_exists = FindByGUID<AutofillProfile>(web_profiles_, guid); + auto profile_it = FindElementByGUID<AutofillProfile>(web_profiles_, guid); + bool profile_exists = profile_it != web_profiles_.end(); if (!profile_exists && !ProfileChangesAreOngoing(guid)) { NotifyPersonalDataObserver(); return; } - AutofillProfileDeepChange change(AutofillProfileChange::REMOVE, guid); + const AutofillProfile* profile = + profile_exists ? profile_it->get() + : ongoing_profile_changes_[guid].back().profile(); + AutofillProfileDeepChange change(AutofillProfileChange::REMOVE, *profile); if (!ProfileChangesAreOngoing(guid)) { database_helper_->GetLocalDatabase()->RemoveAutofillProfile(guid); change.set_is_ongoing_on_background();
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc index 10deadda..e3c2ba2 100644 --- a/components/autofill/core/browser/personal_data_manager_unittest.cc +++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -2544,6 +2544,7 @@ EXPECT_EQ(0U, personal_data_->GetProfiles().size()); } +#if !defined(OS_ANDROID) && !defined(OS_IOS) TEST_F(PersonalDataManagerTest, GetProfileSuggestionsWithImprovedLabelDisambiguationForContactForm) { AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin); @@ -2568,9 +2569,12 @@ FormatExpectedLabel("(978) 674-4120", "hoa.pham@comcast.net")), testing::Field( &Suggestion::additional_label, - FormatExpectedLabel("(978) 674-4120", "hoa.pham@comcast.net"))))); + FormatExpectedLabel("(978) 674-4120", "hoa.pham@comcast.net")), + testing::Field(&Suggestion::icon, "userAccountAvatarIcon")))); } +#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS) +#if !defined(OS_ANDROID) && !defined(OS_IOS) TEST_F(PersonalDataManagerTest, GetProfileSuggestionsWithImprovedLabelDisambiguationForAddressForm) { AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin); @@ -2593,11 +2597,14 @@ testing::Field( &Suggestion::label, base::ASCIIToUTF16("401 Merrimack St, Lowell, MA 01852")), - testing::Field(&Suggestion::additional_label, - base::ASCIIToUTF16( - "401 Merrimack St, Lowell, MA 01852"))))); + testing::Field( + &Suggestion::additional_label, + base::ASCIIToUTF16("401 Merrimack St, Lowell, MA 01852")), + testing::Field(&Suggestion::icon, "locationOnIcon")))); } +#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS) +#if !defined(OS_ANDROID) && !defined(OS_IOS) TEST_F( PersonalDataManagerTest, GetProfileSuggestionsWithImprovedLabelDisambiguationForAddressPhoneForm) { @@ -2617,15 +2624,17 @@ AutofillType(NAME_FULL), base::string16(), false, std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, PHONE_HOME_WHOLE_NUMBER}), - ElementsAre(AllOf( - testing::Field( - &Suggestion::label, - FormatExpectedLabel("(978) 674-4120", "401 Merrimack St")), - testing::Field( - &Suggestion::additional_label, - FormatExpectedLabel("(978) 674-4120", "401 Merrimack St"))))); + ElementsAre(AllOf(testing::Field(&Suggestion::label, + FormatExpectedLabel("(978) 674-4120", + "401 Merrimack St")), + testing::Field(&Suggestion::additional_label, + FormatExpectedLabel("(978) 674-4120", + "401 Merrimack St")), + testing::Field(&Suggestion::icon, "locationOnIcon")))); } +#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS) +#if !defined(OS_ANDROID) && !defined(OS_IOS) TEST_F( PersonalDataManagerTest, GetProfileSuggestionsWithImprovedLabelDisambiguationForAddressEmailForm) { @@ -2640,19 +2649,20 @@ /*enabled_features=*/{features::kAutofillUseImprovedLabelDisambiguation}, /*disabled_features=*/{}); - EXPECT_THAT( - personal_data_->GetProfileSuggestions( - AutofillType(NAME_FULL), base::string16(), false, - std::vector<ServerFieldType>{NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, - EMAIL_ADDRESS}), - ElementsAre(AllOf( - testing::Field( - &Suggestion::label, - FormatExpectedLabel("401 Merrimack St", "hoa.pham@comcast.net")), - testing::Field(&Suggestion::additional_label, - FormatExpectedLabel("401 Merrimack St", - "hoa.pham@comcast.net"))))); + EXPECT_THAT(personal_data_->GetProfileSuggestions( + AutofillType(NAME_FULL), base::string16(), false, + std::vector<ServerFieldType>{ + NAME_FULL, ADDRESS_HOME_STREET_ADDRESS, EMAIL_ADDRESS}), + ElementsAre(AllOf( + testing::Field(&Suggestion::label, + FormatExpectedLabel("401 Merrimack St", + "hoa.pham@comcast.net")), + testing::Field(&Suggestion::additional_label, + FormatExpectedLabel("401 Merrimack St", + "hoa.pham@comcast.net")), + testing::Field(&Suggestion::icon, "locationOnIcon")))); } +#endif // #if !defined(OS_ANDROID) && !defined(OS_IOS) TEST_F(PersonalDataManagerTest, IsKnownCard_MatchesMaskedServerCard) { // Add a masked server card.
diff --git a/components/autofill/core/browser/suggestion_selection.cc b/components/autofill/core/browser/suggestion_selection.cc index 10d93bd..b8c2711 100644 --- a/components/autofill/core/browser/suggestion_selection.cc +++ b/components/autofill/core/browser/suggestion_selection.cc
@@ -9,6 +9,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "build/build_config.h" #include "components/autofill/core/browser/address_i18n.h" #include "components/autofill/core/browser/autofill_data_util.h" #include "components/autofill/core/browser/autofill_metrics.h" @@ -99,6 +100,7 @@ /* is_masked_server_card= */ false, &prefix_matched_suggestion)) { matched_profiles->push_back(profile); +#if !defined(OS_ANDROID) && !defined(OS_IOS) // If the field with which the user is interacting is a phone number or // part of a phone number, then display it in the national format // corresponding to the profile's country. For example, (508) 488-0800 @@ -112,6 +114,7 @@ base::UTF16ToUTF8(value), data_util::GetCountryCodeWithFallback( *profile, comparator.app_locale()))); } +#endif suggestions.push_back(Suggestion(value)); suggestions.back().backend_id = profile->guid(); @@ -233,13 +236,22 @@ num_profiles_supressed); } -void PrepareSuggestions(const std::vector<base::string16>& labels, +void PrepareSuggestions(bool contains_address, + const std::vector<base::string16>& labels, std::vector<Suggestion>* suggestions) { DCHECK_EQ(suggestions->size(), labels.size()); for (size_t i = 0; i < labels.size(); ++i) { (*suggestions)[i].additional_label = base::string16(labels[i]); (*suggestions)[i].label = base::string16(labels[i]); + +#if !defined(OS_ANDROID) && !defined(OS_IOS) + if (base::FeatureList::IsEnabled( + autofill::features::kAutofillUseImprovedLabelDisambiguation)) { + (*suggestions)[i].icon = + contains_address ? "locationOnIcon" : "userAccountAvatarIcon"; + } +#endif } }
diff --git a/components/autofill/core/browser/suggestion_selection.h b/components/autofill/core/browser/suggestion_selection.h index 067538b..817c0d20 100644 --- a/components/autofill/core/browser/suggestion_selection.h +++ b/components/autofill/core/browser/suggestion_selection.h
@@ -62,7 +62,10 @@ // Prepares a collection of Suggestions to show to the user. Adds |labels| to // their corresponding |suggestions|. A label corresponds to the suggestion with // the same index. -void PrepareSuggestions(const std::vector<base::string16>& labels, +// |contains_address| determines which icon to add to suggestions in the +// autofill-use-improved-label-disambiguation experiment. +void PrepareSuggestions(bool contains_address, + const std::vector<base::string16>& labels, std::vector<Suggestion>* suggestions); } // namespace suggestion_selection
diff --git a/components/autofill/core/browser/webdata/autofill_change.h b/components/autofill/core/browser/webdata/autofill_change.h index 308ea62d..f23695ad 100644 --- a/components/autofill/core/browser/webdata/autofill_change.h +++ b/components/autofill/core/browser/webdata/autofill_change.h
@@ -55,16 +55,12 @@ // The |type| input specifies the change type. The |key| input is the key // that identifies the |data_model|; it is the GUID of the entry for local // data and server_id of the entry for server data from GPay. - // When |type| == ADD, |data_model| should be non-NULL. - // When |type| == UPDATE, |data_model| should be non-NULL. - // When |type| == REMOVE, |data_model| should be NULL. AutofillDataModelChange(Type type, const std::string& key, const DataType* data_model) : GenericAutofillChange<std::string>(type, key), data_model_(data_model) { - DCHECK(type == REMOVE ? !data_model - : data_model && (data_model->guid() == key || - data_model->server_id() == key)); + DCHECK(data_model && + (data_model->guid() == key || data_model->server_id() == key)); } ~AutofillDataModelChange() override {} @@ -90,11 +86,6 @@ : AutofillProfileChange(type, profile.guid(), &profile), profile_(profile) {} - AutofillProfileDeepChange(Type type, const std::string& guid) - : AutofillProfileChange(type, guid, nullptr), profile_(guid, "") { - DCHECK(type == GenericAutofillChange::REMOVE); - } - ~AutofillProfileDeepChange() override {} const AutofillProfile* profile() const { return &profile_; }
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc index 961972e..fee7640 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc +++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge.cc
@@ -208,12 +208,8 @@ void AutofillProfileSyncBridge::ActOnLocalChange( const AutofillProfileChange& change) { - DCHECK((change.type() == AutofillProfileChange::REMOVE) == - (change.data_model() == nullptr)); - if (!change_processor()->IsTrackingMetadata()) { - return; - } - if (change.data_model() && + DCHECK(change.data_model()); + if (!change_processor()->IsTrackingMetadata() || change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) { return; } @@ -223,19 +219,10 @@ GetAutofillTable(), syncer::AUTOFILL_PROFILE); // TODO(crbug.com/904390): Remove when the investigation is over. - bool is_converted_from_server = false; - if (change.type() == AutofillProfileChange::REMOVE) { - // The profile is not available any more so we cannot compare its value, - // instead we use a rougher test based on the id - whether it is a local - // GUID or a server id. As a result, it has a different semantics compared - // to AddOrUpdate. - is_converted_from_server = !base::IsValidGUID(change.key()); - } else { - std::vector<std::unique_ptr<AutofillProfile>> server_profiles; - GetAutofillTable()->GetServerProfiles(&server_profiles); - is_converted_from_server = IsLocalProfileEqualToServerProfile( - server_profiles, *change.data_model(), app_locale_); - } + std::vector<std::unique_ptr<AutofillProfile>> server_profiles; + GetAutofillTable()->GetServerProfiles(&server_profiles); + bool is_converted_from_server = IsLocalProfileEqualToServerProfile( + server_profiles, *change.data_model(), app_locale_); switch (change.type()) { case AutofillProfileChange::ADD: @@ -252,12 +239,6 @@ : AutofillProfileSyncChangeOrigin::kTrulyLocal); break; case AutofillProfileChange::REMOVE: - // Removals have no data_model() so this change can still be for a - // SERVER_PROFILE. We have no simple way to rule it out. For the time - // being we rely on the processor ignoring deletions for storage keys it - // does not know. - // TODO(jkrcal): implement a hash map of known storage_keys and use it - // here. change_processor()->Delete(change.key(), metadata_change_list.get()); // TODO(crbug.com/904390): Remove when the investigation is over.
diff --git a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc index e2410d7..9da18603 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_profile_sync_bridge_unittest.cc
@@ -453,7 +453,9 @@ TEST_F(AutofillProfileSyncBridgeTest, AutofillProfileChanged_Deleted) { StartSyncing({}); - AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuidB, nullptr); + AutofillProfile local(kGuidB, kHttpsOrigin); + local.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane")); + AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuidB, &local); EXPECT_CALL(mock_processor(), Delete(kGuidB, _)); // The bridge does not need to commit when reacting to a notification about a // local change. @@ -462,6 +464,20 @@ bridge()->AutofillProfileChanged(change); } +// Server profile updates should be ignored. +TEST_F(AutofillProfileSyncBridgeTest, + AutofillProfileChanged_Deleted_IgnoreServerProfiles) { + StartSyncing({}); + + AutofillProfile server_profile(AutofillProfile::SERVER_PROFILE, "server-id"); + AutofillProfileChange change(AutofillProfileChange::REMOVE, + server_profile.guid(), &server_profile); + + EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0); + // Should not crash. + bridge()->AutofillProfileChanged(change); +} + TEST_F(AutofillProfileSyncBridgeTest, GetAllDataForDebugging) { AutofillProfile local1 = AutofillProfile(kGuidA, kHttpsOrigin); local1.SetRawInfo(NAME_FIRST, ASCIIToUTF16("John"));
diff --git a/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc index c5853c0..1a6b461 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc +++ b/components/autofill/core/browser/webdata/autofill_profile_syncable_service.cc
@@ -608,33 +608,21 @@ void AutofillProfileSyncableService::ActOnChange( const AutofillProfileChange& change) { - DCHECK( - (change.type() == AutofillProfileChange::REMOVE && - !change.data_model()) || - (change.type() != AutofillProfileChange::REMOVE && change.data_model())); + DCHECK(change.data_model()); DCHECK(sync_processor_); - if (change.data_model() && - change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) { + if (change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) { return; } // TODO(crbug.com/904390): Remove when the investigation is over. bool is_converted_from_server = false; - if (change.type() == AutofillProfileChange::REMOVE) { - // The profile is not available any more so we cannot compare its value, - // instead we use a rougher test based on the id - whether it is a local - // GUID or a server id. As a result, it has a different semantics compared - // to AddOrUpdate. - is_converted_from_server = !base::IsValidGUID(change.key()); - } else { - // |webdata_backend_|, used by GetAutofillTable() may be null in unit-tests. - if (webdata_backend_ != nullptr) { - std::vector<std::unique_ptr<AutofillProfile>> server_profiles; - GetAutofillTable()->GetServerProfiles(&server_profiles); - is_converted_from_server = IsLocalProfileEqualToServerProfile( - server_profiles, *change.data_model(), app_locale_); - } + // |webdata_backend_|, used by GetAutofillTable() may be null in unit-tests. + if (webdata_backend_ != nullptr) { + std::vector<std::unique_ptr<AutofillProfile>> server_profiles; + GetAutofillTable()->GetServerProfiles(&server_profiles); + is_converted_from_server = IsLocalProfileEqualToServerProfile( + server_profiles, *change.data_model(), app_locale_); } syncer::SyncChangeList new_changes; @@ -674,13 +662,10 @@ break; } case AutofillProfileChange::REMOVE: { - // Removals have no data_model() so this change can still be for a - // SERVER_PROFILE. Rule it out by a lookup in profiles_map_. if (profiles_map_.find(change.key()) != profiles_map_.end()) { - AutofillProfile empty_profile(change.key(), std::string()); new_changes.push_back( syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_DELETE, - CreateData(empty_profile))); + CreateData(*(change.data_model())))); profiles_map_.erase(change.key()); // TODO(crbug.com/904390): Remove when the investigation is over. ReportAutofillProfileDeleteOrigin(
diff --git a/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc b/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc index 1b605e94..6291ce17 100644 --- a/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_profile_syncable_service_unittest.cc
@@ -593,7 +593,8 @@ AutofillProfileChange change1(AutofillProfileChange::ADD, kGuid1, &profile); autofill_syncable_service_.AutofillProfileChanged(change1); - AutofillProfileChange change2(AutofillProfileChange::REMOVE, kGuid1, nullptr); + AutofillProfileChange change2(AutofillProfileChange::REMOVE, kGuid1, + &profile); autofill_syncable_service_.AutofillProfileChanged(change2); ASSERT_EQ(1U, sync_change_processor->changes().size()); @@ -611,7 +612,9 @@ TestSyncChangeProcessor* sync_change_processor = new TestSyncChangeProcessor; autofill_syncable_service_.set_sync_processor(sync_change_processor); - AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuid2, nullptr); + AutofillProfile profile(kGuid2, kEmptyOrigin); + profile.SetRawInfo(NAME_FIRST, ASCIIToUTF16("Jane")); + AutofillProfileChange change(AutofillProfileChange::REMOVE, kGuid2, &profile); autofill_syncable_service_.AutofillProfileChanged(change); ASSERT_EQ(0U, sync_change_processor->changes().size());
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc index 0b1570d..c174b5a4 100644 --- a/components/autofill/core/browser/webdata/autofill_table.cc +++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -1705,8 +1705,8 @@ bool AutofillTable::RemoveAutofillDataModifiedBetween( const base::Time& delete_begin, const base::Time& delete_end, - std::vector<std::string>* profile_guids, - std::vector<std::string>* credit_card_guids) { + std::vector<std::unique_ptr<AutofillProfile>>* profiles, + std::vector<std::unique_ptr<CreditCard>>* credit_cards) { DCHECK(delete_end.is_null() || delete_begin < delete_end); time_t delete_begin_t = delete_begin.ToTimeT(); @@ -1719,17 +1719,20 @@ s_profiles_get.BindInt64(0, delete_begin_t); s_profiles_get.BindInt64(1, delete_end_t); - profile_guids->clear(); + profiles->clear(); while (s_profiles_get.Step()) { std::string guid = s_profiles_get.ColumnString(0); - profile_guids->push_back(guid); + std::unique_ptr<AutofillProfile> profile = GetAutofillProfile(guid); + if (!profile) + return false; + profiles->push_back(std::move(profile)); } if (!s_profiles_get.Succeeded()) return false; // Remove the profile pieces. - for (const std::string& guid : *profile_guids) { - if (!RemoveAutofillProfilePieces(guid, db_)) + for (const std::unique_ptr<AutofillProfile>& profile : *profiles) { + if (!RemoveAutofillProfilePieces(profile->guid(), db_)) return false; } @@ -1750,10 +1753,13 @@ s_credit_cards_get.BindInt64(0, delete_begin_t); s_credit_cards_get.BindInt64(1, delete_end_t); - credit_card_guids->clear(); + credit_cards->clear(); while (s_credit_cards_get.Step()) { std::string guid = s_credit_cards_get.ColumnString(0); - credit_card_guids->push_back(guid); + std::unique_ptr<CreditCard> credit_card = GetCreditCard(guid); + if (!credit_card) + return false; + credit_cards->push_back(std::move(credit_card)); } if (!s_credit_cards_get.Succeeded()) return false;
diff --git a/components/autofill/core/browser/webdata/autofill_table.h b/components/autofill/core/browser/webdata/autofill_table.h index ae7114f..4c57a95 100644 --- a/components/autofill/core/browser/webdata/autofill_table.h +++ b/components/autofill/core/browser/webdata/autofill_table.h
@@ -452,8 +452,8 @@ bool RemoveAutofillDataModifiedBetween( const base::Time& delete_begin, const base::Time& delete_end, - std::vector<std::string>* profile_guids, - std::vector<std::string>* credit_card_guids); + std::vector<std::unique_ptr<AutofillProfile>>* profiles, + std::vector<std::unique_ptr<CreditCard>>* credit_cards); // Removes origin URLs from the autofill_profiles and credit_cards tables if // they were written on or after |delete_begin| and strictly before
diff --git a/components/autofill/core/browser/webdata/autofill_table_unittest.cc b/components/autofill/core/browser/webdata/autofill_table_unittest.cc index dce60d15..b2f8812 100644 --- a/components/autofill/core/browser/webdata/autofill_table_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_table_unittest.cc
@@ -1519,16 +1519,15 @@ "VALUES('00000000-0000-0000-0000-000000000011', 67);")); // Remove all entries modified in the bounded time range [17,41). - std::vector<std::string> profile_guids; - std::vector<std::string> credit_card_guids; + std::vector<std::unique_ptr<AutofillProfile>> profiles; + std::vector<std::unique_ptr<CreditCard>> credit_cards; table_->RemoveAutofillDataModifiedBetween( - Time::FromTimeT(17), Time::FromTimeT(41), - &profile_guids, &credit_card_guids); + Time::FromTimeT(17), Time::FromTimeT(41), &profiles, &credit_cards); // Two profiles should have been removed. - ASSERT_EQ(2UL, profile_guids.size()); - EXPECT_EQ("00000000-0000-0000-0000-000000000001", profile_guids[0]); - EXPECT_EQ("00000000-0000-0000-0000-000000000002", profile_guids[1]); + ASSERT_EQ(2UL, profiles.size()); + EXPECT_EQ("00000000-0000-0000-0000-000000000001", profiles[0]->guid()); + EXPECT_EQ("00000000-0000-0000-0000-000000000002", profiles[1]->guid()); // Make sure that only the expected profiles are still present. sql::Statement s_autofill_profiles_bounded( @@ -1595,10 +1594,10 @@ EXPECT_FALSE(s_autofill_profile_phones_bounded.Step()); // Three cards should have been removed. - ASSERT_EQ(3UL, credit_card_guids.size()); - EXPECT_EQ("00000000-0000-0000-0000-000000000006", credit_card_guids[0]); - EXPECT_EQ("00000000-0000-0000-0000-000000000007", credit_card_guids[1]); - EXPECT_EQ("00000000-0000-0000-0000-000000000008", credit_card_guids[2]); + ASSERT_EQ(3UL, credit_cards.size()); + EXPECT_EQ("00000000-0000-0000-0000-000000000006", credit_cards[0]->guid()); + EXPECT_EQ("00000000-0000-0000-0000-000000000007", credit_cards[1]->guid()); + EXPECT_EQ("00000000-0000-0000-0000-000000000008", credit_cards[2]->guid()); // Make sure the expected profiles are still present. sql::Statement s_credit_cards_bounded( @@ -1614,12 +1613,11 @@ EXPECT_FALSE(s_credit_cards_bounded.Step()); // Remove all entries modified on or after time 51 (unbounded range). - table_->RemoveAutofillDataModifiedBetween( - Time::FromTimeT(51), Time(), - &profile_guids, &credit_card_guids); - ASSERT_EQ(2UL, profile_guids.size()); - EXPECT_EQ("00000000-0000-0000-0000-000000000004", profile_guids[0]); - EXPECT_EQ("00000000-0000-0000-0000-000000000005", profile_guids[1]); + table_->RemoveAutofillDataModifiedBetween(Time::FromTimeT(51), Time(), + &profiles, &credit_cards); + ASSERT_EQ(2UL, profiles.size()); + EXPECT_EQ("00000000-0000-0000-0000-000000000004", profiles[0]->guid()); + EXPECT_EQ("00000000-0000-0000-0000-000000000005", profiles[1]->guid()); // Make sure that only the expected profile names are still present. sql::Statement s_autofill_profiles_unbounded( @@ -1670,9 +1668,9 @@ EXPECT_FALSE(s_autofill_profile_phones_unbounded.Step()); // Two cards should have been removed. - ASSERT_EQ(2UL, credit_card_guids.size()); - EXPECT_EQ("00000000-0000-0000-0000-000000000010", credit_card_guids[0]); - EXPECT_EQ("00000000-0000-0000-0000-000000000011", credit_card_guids[1]); + ASSERT_EQ(2UL, credit_cards.size()); + EXPECT_EQ("00000000-0000-0000-0000-000000000010", credit_cards[0]->guid()); + EXPECT_EQ("00000000-0000-0000-0000-000000000011", credit_cards[1]->guid()); // Make sure the remaining card is the expected one. sql::Statement s_credit_cards_unbounded( @@ -1684,14 +1682,13 @@ EXPECT_FALSE(s_credit_cards_unbounded.Step()); // Remove all remaining entries. - table_->RemoveAutofillDataModifiedBetween( - Time(), Time(), - &profile_guids, &credit_card_guids); + table_->RemoveAutofillDataModifiedBetween(Time(), Time(), &profiles, + &credit_cards); // Two profiles should have been removed. - ASSERT_EQ(2UL, profile_guids.size()); - EXPECT_EQ("00000000-0000-0000-0000-000000000000", profile_guids[0]); - EXPECT_EQ("00000000-0000-0000-0000-000000000003", profile_guids[1]); + ASSERT_EQ(2UL, profiles.size()); + EXPECT_EQ("00000000-0000-0000-0000-000000000000", profiles[0]->guid()); + EXPECT_EQ("00000000-0000-0000-0000-000000000003", profiles[1]->guid()); // Make sure there are no profiles remaining. sql::Statement s_autofill_profiles_empty( @@ -1722,8 +1719,8 @@ EXPECT_FALSE(s_autofill_profile_phones_empty.Step()); // One credit card should have been deleted. - ASSERT_EQ(1UL, credit_card_guids.size()); - EXPECT_EQ("00000000-0000-0000-0000-000000000009", credit_card_guids[0]); + ASSERT_EQ(1UL, credit_cards.size()); + EXPECT_EQ("00000000-0000-0000-0000-000000000009", credit_cards[0]->guid()); // There should be no cards left. sql::Statement s_credit_cards_empty( @@ -2677,12 +2674,12 @@ table_->UnmaskServerCreditCard(masked_card, full_number); // Delete data in a range a year in the future. - std::vector<std::string> profile_guids; - std::vector<std::string> credit_card_guids; + std::vector<std::unique_ptr<AutofillProfile>> profiles; + std::vector<std::unique_ptr<CreditCard>> credit_cards; ASSERT_TRUE(table_->RemoveAutofillDataModifiedBetween( unmasked_time + base::TimeDelta::FromDays(365), - unmasked_time + base::TimeDelta::FromDays(530), - &profile_guids, &credit_card_guids)); + unmasked_time + base::TimeDelta::FromDays(530), &profiles, + &credit_cards)); // This should not affect the unmasked card (should be unmasked). std::vector<std::unique_ptr<CreditCard>> outputs; @@ -2697,8 +2694,7 @@ // the database uses. base::Time now = base::Time::Now() + base::TimeDelta::FromSeconds(1); ASSERT_TRUE(table_->RemoveAutofillDataModifiedBetween( - now - base::TimeDelta::FromDays(1), now, - &profile_guids, &credit_card_guids)); + now - base::TimeDelta::FromDays(1), now, &profiles, &credit_cards)); // This should re-mask. ASSERT_TRUE(table_->GetServerCreditCards(&outputs)); @@ -2717,7 +2713,7 @@ // Delete all data. ASSERT_TRUE(table_->RemoveAutofillDataModifiedBetween( - base::Time(), base::Time::Max(), &profile_guids, &credit_card_guids)); + base::Time(), base::Time::Max(), &profiles, &credit_cards)); // Should be masked again. ASSERT_TRUE(table_->GetServerCreditCards(&outputs));
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc index 2a0caec..a38a740 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge.cc
@@ -438,10 +438,8 @@ void AutofillWalletMetadataSyncBridge::AutofillProfileChanged( const AutofillProfileChange& change) { - // Skip local profiles (if possible, i.e. if it is not a deletion where - // data_model() is not set). - if (change.data_model() && - change.data_model()->record_type() != AutofillProfile::SERVER_PROFILE) { + // Skip local profiles. + if (change.data_model()->record_type() != AutofillProfile::SERVER_PROFILE) { return; } LocalMetadataChanged(WalletMetadataSpecifics::ADDRESS, change); @@ -703,9 +701,7 @@ if (RemoveServerMetadata(GetAutofillTable(), type, metadata_id)) { cache_.erase(storage_key); // Send up deletion only if we had this entry in the DB. It is not there - // if (i) it was previously deleted by a remote deletion or (ii) this is - // notification for a LOCAL_PROFILE (which have non-overlapping - // storage_keys). + // if it was previously deleted by a remote deletion. change_processor()->Delete(storage_key, metadata_change_list.get()); } return;
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc index 237782d..f793b93 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_sync_bridge_unittest.cc
@@ -821,10 +821,11 @@ EXPECT_CALL(*backend(), CommitChanges()).Times(0); EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0); - bridge()->AutofillProfileChanged(AutofillProfileChange( - AutofillProfileChange::REMOVE, existing_profile.server_id(), nullptr)); + bridge()->AutofillProfileChanged( + AutofillProfileChange(AutofillProfileChange::REMOVE, + existing_profile.server_id(), &existing_profile)); bridge()->CreditCardChanged(CreditCardChange( - CreditCardChange::REMOVE, existing_card.server_id(), nullptr)); + CreditCardChange::REMOVE, existing_card.server_id(), &existing_card)); // Check that there is no metadata anymore. EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty()); @@ -850,10 +851,11 @@ EXPECT_CALL(*backend(), CommitChanges()).Times(0); EXPECT_CALL(*backend(), NotifyOfMultipleAutofillChanges()).Times(0); - bridge()->AutofillProfileChanged(AutofillProfileChange( - AutofillProfileChange::REMOVE, existing_profile.server_id(), nullptr)); + bridge()->AutofillProfileChanged( + AutofillProfileChange(AutofillProfileChange::REMOVE, + existing_profile.server_id(), &existing_profile)); bridge()->CreditCardChanged(CreditCardChange( - CreditCardChange::REMOVE, existing_card.server_id(), nullptr)); + CreditCardChange::REMOVE, existing_card.server_id(), &existing_card)); // Check that there is also no metadata at the end. EXPECT_THAT(GetAllLocalDataInclRestart(), IsEmpty());
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc index 3ee7061..e801acb8 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_metadata_syncable_service.cc
@@ -563,19 +563,18 @@ void AutofillWalletMetadataSyncableService::AutofillProfileChanged( const AutofillProfileChange& change) { DCHECK(thread_checker_.CalledOnValidThread()); + DCHECK(change.data_model()); if (!track_wallet_data_) { return; } - if (sync_processor_ && change.data_model() && + if (sync_processor_ && change.type() == AutofillProfileChange::UPDATE && change.data_model()->record_type() != AutofillProfile::LOCAL_PROFILE) { std::string server_id = GetServerId(*change.data_model()); auto it = FindServerIdAndTypeInCache( server_id, sync_pb::WalletMetadataSpecifics::ADDRESS, &cache_); if (it == cache_.end()) return; - // Implicitly, we filter out ADD (not in cache) and REMOVE (!data_model()). - DCHECK(change.type() == AutofillProfileChange::UPDATE); const sync_pb::WalletMetadataSpecifics& remote = it->GetSpecifics().wallet_metadata();
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc index c76ea95..aa51b2f 100644 --- a/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc +++ b/components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.cc
@@ -533,7 +533,7 @@ if (cmp < 0) { ++result.items_removed; result.changes.emplace_back(AutofillDataModelChange<Item>::REMOVE, - (*old_it)->server_id(), nullptr); + (*old_it)->server_id(), *old_it); ++old_it; } else if (cmp == 0) { ++old_it;
diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc index 0725f77..1027a3d 100644 --- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc +++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc
@@ -306,15 +306,17 @@ } // Send GUID-based notification. - AutofillProfileChange change(AutofillProfileChange::REMOVE, guid, nullptr); + AutofillProfileChange change(AutofillProfileChange::REMOVE, guid, + profile.get()); for (auto& db_observer : db_observer_list_) db_observer.AutofillProfileChanged(change); if (!on_autofill_profile_changed_cb_.is_null()) { ui_task_runner_->PostTask( - FROM_HERE, base::BindOnce(on_autofill_profile_changed_cb_, - AutofillProfileDeepChange( - AutofillProfileChange::REMOVE, guid))); + FROM_HERE, + base::BindOnce(on_autofill_profile_changed_cb_, + AutofillProfileDeepChange(AutofillProfileChange::REMOVE, + *profile.get()))); } return WebDatabase::COMMIT_NEEDED; @@ -413,6 +415,13 @@ WebDatabase::State AutofillWebDataBackendImpl::RemoveCreditCard( const std::string& guid, WebDatabase* db) { DCHECK(owning_task_runner()->RunsTasksInCurrentSequence()); + std::unique_ptr<CreditCard> card = + AutofillTable::FromWebDatabase(db)->GetCreditCard(guid); + if (!card) { + NOTREACHED(); + return WebDatabase::COMMIT_NOT_NEEDED; + } + if (!AutofillTable::FromWebDatabase(db)->RemoveCreditCard(guid)) { NOTREACHED(); return WebDatabase::COMMIT_NOT_NEEDED; @@ -420,7 +429,7 @@ for (auto& db_observer : db_observer_list_) { db_observer.CreditCardChanged( - CreditCardChange(CreditCardChange::REMOVE, guid, nullptr)); + CreditCardChange(CreditCardChange::REMOVE, guid, card.get())); } return WebDatabase::COMMIT_NEEDED; } @@ -552,23 +561,20 @@ const base::Time& delete_end, WebDatabase* db) { DCHECK(owning_task_runner()->RunsTasksInCurrentSequence()); - std::vector<std::string> profile_guids; - std::vector<std::string> credit_card_guids; + std::vector<std::unique_ptr<AutofillProfile>> profiles; + std::vector<std::unique_ptr<CreditCard>> credit_cards; if (AutofillTable::FromWebDatabase(db)->RemoveAutofillDataModifiedBetween( - delete_begin, - delete_end, - &profile_guids, - &credit_card_guids)) { - for (const std::string& guid : profile_guids) { + delete_begin, delete_end, &profiles, &credit_cards)) { + for (const std::unique_ptr<AutofillProfile>& profile : profiles) { for (auto& db_observer : db_observer_list_) { db_observer.AutofillProfileChanged(AutofillProfileChange( - AutofillProfileChange::REMOVE, guid, nullptr)); + AutofillProfileChange::REMOVE, profile->guid(), profile.get())); } } - for (const std::string& guid : credit_card_guids) { + for (const std::unique_ptr<CreditCard>& credit_card : credit_cards) { for (auto& db_observer : db_observer_list_) { - db_observer.CreditCardChanged( - CreditCardChange(CreditCardChange::REMOVE, guid, nullptr)); + db_observer.CreditCardChanged(CreditCardChange( + CreditCardChange::REMOVE, credit_card->guid(), credit_card.get())); } } // Note: It is the caller's responsibility to post notifications for any
diff --git a/components/autofill/core/browser/webdata/web_data_service_unittest.cc b/components/autofill/core/browser/webdata/web_data_service_unittest.cc index f1d6e76..5c2ff85c 100644 --- a/components/autofill/core/browser/webdata/web_data_service_unittest.cc +++ b/components/autofill/core/browser/webdata/web_data_service_unittest.cc
@@ -313,7 +313,7 @@ // Check that GUID-based notification was sent. const AutofillProfileChange expected_change(AutofillProfileChange::REMOVE, - profile.guid(), nullptr); + profile.guid(), &profile); EXPECT_CALL(observer_, AutofillProfileChanged(expected_change)) .WillOnce(SignalEvent(&done_event_)); @@ -491,7 +491,7 @@ // Check that GUID-based notification was sent for the profile. const AutofillProfileChange expected_profile_change( - AutofillProfileChange::REMOVE, profile.guid(), nullptr); + AutofillProfileChange::REMOVE, profile.guid(), &profile); EXPECT_CALL(observer_, AutofillProfileChanged(expected_profile_change)) .WillOnce(SignalEvent(&done_event_));
diff --git a/components/browser_sync/profile_sync_service_autofill_unittest.cc b/components/browser_sync/profile_sync_service_autofill_unittest.cc index b9651a6..3fef1b74 100644 --- a/components/browser_sync/profile_sync_service_autofill_unittest.cc +++ b/components/browser_sync/profile_sync_service_autofill_unittest.cc
@@ -999,7 +999,7 @@ ASSERT_TRUE(add_autofill.success()); AutofillProfileChange change(AutofillProfileChange::REMOVE, - sync_profile.guid(), nullptr); + sync_profile.guid(), &sync_profile); web_data_service()->OnAutofillProfileChanged(change); std::vector<AutofillProfile> new_sync_profiles;
diff --git a/components/cbor/BUILD.gn b/components/cbor/BUILD.gn index b0d8024..d2736ea 100644 --- a/components/cbor/BUILD.gn +++ b/components/cbor/BUILD.gn
@@ -7,6 +7,8 @@ component("cbor") { sources = [ "constants.h", + "diagnostic_writer.cc", + "diagnostic_writer.h", "reader.cc", "reader.h", "values.cc", @@ -25,6 +27,7 @@ source_set("unit_tests") { testonly = true sources = [ + "diagnostic_writer_unittest.cc", "reader_unittest.cc", "values_unittest.cc", "writer_unittest.cc",
diff --git a/components/cbor/diagnostic_writer.cc b/components/cbor/diagnostic_writer.cc new file mode 100644 index 0000000..870f6ba --- /dev/null +++ b/components/cbor/diagnostic_writer.cc
@@ -0,0 +1,143 @@ +// Copyright 2019 The Chromium Authors. 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/cbor/diagnostic_writer.h" + +#include <string> + +#include "base/json/string_escape.h" +#include "base/logging.h" +#include "base/numerics/clamped_math.h" +#include "base/strings/string_number_conversions.h" +#include "components/cbor/constants.h" +#include "components/cbor/values.h" + +using base::ClampAdd; +using base::ClampMul; + +namespace cbor { + +static bool Serialize(const Value& node, + size_t rough_max_output_bytes, + std::string* s) { + switch (node.type()) { + case Value::Type::UNSIGNED: + s->append(base::NumberToString(node.GetUnsigned())); + break; + + case Value::Type::NEGATIVE: + s->append(base::NumberToString(node.GetNegative())); + break; + + case Value::Type::BYTE_STRING: { + s->append("h'"); + + const std::vector<uint8_t>& bytes = node.GetBytestring(); + if (ClampAdd(s->size(), ClampMul(2u, bytes.size())) > + rough_max_output_bytes) { + return false; + } + s->append(base::HexEncode(bytes.data(), bytes.size())); + + s->push_back('\''); + break; + } + + case Value::Type::STRING: { + std::string quoted_and_escaped; + base::EscapeJSONString(node.GetString(), /*put_in_quotes=*/true, + "ed_and_escaped); + if (ClampAdd(s->size(), quoted_and_escaped.size()) > + rough_max_output_bytes) { + return false; + } + s->append(quoted_and_escaped); + break; + } + + case Value::Type::ARRAY: { + s->push_back('['); + + const Value::ArrayValue& nodes = node.GetArray(); + bool first = true; + for (const auto& subnode : nodes) { + if (!first) { + s->append(", "); + } + if (!Serialize(subnode, rough_max_output_bytes, s) || + s->size() > rough_max_output_bytes) { + return false; + } + first = false; + } + + s->push_back(']'); + break; + } + + case Value::Type::MAP: { + s->push_back('{'); + + const Value::MapValue& nodes = node.GetMap(); + bool first = true; + for (const auto& pair : nodes) { + if (!first) { + s->append(", "); + } + if (!Serialize(pair.first, rough_max_output_bytes, s)) { + return false; + } + s->append(": "); + if (!Serialize(pair.second, rough_max_output_bytes, s) || + s->size() > rough_max_output_bytes) { + return false; + } + first = false; + } + + s->push_back('}'); + break; + } + + case Value::Type::SIMPLE_VALUE: + switch (node.GetSimpleValue()) { + case Value::SimpleValue::FALSE_VALUE: + s->append("false"); + break; + case Value::SimpleValue::TRUE_VALUE: + s->append("true"); + break; + case Value::SimpleValue::NULL_VALUE: + s->append("null"); + break; + case Value::SimpleValue::UNDEFINED: + s->append("undefined"); + break; + default: + NOTREACHED(); + break; + } + break; + + case Value::Type::NONE: + s->append("none"); + break; + + case Value::Type::TAG: + NOTREACHED(); + break; + } + + return true; +} + +// static +std::string DiagnosticWriter::Write(const Value& node, + size_t rough_max_output_bytes) { + std::string ret; + Serialize(node, rough_max_output_bytes, &ret); + return ret; +} + +} // namespace cbor
diff --git a/components/cbor/diagnostic_writer.h b/components/cbor/diagnostic_writer.h new file mode 100644 index 0000000..3106ee3 --- /dev/null +++ b/components/cbor/diagnostic_writer.h
@@ -0,0 +1,29 @@ +// Copyright 2019 The Chromium Authors. 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_CBOR_DIAGNOSTIC_WRITER_H_ +#define COMPONENTS_CBOR_DIAGNOSTIC_WRITER_H_ + +#include <string> + +#include "components/cbor/cbor_export.h" + +namespace cbor { + +class Value; + +class CBOR_EXPORT DiagnosticWriter { + public: + // Write converts the given CBOR value to a compact string, following the + // "Diagnostic Notation" format for CBOR + // (https://tools.ietf.org/html/rfc7049#section-6). |rough_max_output_bytes| + // provides a loose upper bound on the size of the result and the result may + // be truncated if it exceeds this size. + static std::string Write(const Value& node, + size_t rough_max_output_bytes = 4096); +}; + +} // namespace cbor + +#endif // COMPONENTS_CBOR_DIAGNOSTIC_WRITER_H_
diff --git a/components/cbor/diagnostic_writer_unittest.cc b/components/cbor/diagnostic_writer_unittest.cc new file mode 100644 index 0000000..c804ce0 --- /dev/null +++ b/components/cbor/diagnostic_writer_unittest.cc
@@ -0,0 +1,61 @@ +// Copyright 2019 The Chromium Authors. 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/cbor/diagnostic_writer.h" +#include "components/cbor/values.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace cbor { + +TEST(CBORDiagnosticWriterTest, Basic) { + Value::MapValue map; + map.emplace(1, 1); + map.emplace(2, -2); + map.emplace(3, "test"); + std::vector<uint8_t> bytes = {1, 2, 3, 4}; + map.emplace(4, std::move(bytes)); + + Value::MapValue submap; + submap.emplace(5, true); + submap.emplace(6, false); + map.emplace(5, cbor::Value(submap)); + + Value::ArrayValue array; + array.emplace_back(1); + array.emplace_back(2); + array.emplace_back(3); + array.emplace_back("foo"); + map.emplace(6, cbor::Value(array)); + + map.emplace(7, "es\'cap\\in\ng"); + + EXPECT_EQ( + "{1: 1, 2: -2, 3: \"test\", 4: h'01020304', 5: {5: true, 6: false}, 6: " + "[1, 2, 3, \"foo\"], 7: \"es'cap\\\\in\\ng\"}", + DiagnosticWriter::Write(cbor::Value(map))); +} + +TEST(CBORDiagnosticWriterTest, SizeLimit) { + Value::ArrayValue array; + array.emplace_back(1); + array.emplace_back(2); + array.emplace_back(3); + EXPECT_EQ("[1, 2, 3]", DiagnosticWriter::Write(cbor::Value(array))); + // A limit of zero is set, but it's only rough, so a few bytes might be + // produced. + EXPECT_LT( + DiagnosticWriter::Write(cbor::Value(array), /*rough_max_output_bytes=*/0) + .size(), + 3u); + + std::vector<uint8_t> bytes; + bytes.resize(100); + EXPECT_LT( + DiagnosticWriter::Write(cbor::Value(bytes), /*rough_max_output_bytes=*/0) + .size(), + 3u); +} + +} // namespace cbor
diff --git a/components/certificate_transparency/log_dns_client.cc b/components/certificate_transparency/log_dns_client.cc index 783b85d..695c096 100644 --- a/components/certificate_transparency/log_dns_client.cc +++ b/components/certificate_transparency/log_dns_client.cc
@@ -483,14 +483,14 @@ } last_dns_response_ = nullptr; + DCHECK(url_request_context_); current_dns_transaction_ = factory->CreateTransaction( qname, net::dns_protocol::kTypeTXT, base::BindOnce(&AuditProofQueryImpl::OnDnsTransactionComplete, weak_ptr_factory_.GetWeakPtr()), net_log_, - lookup_securely_ ? net::SecureDnsMode::SECURE : net::SecureDnsMode::OFF); - DCHECK(url_request_context_); - current_dns_transaction_->SetRequestContext(url_request_context_); + lookup_securely_ ? net::SecureDnsMode::SECURE : net::SecureDnsMode::OFF, + url_request_context_); current_dns_transaction_->Start(); return true;
diff --git a/components/crash/content/app/breakpad_win.cc b/components/crash/content/app/breakpad_win.cc index 172cf5b..2231f14 100644 --- a/components/crash/content/app/breakpad_win.cc +++ b/components/crash/content/app/breakpad_win.cc
@@ -372,9 +372,6 @@ // Crashes the process after generating a dump for the provided exception. Note // that the crash reporter should be initialized before calling this function // for it to do anything. -// NOTE: This function is used by SyzyASAN to invoke a crash. If you change the -// the name or signature of this function you will break SyzyASAN instrumented -// releases of Chrome. Please contact syzygy-team@chromium.org before doing so! extern "C" int __declspec(dllexport) CrashForException( EXCEPTION_POINTERS* info) { if (g_breakpad) {
diff --git a/components/cronet/native/cronet.idl b/components/cronet/native/cronet.idl index c5615cd..ec9463b 100644 --- a/components/cronet/native/cronet.idl +++ b/components/cronet/native/cronet.idl
@@ -859,6 +859,9 @@ * Invoked when request is completed successfully. Once invoked, no other * UrlRequestCallback methods will be invoked. * + * Implementations of {@link #OnSucceeded} are allowed to call {@code + * Cronet_UrlRequest_Destroy(request)}. + * * @param request Request that succeeded. * @param info Response information. */ @@ -869,6 +872,9 @@ * Once invoked, no other UrlRequestCallback methods will be invoked. * |error| provides information about the failure. * + * Implementations of {@link #OnFailed} are allowed to call {@code + * Cronet_UrlRequest_Destroy(request)}. + * * @param request Request that failed. * @param info Response information. May be null if no response was * received. @@ -880,6 +886,9 @@ * Invoked if request was canceled via UrlRequest.cancel(). Once * invoked, no other UrlRequestCallback methods will be invoked. * + * Implementations of {@link #OnCanceled} are allowed to call {@code + * Cronet_UrlRequest_Destroy(request)}. + * * @param request Request that was canceled. * @param info Response information. May be null if no response was * received.
diff --git a/components/cronet/native/url_request.cc b/components/cronet/native/url_request.cc index 8c807c8d..a0ee45c8 100644 --- a/components/cronet/native/url_request.cc +++ b/components/cronet/native/url_request.cc
@@ -546,6 +546,7 @@ } InvokeAllStatusListeners(); Cronet_UrlRequestCallback_OnSucceeded(callback_, this, response_info_.get()); + // |this| may have been deleted here. } void Cronet_UrlRequestImpl::InvokeCallbackOnFailed() { @@ -556,11 +557,13 @@ InvokeAllStatusListeners(); Cronet_UrlRequestCallback_OnFailed(callback_, this, response_info_.get(), error_.get()); + // |this| may have been deleted here. } void Cronet_UrlRequestImpl::InvokeCallbackOnCanceled() { InvokeAllStatusListeners(); Cronet_UrlRequestCallback_OnCanceled(callback_, this, response_info_.get()); + // |this| may have been deleted here. } void Cronet_UrlRequestImpl::InvokeAllStatusListeners() {
diff --git a/components/gwp_asan/common/allocator_state.cc b/components/gwp_asan/common/allocator_state.cc index 636979a..4a6812014 100644 --- a/components/gwp_asan/common/allocator_state.cc +++ b/components/gwp_asan/common/allocator_state.cc
@@ -17,6 +17,7 @@ // TODO: Delete out-of-line constexpr defininitons once C++17 is in use. constexpr size_t AllocatorState::kMaxMetadata; constexpr size_t AllocatorState::kMaxSlots; +constexpr AllocatorState::MetadataIdx AllocatorState::kInvalidMetadataIdx; constexpr size_t AllocatorState::kMaxStackFrames; constexpr size_t AllocatorState::kMaxPackedTraceLength; @@ -28,9 +29,7 @@ const MetadataIdx* slot_to_metadata, MetadataIdx* metadata_idx) const { CHECK(IsValid()); - - if (!PointerIsMine(exception_address)) - return GetMetadataReturnType::kUnrelatedCrash; + CHECK(PointerIsMine(exception_address)); AllocatorState::SlotIdx slot_idx = GetNearestSlot(exception_address); if (slot_idx >= total_pages)
diff --git a/components/gwp_asan/common/allocator_state.h b/components/gwp_asan/common/allocator_state.h index 64d69200..4e3d9240 100644 --- a/components/gwp_asan/common/allocator_state.h +++ b/components/gwp_asan/common/allocator_state.h
@@ -27,6 +27,7 @@ #include <atomic> #include <limits> +#include <type_traits> #include "base/threading/platform_thread.h" @@ -71,12 +72,11 @@ }; enum class GetMetadataReturnType { - kUnrelatedCrash = 0, - kGwpAsanCrash = 1, - kGwpAsanCrashWithMissingMetadata = 2, - kErrorBadSlot = 3, - kErrorBadMetadataIndex = 4, - kErrorOutdatedMetadataIndex = 5, + kGwpAsanCrash = 0, + kGwpAsanCrashWithMissingMetadata = 1, + kErrorBadSlot = 2, + kErrorBadMetadataIndex = 3, + kErrorOutdatedMetadataIndex = 4, }; // Structure for storing data about a slot. @@ -124,15 +124,12 @@ bool IsValid() const; // This method is meant to be called from the crash handler with a validated - // AllocatorState object read from the crashed process. Given the metadata - // and slot to metadata arrays for the allocator and an exception address, - // this method determines if the exception is related to GWP-ASan or not and - // what the metadata for the relevant GWP-ASan allocation is if so. - // - // Returns an enum indicating an error, unrelated exception, or a GWP-ASan - // exception with or without metadata. If metadata is available, the - // metadata_idx parameter stores the index of the relevant metadata in the - // given array. + // AllocatorState object read from the crashed process and an exception + // address known to be in the GWP-ASan allocator region. Given the metadata + // and slot to metadata arrays for the allocator, this method returns an enum + // indicating an error or a GWP-ASan exception with or without metadata. If + // metadata is available, the metadata_idx parameter stores the index of the + // relevant metadata in the given array. GetMetadataReturnType GetMetadataForAddress( uintptr_t exception_address, const SlotMetadata* metadata_arr,
diff --git a/components/gwp_asan/common/allocator_state_unittest.cc b/components/gwp_asan/common/allocator_state_unittest.cc index 4d81967..43246e5 100644 --- a/components/gwp_asan/common/allocator_state_unittest.cc +++ b/components/gwp_asan/common/allocator_state_unittest.cc
@@ -150,9 +150,14 @@ AllocatorState::MetadataIdx slot_to_metadata[kTestSlots]; AllocatorState::MetadataIdx idx; - EXPECT_EQ(state_.GetMetadataForAddress(state_.pages_base_addr - 1, md, - slot_to_metadata, &idx), - GetMetadataReturnType::kUnrelatedCrash); +#if defined(GTEST_HAS_DEATH_TEST) + EXPECT_DEATH( + { + state_.GetMetadataForAddress(state_.pages_base_addr - 1, md, + slot_to_metadata, &idx); + }, + ""); +#endif slot_to_metadata[0] = AllocatorState::kInvalidMetadataIdx; EXPECT_EQ(state_.GetMetadataForAddress(state_.first_page_addr, md,
diff --git a/components/gwp_asan/crash_handler/crash_analyzer.cc b/components/gwp_asan/crash_handler/crash_analyzer.cc index 26f77ad7..78f3213 100644 --- a/components/gwp_asan/crash_handler/crash_analyzer.cc +++ b/components/gwp_asan/crash_handler/crash_analyzer.cc
@@ -111,8 +111,10 @@ else if (valid_state.free_invalid_address) exception_addr = valid_state.free_invalid_address; - if (!exception_addr) + if (!exception_addr || !valid_state.PointerIsMine(exception_addr)) return GwpAsanCrashAnalysisResult::kUnrelatedCrash; + // All errors that occur below happen for an exception known to be related to + // GWP-ASan. // Read the allocator's entire metadata array. auto metadata_arr = std::make_unique<AllocatorState::SlotMetadata[]>( @@ -152,8 +154,6 @@ DLOG(ERROR) << "Metadata index was outdated!"; return GwpAsanCrashAnalysisResult::kErrorOutdatedMetadataIndex; } - if (ret == GetMetadataReturnType::kUnrelatedCrash) - return GwpAsanCrashAnalysisResult::kUnrelatedCrash; bool missing_metadata = (ret == GetMetadataReturnType::kGwpAsanCrashWithMissingMetadata);
diff --git a/components/gwp_asan/crash_handler/crash_handler_unittest.cc b/components/gwp_asan/crash_handler/crash_handler_unittest.cc index 2d17694..56889d1 100644 --- a/components/gwp_asan/crash_handler/crash_handler_unittest.cc +++ b/components/gwp_asan/crash_handler/crash_handler_unittest.cc
@@ -36,8 +36,6 @@ namespace { -class GwpAsanTest : public testing::Test {}; - constexpr size_t kAllocationSize = 902; constexpr int kSuccess = 0; constexpr size_t kTotalPages = AllocatorState::kMaxSlots;
diff --git a/components/keyed_service/core/dependency_manager.cc b/components/keyed_service/core/dependency_manager.cc index 14b20f96..cb4ea9a 100644 --- a/components/keyed_service/core/dependency_manager.cc +++ b/components/keyed_service/core/dependency_manager.cc
@@ -74,25 +74,64 @@ } void DependencyManager::DestroyContextServices(void* context) { - std::vector<DependencyNode*> destruction_order; - if (!dependency_graph_.GetDestructionOrder(&destruction_order)) { - NOTREACHED(); - } + std::vector<DependencyNode*> destruction_order = GetDestructionOrder(); #ifndef NDEBUG DumpContextDependencies(context); #endif - for (auto* dependency_node : destruction_order) { + ShutdownFactoriesInOrder(context, destruction_order); + MarkContextDead(context); + DestroyFactoriesInOrder(context, destruction_order); +} + +// static +void DependencyManager::PerformInterlockedTwoPhaseShutdown( + DependencyManager* dependency_manager1, + void* context1, + DependencyManager* dependency_manager2, + void* context2) { + std::vector<DependencyNode*> destruction_order1 = + dependency_manager1->GetDestructionOrder(); + std::vector<DependencyNode*> destruction_order2 = + dependency_manager2->GetDestructionOrder(); + +#ifndef NDEBUG + dependency_manager1->DumpContextDependencies(context1); + dependency_manager2->DumpContextDependencies(context2); +#endif + + ShutdownFactoriesInOrder(context1, destruction_order1); + ShutdownFactoriesInOrder(context2, destruction_order2); + + dependency_manager1->MarkContextDead(context1); + dependency_manager2->MarkContextDead(context2); + + DestroyFactoriesInOrder(context1, destruction_order1); + DestroyFactoriesInOrder(context2, destruction_order2); +} + +std::vector<DependencyNode*> DependencyManager::GetDestructionOrder() { + std::vector<DependencyNode*> destruction_order; + if (!dependency_graph_.GetDestructionOrder(&destruction_order)) + NOTREACHED(); + return destruction_order; +} + +void DependencyManager::ShutdownFactoriesInOrder( + void* context, + std::vector<DependencyNode*>& order) { + for (auto* dependency_node : order) { KeyedServiceBaseFactory* factory = static_cast<KeyedServiceBaseFactory*>(dependency_node); factory->ContextShutdown(context); } +} - // The context is now dead to the rest of the program. - dead_context_pointers_.insert(context); - - for (auto* dependency_node : destruction_order) { +void DependencyManager::DestroyFactoriesInOrder( + void* context, + std::vector<DependencyNode*>& order) { + for (auto* dependency_node : order) { KeyedServiceBaseFactory* factory = static_cast<KeyedServiceBaseFactory*>(dependency_node); factory->ContextDestroyed(context); @@ -117,6 +156,10 @@ dead_context_pointers_.erase(context); } +void DependencyManager::MarkContextDead(void* context) { + dead_context_pointers_.insert(context); +} + #ifndef NDEBUG namespace {
diff --git a/components/keyed_service/core/dependency_manager.h b/components/keyed_service/core/dependency_manager.h index 39ba693..1ee0b9dcf 100644 --- a/components/keyed_service/core/dependency_manager.h +++ b/components/keyed_service/core/dependency_manager.h
@@ -26,6 +26,19 @@ // broadcasting the context creation and destruction to each factory in // a safe order based on the stated dependencies. class KEYED_SERVICE_EXPORT DependencyManager { + public: + // Shuts down all keyed services managed by two + // DependencyManagers (DMs), then destroys them. The order of execution is: + // - Shutdown services in DM1 + // - Shutdown services in DM2 + // - Destroy services in DM1 + // - Destroy services in DM2 + static void PerformInterlockedTwoPhaseShutdown( + DependencyManager* dependency_manager1, + void* context1, + DependencyManager* dependency_manager2, + void* context2); + protected: DependencyManager(); virtual ~DependencyManager(); @@ -70,6 +83,11 @@ // 0xWhatever). void MarkContextLive(void* context); + // Marks |context| as dead (i.e., stale). Calls passing |context| to + //|AssertContextWasntDestroyed()| will flag an error until that context is + // marked as live again with MarkContextLive(). + void MarkContextDead(void* context); + #ifndef NDEBUG // Dumps service dependency graph as a Graphviz dot file |dot_file| with a // title |top_level_name|. Helper for |DumpContextDependencies|. @@ -85,6 +103,12 @@ virtual void DumpContextDependencies(void* context) const = 0; #endif // NDEBUG + std::vector<DependencyNode*> GetDestructionOrder(); + static void ShutdownFactoriesInOrder(void* context, + std::vector<DependencyNode*>& order); + static void DestroyFactoriesInOrder(void* context, + std::vector<DependencyNode*>& order); + DependencyGraph dependency_graph_; // A list of context objects that have gone through the Shutdown() phase.
diff --git a/components/omnibox/browser/document_provider.cc b/components/omnibox/browser/document_provider.cc index a50c9f7..96f2d47 100644 --- a/components/omnibox/browser/document_provider.cc +++ b/components/omnibox/browser/document_provider.cc
@@ -431,6 +431,9 @@ omnibox::kDocumentProvider, "DocumentScoreResult2", 700); int score2 = base::GetFieldTrialParamByFeatureAsInt( omnibox::kDocumentProvider, "DocumentScoreResult3", 300); + // During development/quality iteration we may wish to defeat server scores. + bool use_server_scores = base::GetFieldTrialParamByFeatureAsBool( + omnibox::kDocumentProvider, "DocumentUseServerScore", true); // Some users may be in a counterfactual study arm in which we perform all // necessary work but do not forward the autocomplete matches. @@ -473,7 +476,7 @@ break; } int server_score; - if (result->GetInteger("score", &server_score)) { + if (use_server_scores && result->GetInteger("score", &server_score)) { if (previous_score >= 0 && server_score >= previous_score) { server_score = previous_score - 1; } @@ -514,7 +517,7 @@ match.description = GetProductDescriptionString(mimetype); } AutocompleteMatch::AddLastClassificationIfNecessary( - &match.description_class, 0, ACMatchClassification::NONE); + &match.description_class, 0, ACMatchClassification::DIM); } match.transition = ui::PAGE_TRANSITION_GENERATED; if (!in_counterfactual_group) {
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc index 82482677c..f77ab0cd 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -253,11 +253,10 @@ bool sign_in_username_first = true; // First username is stored in |result->username|. const FormFieldData* second_username = nullptr; - for (const auto& prediction : predictions) { + for (const PasswordFieldPrediction& prediction : predictions) { ProcessedField* processed_field = nullptr; - CredentialFieldType field_type = - DeriveFromServerFieldType(prediction.second.type); + CredentialFieldType field_type = DeriveFromServerFieldType(prediction.type); bool is_password_prediction = IsPasswordPrediction(field_type); if (mode == FormDataParser::Mode::kSaving && is_password_prediction) { // TODO(crbug.com/913965): Consider server predictions for password fields @@ -267,14 +266,14 @@ switch (field_type) { case CredentialFieldType::kUsername: if (!result->username) { - processed_field = - FindFieldWithUniqueRendererId(processed_fields, prediction.first); + processed_field = FindFieldWithUniqueRendererId( + processed_fields, prediction.renderer_id); if (processed_field) { result->username = processed_field->field; } } else if (!second_username) { - processed_field = - FindFieldWithUniqueRendererId(processed_fields, prediction.first); + processed_field = FindFieldWithUniqueRendererId( + processed_fields, prediction.renderer_id); if (processed_field) { second_username = processed_field->field; } @@ -286,8 +285,8 @@ if (result->password) { prevent_handling_two_usernames = true; } else { - processed_field = - FindFieldWithUniqueRendererId(processed_fields, prediction.first); + processed_field = FindFieldWithUniqueRendererId( + processed_fields, prediction.renderer_id); if (processed_field) { if (!processed_field->is_password) continue; @@ -307,8 +306,8 @@ // before the user has thought of and typed their new password // elsewhere. See https://crbug.com/902700 for more details. if (!result->new_password) { - processed_field = - FindFieldWithUniqueRendererId(processed_fields, prediction.first); + processed_field = FindFieldWithUniqueRendererId( + processed_fields, prediction.renderer_id); if (processed_field) { if (!processed_field->is_password) continue; @@ -317,8 +316,8 @@ } break; case CredentialFieldType::kConfirmationPassword: - processed_field = - FindFieldWithUniqueRendererId(processed_fields, prediction.first); + processed_field = FindFieldWithUniqueRendererId(processed_fields, + prediction.renderer_id); if (processed_field) { if (!processed_field->is_password) continue; @@ -355,11 +354,11 @@ // For the use of basic heuristics, also mark CVC fields and NOT_PASSWORD // fields as such. - for (const auto& prediction : predictions) { - if (prediction.second.type == autofill::CREDIT_CARD_VERIFICATION_CODE || - prediction.second.type == autofill::NOT_PASSWORD) { - ProcessedField* processed_field = - FindFieldWithUniqueRendererId(processed_fields, prediction.first); + for (const PasswordFieldPrediction& prediction : predictions) { + if (prediction.type == autofill::CREDIT_CARD_VERIFICATION_CODE || + prediction.type == autofill::NOT_PASSWORD) { + ProcessedField* processed_field = FindFieldWithUniqueRendererId( + processed_fields, prediction.renderer_id); if (processed_field) processed_field->server_hints_not_password = true; } @@ -868,10 +867,11 @@ return false; uint32_t username_id = significant_fields.username->unique_renderer_id; - auto it = form_predictions->find(username_id); - if (it == form_predictions->end()) - return false; - return it->second.may_use_prefilled_placeholder; + for (const PasswordFieldPrediction& prediction : *form_predictions) { + if (prediction.renderer_id == username_id) + return prediction.may_use_prefilled_placeholder; + } + return false; } // Puts together a PasswordForm, the result of the parsing, based on the
diff --git a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc index 462b1af4..894dc06 100644 --- a/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/form_parser_unittest.cc
@@ -174,8 +174,8 @@ form_data.submission_event = test_case.submission_event; for (const FieldDataDescription& field_description : test_case.fields) { FormFieldData field; - const uint32_t unique_id = GetUniqueId(); - field.unique_renderer_id = unique_id; + const uint32_t renderer_id = GetUniqueId(); + field.unique_renderer_id = renderer_id; field.id_attribute = StampUniqueSuffix("html_id"); if (field_description.name == kNonimportantValue) { field.name = StampUniqueSuffix("html_name"); @@ -199,16 +199,19 @@ field.typed_value = ASCIIToUTF16(field_description.typed_value); form_data.fields.push_back(field); if (field_description.role == ElementRole::NONE) { - UpdateResultWithIdByRole(fill_result, unique_id, + UpdateResultWithIdByRole(fill_result, renderer_id, field_description.role_filling); - UpdateResultWithIdByRole(save_result, unique_id, + UpdateResultWithIdByRole(save_result, renderer_id, field_description.role_saving); } else { - UpdateResultWithIdByRole(fill_result, unique_id, field_description.role); - UpdateResultWithIdByRole(save_result, unique_id, field_description.role); + UpdateResultWithIdByRole(fill_result, renderer_id, + field_description.role); + UpdateResultWithIdByRole(save_result, renderer_id, + field_description.role); } if (field_description.prediction.type != autofill::MAX_VALID_FIELD_TYPE) { - (*predictions)[unique_id] = field_description.prediction; + predictions->push_back(field_description.prediction); + predictions->back().renderer_id = renderer_id; } if (field_description.predicted_username >= 0) { size_t index = static_cast<size_t>(field_description.predicted_username);
diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction.cc b/components/password_manager/core/browser/form_parsing/password_field_prediction.cc index 53d62567..3cae5de 100644 --- a/components/password_manager/core/browser/form_parsing/password_field_prediction.cc +++ b/components/password_manager/core/browser/form_parsing/password_field_prediction.cc
@@ -86,9 +86,10 @@ predictions.may_use_prefilled_placeholder(); } - result[field->unique_renderer_id] = PasswordFieldPrediction{ - .type = server_type, - .may_use_prefilled_placeholder = may_use_prefilled_placeholder}; + result.push_back( + {.renderer_id = field->unique_renderer_id, + .type = server_type, + .may_use_prefilled_placeholder = may_use_prefilled_placeholder}); } }
diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction.h b/components/password_manager/core/browser/form_parsing/password_field_prediction.h index c4bb30a..50adf03e 100644 --- a/components/password_manager/core/browser/form_parsing/password_field_prediction.h +++ b/components/password_manager/core/browser/form_parsing/password_field_prediction.h
@@ -6,7 +6,7 @@ #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_FORM_PARSING_PASSWORD_FIELD_PREDICTION_H_ #include <stdint.h> -#include <map> +#include <vector> #include "components/autofill/core/browser/field_types.h" @@ -30,13 +30,14 @@ // Contains server predictions for a field. struct PasswordFieldPrediction { + uint32_t renderer_id; autofill::ServerFieldType type; bool may_use_prefilled_placeholder = false; }; // Contains server predictions for a form. Keys are unique renderer ids of // fields. -using FormPredictions = std::map<uint32_t, PasswordFieldPrediction>; +using FormPredictions = std::vector<PasswordFieldPrediction>; // Extracts all password related server predictions from |form_structure|. FormPredictions ConvertToFormPredictions(
diff --git a/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc b/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc index 3c78258..a0265ee 100644 --- a/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc +++ b/components/password_manager/core/browser/form_parsing/password_field_prediction_unittest.cc
@@ -36,6 +36,16 @@ namespace { +const PasswordFieldPrediction* FindFormPrediction( + const FormPredictions& predictions, + uint32_t renderer_id) { + for (const PasswordFieldPrediction& prediction : predictions) { + if (prediction.renderer_id == renderer_id) + return &prediction; + } + return nullptr; +} + TEST(FormPredictionsTest, ConvertToFormPredictions) { struct TestField { std::string name; @@ -85,14 +95,15 @@ for (size_t i = 0; i < base::size(test_fields); ++i) { uint32_t unique_renderer_id = form_data.fields[i].unique_renderer_id; - auto it = actual_predictions.find(unique_renderer_id); + const PasswordFieldPrediction* actual_prediction = + FindFormPrediction(actual_predictions, unique_renderer_id); if (test_fields[i].expected_type == UNKNOWN_TYPE) { - EXPECT_EQ(actual_predictions.end(), it); + EXPECT_FALSE(actual_prediction); } else { - ASSERT_NE(actual_predictions.end(), it); - EXPECT_EQ(test_fields[i].expected_type, it->second.type); + ASSERT_TRUE(actual_prediction); + EXPECT_EQ(test_fields[i].expected_type, actual_prediction->type); EXPECT_EQ(test_fields[i].may_use_prefilled_placeholder, - it->second.may_use_prefilled_placeholder); + actual_prediction->may_use_prefilled_placeholder); } } } @@ -155,9 +166,10 @@ << ", input type=" << test_form[i].input_type << ", expected type=" << test_form[i].expected_type << ", synthesised FormFieldData=" << form_data.fields[i]); - auto it = actual_predictions.find(form_data.fields[i].unique_renderer_id); - ASSERT_NE(actual_predictions.end(), it); - EXPECT_EQ(test_form[i].expected_type, it->second.type); + const PasswordFieldPrediction* actual_prediction = FindFormPrediction( + actual_predictions, form_data.fields[i].unique_renderer_id); + ASSERT_TRUE(actual_prediction); + EXPECT_EQ(test_form[i].expected_type, actual_prediction->type); } } }
diff --git a/components/password_manager/core/browser/new_password_form_manager.cc b/components/password_manager/core/browser/new_password_form_manager.cc index abe79c5..74e03072 100644 --- a/components/password_manager/core/browser/new_password_form_manager.cc +++ b/components/password_manager/core/browser/new_password_form_manager.cc
@@ -1024,6 +1024,7 @@ parsed_form->origin = form.origin; parsed_form->signon_realm = GetSignonRealm(form.origin); } + parsed_form->date_created = base::Time::Now(); if (!HasGeneratedPassword()) { votes_uploader_.set_generated_password_changed(false);
diff --git a/components/password_manager/core/browser/new_password_form_manager_unittest.cc b/components/password_manager/core/browser/new_password_form_manager_unittest.cc index acd6988..414e18d 100644 --- a/components/password_manager/core/browser/new_password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/new_password_form_manager_unittest.cc
@@ -175,7 +175,7 @@ uint32_t renderer_id = form.fields[index_prediction.first].unique_renderer_id; ServerFieldType server_type = index_prediction.second; - predictions[renderer_id] = PasswordFieldPrediction{.type = server_type}; + predictions.push_back({.renderer_id = renderer_id, .type = server_type}); } FormSignature form_signature = CalculateFormSignature(form); return {{form_signature, predictions}};
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc index ec2f994..3331be9 100644 --- a/components/password_manager/core/browser/password_form_manager.cc +++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -415,13 +415,14 @@ void PasswordFormManager::PresaveGeneratedPassword( const autofill::PasswordForm& form) { + autofill::PasswordForm mutable_form(form); + mutable_form.date_created = base::Time::Now(); if ((best_matches_.find(form.username_value) == best_matches_.end()) || form.username_value.empty()) { - form_saver()->PresaveGeneratedPassword(form); + form_saver()->PresaveGeneratedPassword(mutable_form); } else { - autofill::PasswordForm form_without_username(form); - form_without_username.username_value.clear(); - form_saver()->PresaveGeneratedPassword(form_without_username); + mutable_form.username_value.clear(); + form_saver()->PresaveGeneratedPassword(mutable_form); } if (!has_generated_password_) {
diff --git a/components/password_manager/core/browser/password_form_manager_unittest.cc b/components/password_manager/core/browser/password_form_manager_unittest.cc index 252e48b..e3f95227 100644 --- a/components/password_manager/core/browser/password_form_manager_unittest.cc +++ b/components/password_manager/core/browser/password_form_manager_unittest.cc
@@ -3265,24 +3265,21 @@ credentials.password_value = ASCIIToUTF16("password"); // Simulate the user accepted a generated password. - EXPECT_CALL(MockFormSaver::Get(form_manager()), - PresaveGeneratedPassword(credentials)); + EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_)); form_manager()->PresaveGeneratedPassword(credentials); EXPECT_TRUE(form_manager()->HasGeneratedPassword()); EXPECT_FALSE(form_manager()->generated_password_changed()); // Simulate the user changed the presaved username. credentials.username_value = ASCIIToUTF16("new_username"); - EXPECT_CALL(MockFormSaver::Get(form_manager()), - PresaveGeneratedPassword(credentials)); + EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_)); form_manager()->PresaveGeneratedPassword(credentials); EXPECT_TRUE(form_manager()->HasGeneratedPassword()); EXPECT_FALSE(form_manager()->generated_password_changed()); // Simulate the user changed the presaved password. credentials.password_value = ASCIIToUTF16("changed_password"); - EXPECT_CALL(MockFormSaver::Get(form_manager()), - PresaveGeneratedPassword(credentials)); + EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_)); form_manager()->PresaveGeneratedPassword(credentials); EXPECT_TRUE(form_manager()->HasGeneratedPassword()); EXPECT_TRUE(form_manager()->generated_password_changed()); @@ -4516,8 +4513,7 @@ credentials.username_value = ASCIIToUTF16("new_user"); credentials.password_value = ASCIIToUTF16("generatated_password"); - EXPECT_CALL(MockFormSaver::Get(form_manager()), - PresaveGeneratedPassword(credentials)); + EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_)); form_manager()->PresaveGeneratedPassword(credentials); } @@ -4534,9 +4530,12 @@ PasswordForm credentials_without_username(credentials); credentials_without_username.username_value.clear(); - EXPECT_CALL(MockFormSaver::Get(form_manager()), - PresaveGeneratedPassword(credentials_without_username)); + PasswordForm actual; + EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_)) + .WillOnce(SaveArg<0>(&actual)); form_manager()->PresaveGeneratedPassword(credentials); + credentials_without_username.date_created = actual.date_created; + EXPECT_EQ(credentials_without_username, actual); } TEST_F(PasswordFormManagerTest, PresaveGeneratedPassword_EmptyUsername) { @@ -4550,8 +4549,7 @@ credentials.username_value.clear(); credentials.password_value = ASCIIToUTF16("generatated_password"); - EXPECT_CALL(MockFormSaver::Get(form_manager()), - PresaveGeneratedPassword(credentials)); + EXPECT_CALL(MockFormSaver::Get(form_manager()), PresaveGeneratedPassword(_)); form_manager()->PresaveGeneratedPassword(credentials); }
diff --git a/components/password_manager/core/browser/password_manager_unittest.cc b/components/password_manager/core/browser/password_manager_unittest.cc index 7006db1..b02d694 100644 --- a/components/password_manager/core/browser/password_manager_unittest.cc +++ b/components/password_manager/core/browser/password_manager_unittest.cc
@@ -2178,18 +2178,23 @@ PasswordForm sanitized_form(form); SanitizeFormData(&sanitized_form.form_data); - EXPECT_CALL(*store_, AddLogin(sanitized_form)).WillOnce(Return()); + PasswordForm actual_form; + EXPECT_CALL(*store_, AddLogin(_)).WillOnce(SaveArg<0>(&actual_form)); manager()->OnPresaveGeneratedPassword(&driver_, form); + EXPECT_NE(actual_form.date_created, base::Time()); + sanitized_form.date_created = actual_form.date_created; + EXPECT_EQ(sanitized_form, actual_form); // The user updates the generated password. PasswordForm updated_form(form); updated_form.password_value = base::ASCIIToUTF16("password_12345"); PasswordForm sanitized_updated_form(updated_form); SanitizeFormData(&sanitized_updated_form.form_data); - EXPECT_CALL(*store_, - UpdateLoginWithPrimaryKey(sanitized_updated_form, sanitized_form)) - .WillOnce(Return()); + EXPECT_CALL(*store_, UpdateLoginWithPrimaryKey(_, sanitized_form)) + .WillOnce(SaveArg<0>(&actual_form)); manager()->OnPresaveGeneratedPassword(&driver_, updated_form); + sanitized_updated_form.date_created = actual_form.date_created; + EXPECT_EQ(sanitized_updated_form, actual_form); histogram_tester.ExpectUniqueSample( "PasswordManager.GeneratedFormHasNoFormManager", false, 2); @@ -2256,8 +2261,12 @@ PasswordForm presaved_form(form); if (found_matched_logins_in_store) presaved_form.username_value.clear(); - EXPECT_CALL(*store_, AddLogin(presaved_form)).WillOnce(Return()); + PasswordForm actual_form; + EXPECT_CALL(*store_, AddLogin(_)).WillOnce(SaveArg<0>(&actual_form)); manager()->OnPresaveGeneratedPassword(&driver_, form); + EXPECT_NE(actual_form.date_created, base::Time()); + presaved_form.date_created = actual_form.date_created; + EXPECT_EQ(presaved_form, actual_form); ::testing::Mock::VerifyAndClearExpectations(store_.get()); EXPECT_CALL(*store_, IsAbleToSavePasswords()).WillRepeatedly(Return(true));
diff --git a/components/password_manager/core/browser/password_ui_utils.cc b/components/password_manager/core/browser/password_ui_utils.cc index 8e4cf6a..93b1993 100644 --- a/components/password_manager/core/browser/password_ui_utils.cc +++ b/components/password_manager/core/browser/password_ui_utils.cc
@@ -8,11 +8,14 @@ #include <string> #include <vector> +#include "base/metrics/histogram_macros.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.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_form_manager_for_ui.h" +#include "components/password_manager/core/browser/password_form_metrics_recorder.h" #include "components/url_formatter/elide_url.h" namespace password_manager { @@ -71,4 +74,38 @@ : original; } +void UpdatePasswordFormUsernameAndPassword( + const base::string16& username, + const base::string16& password, + PasswordFormManagerForUI* form_manager) { + const auto& pending_credentials = form_manager->GetPendingCredentials(); + bool username_edited = pending_credentials.username_value != username; + bool password_changed = pending_credentials.password_value != password; + if (username_edited) { + form_manager->UpdateUsername(username); + if (form_manager->GetMetricsRecorder()) { + form_manager->GetMetricsRecorder()->RecordDetailedUserAction( + password_manager::PasswordFormMetricsRecorder::DetailedUserAction:: + kEditedUsernameInBubble); + } + } + if (password_changed) { + form_manager->UpdatePasswordValue(password); + if (form_manager->GetMetricsRecorder()) { + form_manager->GetMetricsRecorder()->RecordDetailedUserAction( + password_manager::PasswordFormMetricsRecorder::DetailedUserAction:: + kSelectedDifferentPasswordInBubble); + } + } + + // Values of this histogram are a bit mask. Only the lower two bits are used: + // 0001 to indicate that the user has edited the username in the password save + // bubble. + // 0010 to indicate that the user has changed the password in the + // password save bubble. + // The maximum possible value is defined by OR-ing these values. + UMA_HISTOGRAM_ENUMERATION("PasswordManager.EditsInSaveBubble", + username_edited + 2 * password_changed, 4); +} + } // namespace password_manager
diff --git a/components/password_manager/core/browser/password_ui_utils.h b/components/password_manager/core/browser/password_ui_utils.h index b4d98c8c..18a4fd7 100644 --- a/components/password_manager/core/browser/password_ui_utils.h +++ b/components/password_manager/core/browser/password_ui_utils.h
@@ -20,6 +20,8 @@ namespace password_manager { +class PasswordFormManagerForUI; + // Reverses order of labels in hostname. std::string SplitByDotAndReverse(base::StringPiece host); @@ -41,6 +43,13 @@ // |password_form|) and without prefixes "m.", "mobile." or "www.". std::string GetShownOrigin(const GURL& origin); +// Updates the |form_manager| pending credentials with |username| and +// |password|. +void UpdatePasswordFormUsernameAndPassword( + const base::string16& username, + const base::string16& password, + PasswordFormManagerForUI* form_manager); + } // namespace password_manager #endif // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_UI_UTILS_H_
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json index fcfb2c0..3ba1c52 100644 --- a/components/policy/resources/policy_templates.json +++ b/components/policy/resources/policy_templates.json
@@ -15330,6 +15330,27 @@ If this policy is not set, or if its value does not map to a Quick Fix Build, then the device won't be updated to a Quick Fix Build. If the device is already running a Quick Fix Build and the policy is not set anymore or its value does not map to a Quick Fix Build anymore, then the device will be updated to a regular build if the update is not blocked by another policy.''', }, + { + 'name': 'SamlInSessionPasswordChangeEnabled', + 'type': 'main', + 'schema': { 'type': 'boolean' }, + 'supported_on': ['chrome_os:76-'], + 'future': True, + 'tags': [], + 'features': { + 'dynamic_refresh': True, + 'per_profile': False, + }, + 'example_value': True, + 'id': 545, + 'caption': '''Enables a page for in-session change of password for SAML users.''', + 'desc': '''Enables a page at chrome://password-change that lets SAML users change their SAML passwords while in-session, which ensures that the SAML password and the device lockscreen password are kept in-sync. + + This policy also enables notifications that warn SAML users if their SAML passwords are soon to expire so that they can deal with this immediately by doing an in-session password change. + But, these notifications will only be shown if password expiry information is sent to the device by the SAML identity provider during the SAML login flow. + + If this policy is set, the user cannot change or override it.''', + }, ], 'messages': { @@ -15495,5 +15516,5 @@ }, 'placeholders': [], 'deleted_policy_ids': [412], - 'highest_id_currently_used': 544 + 'highest_id_currently_used': 545 }
diff --git a/components/previews/content/BUILD.gn b/components/previews/content/BUILD.gn index 70e8cc8..6c28495 100644 --- a/components/previews/content/BUILD.gn +++ b/components/previews/content/BUILD.gn
@@ -8,6 +8,8 @@ "hint_cache.h", "hint_cache_store.cc", "hint_cache_store.h", + "hint_update_data.cc", + "hint_update_data.h", "hints_fetcher.cc", "hints_fetcher.h", "previews_decider_impl.cc", @@ -45,6 +47,7 @@ sources = [ "hint_cache_store_unittest.cc", "hint_cache_unittest.cc", + "hint_update_data_unittest.cc", "hints_fetcher_unittest.cc", "previews_decider_impl_unittest.cc", "previews_hints_unittest.cc",
diff --git a/components/previews/content/hint_cache_store.h b/components/previews/content/hint_cache_store.h index b25b9cd..c5310dd5 100644 --- a/components/previews/content/hint_cache_store.h +++ b/components/previews/content/hint_cache_store.h
@@ -139,6 +139,7 @@ private: friend class HintCacheStoreTest; + friend class HintUpdateData; using EntryKeyPrefix = std::string; using EntryKeySet = std::unordered_set<EntryKey>;
diff --git a/components/previews/content/hint_update_data.cc b/components/previews/content/hint_update_data.cc new file mode 100644 index 0000000..6375b14b --- /dev/null +++ b/components/previews/content/hint_update_data.cc
@@ -0,0 +1,84 @@ +// Copyright 2019 The Chromium Authors. 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/previews/content/hint_update_data.h" + +#include "components/optimization_guide/proto/hints.pb.h" +#include "components/previews/content/hint_cache_store.h" +#include "components/previews/content/proto/hint_cache.pb.h" + +namespace previews { + +// static +std::unique_ptr<HintUpdateData> HintUpdateData::CreateComponentHintUpdateData( + const base::Version& component_version) { + std::unique_ptr<HintUpdateData> update_data( + new HintUpdateData(base::Optional<base::Version>(component_version), + base::Optional<base::Time>())); + return update_data; +} + +// static +std::unique_ptr<HintUpdateData> HintUpdateData::CreateFetchedHintUpdateData( + base::Time fetch_update_time) { + std::unique_ptr<HintUpdateData> update_data( + new HintUpdateData(base::Optional<base::Version>(), + base::Optional<base::Time>(fetch_update_time))); + return update_data; +} + +HintUpdateData::HintUpdateData(base::Optional<base::Version> component_version, + base::Optional<base::Time> fetch_update_time) + : component_version_(component_version), + fetch_update_time_(fetch_update_time), + entries_to_save_(std::make_unique<EntryVector>()) { + DCHECK_NE(!component_version_, !fetch_update_time_); + + if (component_version_.has_value()) { + hint_entry_key_prefix_ = + HintCacheStore::GetComponentHintEntryKeyPrefix(*component_version_); + + // Add a component metadata entry for the component's version. + previews::proto::StoreEntry metadata_component_entry; + metadata_component_entry.set_version(component_version_->GetString()); + entries_to_save_->emplace_back( + HintCacheStore::GetMetadataTypeEntryKey( + HintCacheStore::MetadataType::kComponent), + std::move(metadata_component_entry)); + } else if (fetch_update_time_.has_value()) { + hint_entry_key_prefix_ = + // TODO(dougarnett): Merge in new call once landed: + // HintCacheStore::GetFetchedHintEntryKeyPrefix(); + "3_"; + + // TODO(dougarnett): add metadata entry for Fetch update? + } else { + NOTREACHED(); + } +} + +HintUpdateData::~HintUpdateData() {} + +void HintUpdateData::MoveHintIntoUpdateData( + optimization_guide::proto::Hint&& hint) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(!hint_entry_key_prefix_.empty()); + + // To avoid any unnecessary copying, the hint is moved into proto::StoreEntry. + HintCacheStore::EntryKey hint_entry_key = hint_entry_key_prefix_ + hint.key(); + previews::proto::StoreEntry entry_proto; + entry_proto.set_allocated_hint( + new optimization_guide::proto::Hint(std::move(hint))); + entries_to_save_->emplace_back(std::move(hint_entry_key), + std::move(entry_proto)); +} + +std::unique_ptr<EntryVector> HintUpdateData::TakeUpdateEntries() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + DCHECK(entries_to_save_); + + return std::move(entries_to_save_); +} + +} // namespace previews
diff --git a/components/previews/content/hint_update_data.h b/components/previews/content/hint_update_data.h new file mode 100644 index 0000000..7a6f153 --- /dev/null +++ b/components/previews/content/hint_update_data.h
@@ -0,0 +1,85 @@ +// Copyright 2019 The Chromium Authors. 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_PREVIEWS_CONTENT_HINT_UPDATE_DATA_H_ +#define COMPONENTS_PREVIEWS_CONTENT_HINT_UPDATE_DATA_H_ + +#include <string> + +#include "base/macros.h" +#include "base/optional.h" +#include "base/sequence_checker.h" +#include "base/time/time.h" +#include "base/version.h" +#include "components/leveldb_proto/public/proto_database.h" + +namespace optimization_guide { +namespace proto { +class Hint; +} // namespace proto +} // namespace optimization_guide + +namespace previews { +namespace proto { +class StoreEntry; +} // namespace proto + +using EntryVector = + leveldb_proto::ProtoDatabase<previews::proto::StoreEntry>::KeyEntryVector; + +// Holds hint data for updating the HintCacheStore. +class HintUpdateData { + public: + ~HintUpdateData(); + + // Creates an update data object for a component hint update. + static std::unique_ptr<HintUpdateData> CreateComponentHintUpdateData( + const base::Version& component_version); + + // Creates an update data object for a fetched hint update. + static std::unique_ptr<HintUpdateData> CreateFetchedHintUpdateData( + base::Time fetch_update_time); + + // Returns the component version of a component hint update. + const base::Optional<base::Version> component_version() const { + return component_version_; + } + + // Returns the next update time for a fetched hint update. + const base::Optional<base::Time> fetch_update_time() const { + return fetch_update_time_; + } + + // Moves |hint| into this update data. After MoveHintIntoUpdateData() is + // called, |hint| is no longer valid. + void MoveHintIntoUpdateData(optimization_guide::proto::Hint&& hint); + + // Returns the store entry updates along with ownership to them. + std::unique_ptr<EntryVector> TakeUpdateEntries(); + + private: + HintUpdateData(base::Optional<base::Version> component_version, + base::Optional<base::Time> fetch_update_time); + + // The component version of the update data for a component update. + base::Optional<base::Version> component_version_; + + // The time when hints in this update need to be updated for a fetch update. + base::Optional<base::Time> fetch_update_time_; + + // The prefix to add to the key of every hint entry. It is set + // during construction for appropriate type of update. + std::string hint_entry_key_prefix_; + + // The vector of entries to save. + std::unique_ptr<EntryVector> entries_to_save_; + + SEQUENCE_CHECKER(sequence_checker_); + + DISALLOW_COPY_AND_ASSIGN(HintUpdateData); +}; + +} // namespace previews + +#endif // COMPONENTS_PREVIEWS_CONTENT_HINT_UPDATE_DATA_H_
diff --git a/components/previews/content/hint_update_data_unittest.cc b/components/previews/content/hint_update_data_unittest.cc new file mode 100644 index 0000000..a177d1a --- /dev/null +++ b/components/previews/content/hint_update_data_unittest.cc
@@ -0,0 +1,70 @@ +// Copyright 2019 The Chromium Authors. 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/previews/content/hint_update_data.h" + +#include <string> +#include <vector> + +#include "base/macros.h" +#include "base/time/time.h" +#include "base/version.h" +#include "components/optimization_guide/proto/hints.pb.h" +#include "components/previews/content/proto/hint_cache.pb.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace previews { + +namespace { + +TEST(HintUpdateDataTest, BuildComponentUpdateData) { + // Verify creating a Component Hint update package. + base::Version v1("1.2.3.4"); + optimization_guide::proto::Hint hint1; + hint1.set_key("foo.org"); + hint1.set_key_representation(optimization_guide::proto::HOST_SUFFIX); + optimization_guide::proto::PageHint* page_hint1 = hint1.add_page_hints(); + page_hint1->set_page_pattern("slowpage"); + optimization_guide::proto::Hint hint2; + hint2.set_key("bar.com"); + hint2.set_key_representation(optimization_guide::proto::HOST_SUFFIX); + optimization_guide::proto::PageHint* page_hint2 = hint2.add_page_hints(); + page_hint2->set_page_pattern("slowpagealso"); + + std::unique_ptr<HintUpdateData> component_update = + HintUpdateData::CreateComponentHintUpdateData(v1); + component_update->MoveHintIntoUpdateData(std::move(hint1)); + component_update->MoveHintIntoUpdateData(std::move(hint2)); + EXPECT_TRUE(component_update->component_version().has_value()); + EXPECT_FALSE(component_update->fetch_update_time().has_value()); + EXPECT_EQ(v1, *component_update->component_version()); + // Verify there are 3 store entries: 1 for the metadata entry plus + // the 2 added hint entries. + EXPECT_EQ(3ul, component_update->TakeUpdateEntries()->size()); +} + +TEST(HintUpdateDataTest, BuildFetchUpdateData) { + // Verify creating a Fetched Hint update package. + base::Time update_time = base::Time::Now(); + optimization_guide::proto::Hint hint1; + hint1.set_key("foo.org"); + hint1.set_key_representation(optimization_guide::proto::HOST_SUFFIX); + optimization_guide::proto::PageHint* page_hint1 = hint1.add_page_hints(); + page_hint1->set_page_pattern("slowpage"); + + std::unique_ptr<HintUpdateData> fetch_update = + HintUpdateData::CreateFetchedHintUpdateData(update_time); + fetch_update->MoveHintIntoUpdateData(std::move(hint1)); + EXPECT_FALSE(fetch_update->component_version().has_value()); + EXPECT_TRUE(fetch_update->fetch_update_time().has_value()); + EXPECT_EQ(update_time, *fetch_update->fetch_update_time()); + // Verify there are 2 store entries: 1 for the metadata entry plus + // the 1 added hint entries. + // TODO(dougarnett): Increase expected count once metadata support added. + EXPECT_EQ(1ul, fetch_update->TakeUpdateEntries()->size()); +} + +} // namespace + +} // namespace previews
diff --git a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css index 59d5f17..f83991e 100644 --- a/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css +++ b/components/supervised_user_error_page/resources/supervised_user_block_interstitial.css
@@ -313,15 +313,6 @@ transition: opacity 250ms cubic-bezier(0.4, 0, 0.2, 1); } - #details[hidden], - #information-container[hidden] { - display: block; - height: 0; - opacity: 0; - overflow: hidden; - transition: none; - } - .details-button { padding-bottom: 16px; padding-top: 16px;
diff --git a/components/sync/base/DEPS b/components/sync/base/DEPS index 1f826747..eca6939 100644 --- a/components/sync/base/DEPS +++ b/components/sync/base/DEPS
@@ -10,5 +10,5 @@ "+crypto", "+google/cacheinvalidation", "+third_party/zlib", # For UniquePosition compression - "+net/base", + "+net", ]
diff --git a/components/sync/base/syncer_error.cc b/components/sync/base/syncer_error.cc index 43496640..ede7462 100644 --- a/components/sync/base/syncer_error.cc +++ b/components/sync/base/syncer_error.cc
@@ -5,7 +5,9 @@ #include "components/sync/base/syncer_error.h" #include "base/logging.h" +#include "base/strings/string_number_conversions.h" #include "net/base/net_errors.h" +#include "net/http/http_status_code.h" namespace syncer { @@ -47,12 +49,38 @@ } // namespace +SyncerError::SyncerError(Value value) : value_(value) { + // NETWORK_CONNECTION_UNAVAILABLE error must be created via the separate + // factory method NetworkConnectionUnavailable(). + DCHECK_NE(value_, NETWORK_CONNECTION_UNAVAILABLE); + // SYNC_SERVER_ERROR and SYNC_AUTH_ERROR both correspond to HTTP errors, and + // must be created via HttpError(). + DCHECK_NE(value_, SYNC_SERVER_ERROR); + DCHECK_NE(value_, SYNC_AUTH_ERROR); +} + +// static +SyncerError SyncerError::NetworkConnectionUnavailable(int net_error_code) { + return SyncerError(NETWORK_CONNECTION_UNAVAILABLE, net_error_code, + /*http_status_code=*/0); +} + +// static +SyncerError SyncerError::HttpError(int http_status_code) { + return SyncerError((http_status_code == net::HTTP_UNAUTHORIZED) + ? SYNC_AUTH_ERROR + : SYNC_SERVER_ERROR, + /*net_error_code=*/0, http_status_code); +} + std::string SyncerError::ToString() const { - if (value_ != NETWORK_CONNECTION_UNAVAILABLE) { - return GetSyncerErrorString(value_); + std::string result = GetSyncerErrorString(value_); + if (value_ == NETWORK_CONNECTION_UNAVAILABLE) { + result += " (" + net::ErrorToShortString(net_error_code_) + ")"; + } else if (value_ == SYNC_SERVER_ERROR || value_ == SYNC_AUTH_ERROR) { + result += " (HTTP " + base::NumberToString(http_status_code_) + ")"; } - return GetSyncerErrorString(value_) + " (" + - net::ErrorToShortString(net_error_code_) + ")"; + return result; } bool SyncerError::IsActualError() const {
diff --git a/components/sync/base/syncer_error.h b/components/sync/base/syncer_error.h index a6c9495..04edb6ed 100644 --- a/components/sync/base/syncer_error.h +++ b/components/sync/base/syncer_error.h
@@ -25,6 +25,7 @@ SYNC_AUTH_ERROR, // HTTP auth error. // Based on values returned by server. Most are defined in sync.proto. + // TODO(crbug.com/951350): Unused, remove. SERVER_RETURN_INVALID_CREDENTIAL, SERVER_RETURN_UNKNOWN_ERROR, SERVER_RETURN_THROTTLED, @@ -35,6 +36,7 @@ SERVER_RETURN_CONFLICT, SERVER_RESPONSE_VALIDATION_FAILED, SERVER_RETURN_DISABLED_BY_ADMIN, + // TODO(crbug.com/951350): Unused, remove. SERVER_RETURN_USER_ROLLBACK, SERVER_RETURN_PARTIAL_FAILURE, SERVER_RETURN_CLIENT_DATA_OBSOLETE, @@ -47,19 +49,14 @@ SYNCER_OK }; - constexpr SyncerError() : value_(UNSET), net_error_code_(0) {} + constexpr SyncerError() {} + // Note: NETWORK_CONNECTION_UNAVAILABLE, SYNC_SERVER_ERROR, and + // SYNC_AUTH_ERROR are *not* valid inputs for this constructor. These types + // of errors must be created via the factory functions below. + explicit SyncerError(Value value); - explicit constexpr SyncerError(Value value) - : value_(value), net_error_code_(0) { - // NETWORK_CONNECTION_UNAVAILABLE error must be created via the separate - // factory method NetworkConnectionUnavailable(). - DCHECK_NE(value_, NETWORK_CONNECTION_UNAVAILABLE); - } - - static constexpr SyncerError NetworkConnectionUnavailable( - int net_error_code) { - return SyncerError(NETWORK_CONNECTION_UNAVAILABLE, net_error_code); - } + static SyncerError NetworkConnectionUnavailable(int net_error_code); + static SyncerError HttpError(int http_status_code); Value value() const { return value_; } @@ -70,11 +67,14 @@ bool IsActualError() const; private: - constexpr SyncerError(Value value, int net_error_code) - : value_(value), net_error_code_(net_error_code) {} + constexpr SyncerError(Value value, int net_error_code, int http_status_code) + : value_(value), + net_error_code_(net_error_code), + http_status_code_(http_status_code) {} - Value value_; - int net_error_code_; + Value value_ = UNSET; + int net_error_code_ = 0; + int http_status_code_ = 0; }; } // namespace syncer
diff --git a/components/sync/engine_impl/backoff_delay_provider_unittest.cc b/components/sync/engine_impl/backoff_delay_provider_unittest.cc index db5dff0..49104887 100644 --- a/components/sync/engine_impl/backoff_delay_provider_unittest.cc +++ b/components/sync/engine_impl/backoff_delay_provider_unittest.cc
@@ -10,6 +10,7 @@ #include "components/sync/engine/cycle/model_neutral_state.h" #include "components/sync/engine/polling_constants.h" #include "net/base/net_errors.h" +#include "net/http/http_status_code.h" #include "testing/gtest/include/gtest/gtest.h" using base::TimeDelta; @@ -39,7 +40,8 @@ std::unique_ptr<BackoffDelayProvider> delay( BackoffDelayProvider::FromDefaults()); ModelNeutralState state; - state.last_get_key_result = SyncerError(SyncerError::SYNC_SERVER_ERROR); + state.last_get_key_result = + SyncerError::HttpError(net::HTTP_INTERNAL_SERVER_ERROR); EXPECT_EQ(kInitialBackoffRetrySeconds, delay->GetInitialDelay(state).InSeconds()); @@ -96,7 +98,8 @@ std::unique_ptr<BackoffDelayProvider> delay( BackoffDelayProvider::WithShortInitialRetryOverride()); ModelNeutralState state; - state.last_get_key_result = SyncerError(SyncerError::SYNC_SERVER_ERROR); + state.last_get_key_result = + SyncerError::HttpError(net::HTTP_INTERNAL_SERVER_ERROR); EXPECT_EQ(kInitialBackoffShortRetrySeconds, delay->GetInitialDelay(state).InSeconds());
diff --git a/components/sync/engine_impl/cycle/status_controller_unittest.cc b/components/sync/engine_impl/cycle/status_controller_unittest.cc index 64b0da8..c90ca69 100644 --- a/components/sync/engine_impl/cycle/status_controller_unittest.cc +++ b/components/sync/engine_impl/cycle/status_controller_unittest.cc
@@ -4,6 +4,7 @@ #include "components/sync/engine_impl/cycle/sync_cycle.h" #include "components/sync/test/engine/test_id_factory.h" +#include "net/http/http_status_code.h" #include "testing/gtest/include/gtest/gtest.h" namespace syncer { @@ -20,7 +21,7 @@ EXPECT_EQ(SyncerError::SYNCER_OK, status.model_neutral_state().last_download_updates_result.value()); - status.set_commit_result(SyncerError(SyncerError::SYNC_AUTH_ERROR)); + status.set_commit_result(SyncerError::HttpError(net::HTTP_UNAUTHORIZED)); EXPECT_EQ(SyncerError::SYNC_AUTH_ERROR, status.model_neutral_state().commit_result.value());
diff --git a/components/sync/engine_impl/net/server_connection_manager.h b/components/sync/engine_impl/net/server_connection_manager.h index aa41b48..cce4a3da 100644 --- a/components/sync/engine_impl/net/server_connection_manager.h +++ b/components/sync/engine_impl/net/server_connection_manager.h
@@ -172,6 +172,11 @@ return server_response_.net_error_code; } + inline int http_status_code() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return server_response_.http_status_code; + } + const std::string client_id() const { return client_id_; } // Factory method to create an Connection object we can use for @@ -194,7 +199,7 @@ protected: inline std::string proto_sync_path() const { return proto_sync_path_; } - // Updates server_response_ and notifies listeners if the server status + // Updates |server_response_| and notifies listeners if the server status // changed. void SetServerResponse(const HttpResponse& server_response);
diff --git a/components/sync/engine_impl/sync_manager_impl.cc b/components/sync/engine_impl/sync_manager_impl.cc index 6649ffb..140f949 100644 --- a/components/sync/engine_impl/sync_manager_impl.cc +++ b/components/sync/engine_impl/sync_manager_impl.cc
@@ -305,11 +305,6 @@ std::move(backing_store), args->unrecoverable_error_handler, report_unrecoverable_error_function_, sync_encryption_handler_.get(), sync_encryption_handler_->GetCryptographerUnsafe()); - share_.sync_credentials = args->credentials; - - // UserShare is accessible to a lot of code that doesn't need access to the - // access token, so clear it from the UserShare. - share_.sync_credentials.access_token = ""; DVLOG(1) << "Username: " << args->credentials.email; DVLOG(1) << "AccountId: " << args->credentials.account_id;
diff --git a/components/sync/engine_impl/syncer_proto_util.cc b/components/sync/engine_impl/syncer_proto_util.cc index 2f090fc3..6706d02 100644 --- a/components/sync/engine_impl/syncer_proto_util.cc +++ b/components/sync/engine_impl/syncer_proto_util.cc
@@ -104,7 +104,8 @@ SyncerError ServerConnectionErrorAsSyncerError( const HttpResponse::ServerConnectionCode server_status, - int net_error_code) { + int net_error_code, + int http_status_code) { switch (server_status) { case HttpResponse::CONNECTION_UNAVAILABLE: return SyncerError::NetworkConnectionUnavailable(net_error_code); @@ -112,10 +113,10 @@ return SyncerError(SyncerError::NETWORK_IO_ERROR); case HttpResponse::SYNC_SERVER_ERROR: // This means the server returned a non-401 HTTP error. - return SyncerError(SyncerError::SYNC_SERVER_ERROR); + return SyncerError::HttpError(http_status_code); case HttpResponse::SYNC_AUTH_ERROR: // This means the server returned an HTTP 401 (unauthorized) error. - return SyncerError(SyncerError::SYNC_AUTH_ERROR); + return SyncerError::HttpError(http_status_code); case HttpResponse::SERVER_CONNECTION_OK: case HttpResponse::NONE: default: @@ -467,8 +468,8 @@ DCHECK_NE(server_status, HttpResponse::SERVER_CONNECTION_OK); return ServerConnectionErrorAsSyncerError( - server_status, - cycle->context()->connection_manager()->net_error_code()); + server_status, cycle->context()->connection_manager()->net_error_code(), + cycle->context()->connection_manager()->http_status_code()); } LogClientToServerResponse(*response);
diff --git a/components/sync/syncable/user_share.h b/components/sync/syncable/user_share.h index 40e1975..ad010e66 100644 --- a/components/sync/syncable/user_share.h +++ b/components/sync/syncable/user_share.h
@@ -6,9 +6,6 @@ #define COMPONENTS_SYNC_SYNCABLE_USER_SHARE_H_ #include <memory> -#include <string> - -#include "components/sync/engine/sync_credentials.h" namespace syncer { @@ -26,11 +23,6 @@ // The Directory itself, which is the parent of Transactions. std::unique_ptr<syncable::Directory> directory; - - // The credentials used by sync when talking to the sync server. - // - // Note: some or all of the sync_credentials fields may be empty. - SyncCredentials sync_credentials; }; } // namespace syncer
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 index 16e2e79..1fa6b8b3 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -b40bf386e25ce91aafc019d40a661189a7a47843 \ No newline at end of file +39fa511aadaac5698e0b3e5cbe5048c67a65a2eb \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 index a8129bb..2c45471 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.camera_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -ab606d4139fae91bf4f73f28b6a521ed3eec2a61 \ No newline at end of file +eff215b2df47cdcde486b64911f874112476cedd \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 index 0724fbd47..80c59a3 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -34a24dac8faed5c449b3cefa771251322048d5ae \ No newline at end of file +a83f38ff015b54d6c44c7b3469ecec711a771218 \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 index 0e636c0..3f01627 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.location_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -05c4244fd0044437c4b39dbf30ddedd9af27b72b \ No newline at end of file +4dfeebd17cd6bdc47bf5721a198b414a80081548 \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-25.png.sha1 index b1127d8..266edb3 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -1d39625008d14a1b6205b8163e9966b359863be6 \ No newline at end of file +8c8b2ccdd9c67d3eeb58a2e8b5695bfb035c0173 \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-26.png.sha1 index 4ef0b181..075bc11 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_incognito_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -d4f9cbe2b0d12c55807fdafef90e7c4823563843 \ No newline at end of file +a3a0894dcae57e0b619d3dfae4e2dcc244d03ad2 \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-25.png.sha1 index 146dd944..1f6b55b8 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -dba7354dd9ee806e6d147a11e6ac47c948c4cf4e \ No newline at end of file +8d5871d82eac0fd7cae759e1aa6232f75d508018 \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-26.png.sha1 index cde34b2..8a8d5dc 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_reposition_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -80d577d491ec4ff26236829dc864ec8d5e9dac33 \ No newline at end of file +c6889ab587ebf97338206d4a2d496c1e587f096f \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 index 8d5d31e..23066645 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -e64e29cd5895cdae8a876522ffa1e96887ee3a98 \ No newline at end of file +97da7a119bb4434f7a67b82763d7cd5689748101 \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 index acd6318..2fb9c11 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.microphone_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -e663adf5c61e38ca5c28d8fc6d2bbd979e77245f \ No newline at end of file +6502add492f33d0e76660f6bd72999ef0eecc16f \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 index 73055c8..042e48f 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -a7cf4544187917199e869ea4e0f6950d81ef0bf8 \ No newline at end of file +7a4c548129116530661e27696a5e0dbae793bb9e \ No newline at end of file
diff --git a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 index 92d7ee75..24bc30a 100644 --- a/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1 +++ b/components/test/data/permission_dialogs/render_tests/VrBrowserDialogTest.notification_permission_prompt_visible_browser_ui.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -ae0c048df4c4179c85e13ce30c12543c9cea04bc \ No newline at end of file +2028868199c33d43de706c8607e3af64909784b7 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-25.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-25.png.sha1 index 8c837bc..e962bc35 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-25.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-25.png.sha1
@@ -1 +1 @@ -578b0246815fdd37d5851dabae6aa84a4e4b4a23 \ No newline at end of file +a07778983e1f124108e56837861fac2bd264dfe6 \ No newline at end of file
diff --git a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-26.png.sha1 b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-26.png.sha1 index 76888eb..052764e6 100644 --- a/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-26.png.sha1 +++ b/components/test/data/vr_browser_ui/render_tests/VrBrowserNativeUiTest.reposition_bar_permission_prompt_open.Pixel_XL-26.png.sha1
@@ -1 +1 @@ -561610e9945cd3ff1b052f714189b474a4fa1e97 \ No newline at end of file +aa638ae756981acc3f5100c64cab60ddddc8d73a \ No newline at end of file
diff --git a/components/ukm/content/source_url_recorder_browsertest.cc b/components/ukm/content/source_url_recorder_browsertest.cc index e61b3b2c..ff755a6 100644 --- a/components/ukm/content/source_url_recorder_browsertest.cc +++ b/components/ukm/content/source_url_recorder_browsertest.cc
@@ -161,8 +161,9 @@ EXPECT_NE(source->id(), ukm_entries[1]->source_id); } +// Flaky on all OSes: https://crbug.com/951020 IN_PROC_BROWSER_TEST_F(SourceUrlRecorderWebContentsObserverDownloadBrowserTest, - IgnoreDownload) { + DISABLED_IgnoreDownload) { GURL url(embedded_test_server()->GetURL("/download-test1.lib")); content::NavigationHandleObserver observer(shell()->web_contents(), url); content::NavigateToURL(shell(), url);
diff --git a/content/browser/fileapi/file_system_browsertest.cc b/content/browser/fileapi/file_system_browsertest.cc index 3ff81a5a..863ac7c 100644 --- a/content/browser/fileapi/file_system_browsertest.cc +++ b/content/browser/fileapi/file_system_browsertest.cc
@@ -11,6 +11,7 @@ #include "base/memory/ref_counted.h" #include "base/single_thread_task_runner.h" #include "base/task/post_task.h" +#include "base/test/scoped_feature_list.h" #include "base/test/thread_test_helper.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/browser_context.h" @@ -22,6 +23,7 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" +#include "storage/browser/fileapi/file_system_features.h" #include "storage/browser/quota/quota_manager.h" using storage::QuotaManager; @@ -30,11 +32,16 @@ // This browser test is aimed towards exercising the File System API bindings // and the actual implementation that lives in the browser side. -class FileSystemBrowserTest : public ContentBrowserTest { +class FileSystemBrowserTest : public ContentBrowserTest, + public testing::WithParamInterface<bool> { public: - FileSystemBrowserTest() {} + FileSystemBrowserTest() { + feature_list_.InitAndEnableFeature( + storage::features::kEnableFilesystemInIncognito); + } - void SimpleTest(const GURL& test_url, bool incognito = false) { + void SimpleTest(const GURL& test_url) { + const bool incognito = GetParam(); // The test page will perform tests on FileAPI, then navigate to either // a #pass or #fail ref. Shell* the_browser = incognito ? CreateOffTheRecordBrowser() : shell(); @@ -52,8 +59,13 @@ FAIL() << "Failed: " << js_result; } } + + protected: + base::test::ScopedFeatureList feature_list_; }; +INSTANTIATE_TEST_SUITE_P(, FileSystemBrowserTest, ::testing::Bool()); + class FileSystemBrowserTestWithLowQuota : public FileSystemBrowserTest { public: void SetUpOnMainThread() override { @@ -81,15 +93,21 @@ } }; -IN_PROC_BROWSER_TEST_F(FileSystemBrowserTest, RequestTest) { +// TODO(https://crbug.com/93417): Expand the test after updating quota +// managenent for in-memory implementation. +INSTANTIATE_TEST_SUITE_P(, + FileSystemBrowserTestWithLowQuota, + ::testing::Values(false)); + +IN_PROC_BROWSER_TEST_P(FileSystemBrowserTest, RequestTest) { SimpleTest(GetTestUrl("fileapi", "request_test.html")); } -IN_PROC_BROWSER_TEST_F(FileSystemBrowserTest, CreateTest) { +IN_PROC_BROWSER_TEST_P(FileSystemBrowserTest, CreateTest) { SimpleTest(GetTestUrl("fileapi", "create_test.html")); } -IN_PROC_BROWSER_TEST_F(FileSystemBrowserTestWithLowQuota, QuotaTest) { +IN_PROC_BROWSER_TEST_P(FileSystemBrowserTestWithLowQuota, QuotaTest) { SimpleTest(GetTestUrl("fileapi", "quota_test.html")); }
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 9cafebc..35f0356 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -410,41 +410,15 @@ int32_t routing_id, mojom::WidgetPtr widget, bool hidden) - : renderer_initialized_(false), - destroyed_(false), - delegate_(delegate), - owner_delegate_(nullptr), + : delegate_(delegate), process_(process), routing_id_(routing_id), clock_(base::DefaultTickClock::GetInstance()), - is_loading_(false), is_hidden_(hidden), - visual_properties_ack_pending_(false), - auto_resize_enabled_(false), - page_scale_factor_(1.f), - is_pinch_gesture_active_(false), - waiting_for_screen_rects_ack_(false), - is_unresponsive_(false), - in_flight_event_count_(0), - in_get_backing_store_(false), - text_direction_updated_(false), - text_direction_(blink::kWebTextDirectionLeftToRight), - text_direction_canceled_(false), - suppress_events_until_keydown_(false), - pending_mouse_lock_request_(false), - allow_privileged_mouse_lock_(false), - is_last_unlocked_by_target_(false), - has_touch_handler_(false), - is_in_touchpad_gesture_fling_(false), latency_tracker_(delegate_), - next_browser_snapshot_id_(1), - owned_by_render_frame_host_(false), - is_focused_(false), hung_renderer_delay_(TimeDelta::FromMilliseconds(kHungRendererDelayMs)), new_content_rendering_delay_( TimeDelta::FromMilliseconds(kNewContentRenderingDelayMs)), - current_content_source_id_(0), - monitoring_composition_info_(false), compositor_frame_sink_binding_(this), frame_token_message_queue_( std::make_unique<FrameTokenMessageQueue>(this)),
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index e6d6317..0cd8ae71 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -964,17 +964,17 @@ // true if a renderer has once been valid. We use this flag to display a sad // tab only when we lose our renderer and not if a paint occurs during // initialization. - bool renderer_initialized_; + bool renderer_initialized_ = false; // True if |Destroy()| has been called. - bool destroyed_; + bool destroyed_ = false; // Our delegate, which wants to know mainly about keyboard events. // It will remain non-NULL until DetachDelegate() is called. RenderWidgetHostDelegate* delegate_; // The delegate of the owner of this object. - RenderWidgetHostOwnerDelegate* owner_delegate_; + RenderWidgetHostOwnerDelegate* owner_delegate_ = nullptr; // Created during construction and guaranteed never to be NULL, but its // channel may be NULL if the renderer crashed, so one must always check that. @@ -987,7 +987,7 @@ const base::TickClock* clock_; // Indicates whether a page is loading or not. - bool is_loading_; + bool is_loading_ = false; // Indicates whether a page is hidden or not. Need to call // process_->UpdateClientPriority when this value changes. @@ -1008,14 +1008,14 @@ #endif // True when waiting for visual_properties_ack. - bool visual_properties_ack_pending_; + bool visual_properties_ack_pending_ = false; // Visual properties that were most recently sent to the renderer. std::unique_ptr<VisualProperties> old_visual_properties_; // True if the render widget host should track the render widget's size as // opposed to visa versa. - bool auto_resize_enabled_; + bool auto_resize_enabled_ = false; // The minimum size for the render widget if auto-resize is enabled. gfx::Size min_size_for_auto_resize_; @@ -1024,11 +1024,12 @@ gfx::Size max_size_for_auto_resize_; // The page-scale factor of the main-frame. - float page_scale_factor_; - // True when the renderer is currently undergoing a pinch-zoom gesture. - bool is_pinch_gesture_active_; + float page_scale_factor_ = 1.f; - bool waiting_for_screen_rects_ack_; + // True when the renderer is currently undergoing a pinch-zoom gesture. + bool is_pinch_gesture_active_ = false; + + bool waiting_for_screen_rects_ack_ = false; gfx::Rect last_view_screen_rect_; gfx::Rect last_window_screen_rect_; @@ -1046,27 +1047,27 @@ base::ObserverList<RenderWidgetHostObserver>::Unchecked observers_; // This is true if the renderer is currently unresponsive. - bool is_unresponsive_; + bool is_unresponsive_ = false; // This value denotes the number of input events yet to be acknowledged // by the renderer. - int in_flight_event_count_; + int in_flight_event_count_ = 0; // Flag to detect recursive calls to GetBackingStore(). - bool in_get_backing_store_; + bool in_get_backing_store_ = false; // Used for UMA histogram logging to measure the time for a repaint view // operation to finish. base::TimeTicks repaint_start_time_; // Set when we update the text direction of the selected input element. - bool text_direction_updated_; - blink::WebTextDirection text_direction_; + bool text_direction_updated_ = false; + blink::WebTextDirection text_direction_ = blink::kWebTextDirectionLeftToRight; // Set when we cancel updating the text direction. // This flag also ignores succeeding update requests until we call // NotifyTextDirection(). - bool text_direction_canceled_; + bool text_direction_canceled_ = false; // Indicates if Char and KeyUp events should be suppressed or not. Usually all // events are sent to the renderer directly in sequence. However, if a @@ -1079,10 +1080,10 @@ // the Char event generated by alt-2 may also activate a HTML element if its // accesskey happens to be "2", then the user may get confused when switching // back to the original tab, because the content may already have changed. - bool suppress_events_until_keydown_; + bool suppress_events_until_keydown_ = false; - bool pending_mouse_lock_request_; - bool allow_privileged_mouse_lock_; + bool pending_mouse_lock_request_ = false; + bool allow_privileged_mouse_lock_ = false; // Stores the keyboard keys to lock while waiting for a pending lock request. base::Optional<base::flat_set<ui::DomCode>> keyboard_keys_to_lock_; @@ -1092,18 +1093,18 @@ // Used when locking to indicate when a target application has voluntarily // unlocked and desires to relock the mouse. If the mouse is unlocked due // to ESC being pressed by the user, this will be false. - bool is_last_unlocked_by_target_; + bool is_last_unlocked_by_target_ = false; // Keeps track of whether the webpage has any touch event handler. If it does, // then touch events are sent to the renderer. Otherwise, the touch events are // not sent to the renderer. - bool has_touch_handler_; + bool has_touch_handler_ = false; // TODO(wjmaclean) Remove the code for supporting resending gesture events // when WebView transitions to OOPIF and BrowserPlugin is removed. // http://crbug.com/533069 bool is_in_gesture_scroll_[blink::kWebGestureDeviceCount] = {false}; - bool is_in_touchpad_gesture_fling_; + bool is_in_touchpad_gesture_fling_ = false; std::unique_ptr<SyntheticGestureController> synthetic_gesture_controller_; @@ -1120,20 +1121,20 @@ RenderWidgetHostLatencyTracker latency_tracker_; - int next_browser_snapshot_id_; + int next_browser_snapshot_id_ = 1; using PendingSnapshotMap = std::map<int, GetSnapshotFromBrowserCallback>; PendingSnapshotMap pending_browser_snapshots_; PendingSnapshotMap pending_surface_browser_snapshots_; // Indicates whether a RenderFramehost has ownership, in which case this // object does not self destroy. - bool owned_by_render_frame_host_; + bool owned_by_render_frame_host_ = false; // Indicates whether this RenderWidgetHost thinks is focused. This is trying // to match what the renderer process knows. It is different from // RenderWidgetHostView::HasFocus in that in that the focus request may fail, // causing HasFocus to return false when is_focused_ is true. - bool is_focused_; + bool is_focused_ = false; // Whether the view should send begin frame messages to its render widget. // This is state that may arrive before the view has been set and that must be @@ -1157,12 +1158,12 @@ // a no-op for non-top-level RenderWidgets, as that should always be zero. // TODO(kenrb, fsamuel): We should use SurfaceIDs for this purpose when they // are available in the renderer process. See https://crbug.com/695579. - uint32_t current_content_source_id_; + uint32_t current_content_source_id_ = 0; // When true, the RenderWidget is regularly sending updates regarding // composition info. It should only be true when there is a focused editable // node. - bool monitoring_composition_info_; + bool monitoring_composition_info_ = false; // This is the content_source_id of the latest frame received. This value is // compared against current_content_source_id_ to determine whether the
diff --git a/content/browser/webauth/authenticator_common.cc b/content/browser/webauth/authenticator_common.cc index 1dca48e..028b6d5 100644 --- a/content/browser/webauth/authenticator_common.cc +++ b/content/browser/webauth/authenticator_common.cc
@@ -807,15 +807,13 @@ return; } - if (options->allow_credentials.empty()) { - if (!base::FeatureList::IsEnabled(device::kWebAuthResidentKeys) || - !request_delegate_->SupportsResidentKeys()) { + if (options->allow_credentials.empty() && + (!base::FeatureList::IsEnabled(device::kWebAuthResidentKeys) || + !request_delegate_->SupportsResidentKeys())) { InvokeCallbackAndCleanup( std::move(callback), blink::mojom::AuthenticatorStatus::RESIDENT_CREDENTIALS_UNSUPPORTED); return; - } - need_account_selection_ = true; } if (options->appid) { @@ -1182,15 +1180,14 @@ request_delegate_->UpdateLastTransportUsed(*transport_used); } - if (need_account_selection_) { + if (response_data->size() == 1) { + OnAccountSelected(std::move(response_data->at(0))); + } else { request_delegate_->SelectAccount( std::move(*response_data), base::BindOnce(&AuthenticatorCommon::OnAccountSelected, weak_factory_.GetWeakPtr())); - return; } - - OnAccountSelected(std::move(response_data.value()[0])); return; } NOTREACHED(); @@ -1335,7 +1332,6 @@ client_data_json_.clear(); app_id_.reset(); attestation_requested_ = false; - need_account_selection_ = false; error_awaiting_user_acknowledgement_ = blink::mojom::AuthenticatorStatus::NOT_ALLOWED_ERROR; }
diff --git a/content/browser/webauth/authenticator_common.h b/content/browser/webauth/authenticator_common.h index 488be50..ac7534c 100644 --- a/content/browser/webauth/authenticator_common.h +++ b/content/browser/webauth/authenticator_common.h
@@ -200,10 +200,6 @@ std::string relying_party_id_; std::unique_ptr<base::OneShotTimer> timer_; base::Optional<std::string> app_id_; - // need_account_selection_ indicates if an empty allow-list was used, thus - // implying that an account selection dialog needs to be displayed to the user - // before returning any assertions. - bool need_account_selection_ = false; // awaiting_attestation_response_ is true if the embedder has been queried // about an attestsation decision and the response is still pending. bool awaiting_attestation_response_ = false;
diff --git a/content/browser/webauth/authenticator_impl_unittest.cc b/content/browser/webauth/authenticator_impl_unittest.cc index e1559646..d6337e6 100644 --- a/content/browser/webauth/authenticator_impl_unittest.cc +++ b/content/browser/webauth/authenticator_impl_unittest.cc
@@ -3367,8 +3367,8 @@ TestServiceManagerContext smc; AuthenticatorPtr authenticator = ConnectToAuthenticator(); TestGetAssertionCallback callback_receiver; - test_client_.expected_accounts = "01020304:test@example.com:Test User"; - test_client_.selected_user_id = {1, 2, 3, 4}; + // |SelectAccount| should not be called when there's only a single response. + test_client_.expected_accounts = "<invalid>"; authenticator->GetAssertion(get_credential_options(), callback_receiver.callback()); callback_receiver.WaitForCallback();
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py index af810c9d..cc0c146a 100644 --- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -29,14 +29,10 @@ ['win', 'mac', 'linux']) self.Skip('WebglExtension_WEBGL_compressed_texture_s3tc_srgb', ['win', 'mac', 'linux']) - self.Skip('WebglExtension_WEBGL_multiview', - ['mac', 'linux', 'android'], bug=864524) - # The multiview extension is only expected to be supported through ANGLE. - self.Skip('WebglExtension_WEBGL_multiview', - ['win', 'no_passthrough'], bug=864524) - # # ANGLE's OpenGL backend supports multiview only on NVIDIA. - self.Skip('WebglExtension_WEBGL_multiview', - ['win', 'passthrough', 'opengl', 'intel'], bug=864524) + # Disabling all multiview checks temporarily while ANGLE side changes + # get merged in. + self.Skip('WebglExtension_OVR_multiview2', + ['win', 'mac', 'linux', 'android'], bug=864524) self.Skip('WebglExtension_EXT_disjoint_timer_query_webgl2', ['android'], bug=808744) self.Skip('WebglExtension_KHR_parallel_shader_compile',
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py index f2b5ff1..089b43fa 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -344,6 +344,8 @@ ['win', ('amd', 0x699f), 'opengl'], bug=950123) self.Skip('conformance/glsl/samplers/glsl-function-texture2dprojlod.html', ['win', ('amd', 0x699f), 'opengl'], bug=950123) + self.Fail('conformance/reading/read-pixels-test.html', + ['win', ('amd', 0x699f), 'opengl'], bug=951771) self.Skip('conformance/rendering/line-rendering-quality.html', ['win', ('amd', 0x699f), 'opengl'], bug=950123)
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py index bd14ab3..f838853 100644 --- a/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py +++ b/content/test/gpu/gpu_tests/webgl_conformance_integration_test.py
@@ -181,6 +181,7 @@ 'EXT_texture_filter_anisotropic', 'KHR_parallel_shader_compile', 'OES_texture_float_linear', + 'OVR_multiview2', 'WEBGL_compressed_texture_astc', 'WEBGL_compressed_texture_etc', 'WEBGL_compressed_texture_etc1', @@ -192,7 +193,6 @@ 'WEBGL_lose_context', 'WEBGL_multi_draw', 'WEBGL_multi_draw_instanced', - 'WEBGL_multiview', 'WEBGL_video_texture', ]
diff --git a/device/fido/BUILD.gn b/device/fido/BUILD.gn index e5dd860c..d98b319 100644 --- a/device/fido/BUILD.gn +++ b/device/fido/BUILD.gn
@@ -237,6 +237,7 @@ ":fido", "//base", "//components/apdu", + "//components/cbor", "//testing/gmock", ] } @@ -270,6 +271,7 @@ ":fido", "//base", "//base:i18n", + "//components/cbor", ] seed_corpus = "response_data_fuzzer_corpus/" libfuzzer_options = [ "max_len=65537" ]
diff --git a/device/fido/ctap2_device_operation.h b/device/fido/ctap2_device_operation.h index 527e6af..cc194b6 100644 --- a/device/fido/ctap2_device_operation.h +++ b/device/fido/ctap2_device_operation.h
@@ -16,6 +16,12 @@ #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/optional.h" +#include "base/strings/string_number_conversions.h" +#include "components/cbor/diagnostic_writer.h" +#include "components/cbor/reader.h" +#include "components/cbor/values.h" +#include "components/cbor/writer.h" +#include "components/device_event_log/device_event_log.h" #include "device/fido/device_operation.h" #include "device/fido/device_response_converter.h" #include "device/fido/fido_constants.h" @@ -23,16 +29,25 @@ namespace device { -// Represents per device logic for CTAP2 authenticators. Ctap2DeviceOperation -// is owned by FidoTask, and thus |request| outlives Ctap2DeviceOperation. +// Ctap2DeviceOperation performs a single request--response operation on a CTAP2 +// device. The |Request| class must implement an |EncodeToCBOR| method that +// returns a pair of |CtapRequestCommand| and an optional CBOR |Value|. +// The response will be parsed to CBOR and then further parsed into a |Response| +// using a provided callback. template <class Request, class Response> class Ctap2DeviceOperation : public DeviceOperation<Request, Response> { public: + // DeviceResponseCallback is either called with a |kSuccess| and a |Response| + // object, or else is called with a value other than |kSuccess| and + // |nullopt|. using DeviceResponseCallback = base::OnceCallback<void(CtapDeviceResponseCode, base::Optional<Response>)>; - using DeviceResponseParser = - base::OnceCallback<base::Optional<Response>(base::span<const uint8_t>)>; + // DeviceResponseParser converts a generic CBOR structure into an + // operation-specific response. If the response didn't have a payload then the + // argument will be |nullopt|. The parser should return |nullopt| on error. + using DeviceResponseParser = base::OnceCallback<base::Optional<Response>( + const base::Optional<cbor::Value>&)>; Ctap2DeviceOperation(FidoDevice* device, Request request, @@ -47,8 +62,30 @@ ~Ctap2DeviceOperation() override = default; void Start() override { + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> request( + this->request().EncodeAsCBOR()); + std::vector<uint8_t> request_bytes; + + // TODO: it would be nice to see which device each request is going to, but + // that breaks every mock test because they aren't expecting a call to + // GetId(). + if (request.second) { + FIDO_LOG(DEBUG) << "<- " << static_cast<int>(request.first) << " " + << cbor::DiagnosticWriter::Write(*request.second); + base::Optional<std::vector<uint8_t>> cbor_bytes = + cbor::Writer::Write(*request.second); + DCHECK(cbor_bytes); + request_bytes = std::move(*cbor_bytes); + } else { + FIDO_LOG(DEBUG) << "<- " << static_cast<int>(request.first) + << " (no payload)"; + } + + request_bytes.insert(request_bytes.begin(), + static_cast<uint8_t>(request.first)); + this->token_ = this->device()->DeviceTransact( - this->request().EncodeAsCBOR(), + std::move(request_bytes), base::BindOnce(&Ctap2DeviceOperation::OnResponseReceived, weak_factory_.GetWeakPtr())); } @@ -57,16 +94,65 @@ base::Optional<std::vector<uint8_t>> device_response) { this->token_.reset(); + // TODO: it would be nice to see which device each response is coming from, + // but that breaks every mock test because they aren't expecting a call to + // GetId(). if (!device_response) { + FIDO_LOG(ERROR) << "-> (error reading)"; std::move(this->callback()) .Run(CtapDeviceResponseCode::kCtap2ErrOther, base::nullopt); return; } - const auto response_code = GetResponseCode(*device_response); - std::move(this->callback()) - .Run(response_code, std::move(device_response_parser_) - .Run(std::move(*device_response))); + auto response_code = GetResponseCode(*device_response); + if (response_code != CtapDeviceResponseCode::kSuccess) { + FIDO_LOG(DEBUG) << "-> (CTAP2 error code " + << static_cast<int>(response_code) << ")"; + std::move(this->callback()).Run(response_code, base::nullopt); + return; + } + DCHECK(!device_response->empty()); + + base::Optional<cbor::Value> cbor; + base::Optional<Response> response; + base::span<const uint8_t> cbor_bytes(*device_response); + cbor_bytes = cbor_bytes.subspan(1); + + if (!cbor_bytes.empty()) { + cbor::Reader::DecoderError error; + cbor = cbor::Reader::Read(cbor_bytes, &error); + if (!cbor) { + FIDO_LOG(ERROR) << "-> (CBOR parse error " << static_cast<int>(error) + << " from " + << base::HexEncode(device_response->data(), + device_response->size()) + << ")"; + std::move(this->callback()) + .Run(CtapDeviceResponseCode::kCtap2ErrInvalidCBOR, base::nullopt); + return; + } + + response = std::move(std::move(device_response_parser_).Run(cbor)); + if (response) { + FIDO_LOG(DEBUG) << "-> " << cbor::DiagnosticWriter::Write(*cbor); + } else { + FIDO_LOG(ERROR) << "-> (rejected CBOR structure) " + << cbor::DiagnosticWriter::Write(*cbor); + } + } else { + response = + std::move(std::move(device_response_parser_).Run(base::nullopt)); + if (response) { + FIDO_LOG(DEBUG) << "-> (empty payload)"; + } else { + FIDO_LOG(ERROR) << "-> (rejected empty payload)"; + } + } + + if (!response) { + response_code = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; + } + std::move(this->callback()).Run(response_code, std::move(response)); } private:
diff --git a/device/fido/ctap_get_assertion_request.cc b/device/fido/ctap_get_assertion_request.cc index afc89f9..32fb4ac7 100644 --- a/device/fido/ctap_get_assertion_request.cc +++ b/device/fido/ctap_get_assertion_request.cc
@@ -36,7 +36,8 @@ CtapGetAssertionRequest::~CtapGetAssertionRequest() = default; -std::vector<uint8_t> CtapGetAssertionRequest::EncodeAsCBOR() const { +std::pair<CtapRequestCommand, base::Optional<cbor::Value>> +CtapGetAssertionRequest::EncodeAsCBOR() const { cbor::Value::MapValue cbor_map; cbor_map[cbor::Value(1)] = cbor::Value(rp_id_); cbor_map[cbor::Value(2)] = cbor::Value(client_data_hash_); @@ -74,14 +75,8 @@ cbor_map[cbor::Value(5)] = cbor::Value(std::move(option_map)); } - auto serialized_param = cbor::Writer::Write(cbor::Value(std::move(cbor_map))); - DCHECK(serialized_param); - - std::vector<uint8_t> cbor_request({base::strict_cast<uint8_t>( - CtapRequestCommand::kAuthenticatorGetAssertion)}); - cbor_request.insert(cbor_request.end(), serialized_param->begin(), - serialized_param->end()); - return cbor_request; + return std::make_pair(CtapRequestCommand::kAuthenticatorGetAssertion, + cbor::Value(std::move(cbor_map))); } CtapGetAssertionRequest& CtapGetAssertionRequest::SetUserVerification( @@ -136,9 +131,10 @@ response_rp_id_hash == *alternative_application_parameter()); } -std::vector<uint8_t> CtapGetNextAssertionRequest::EncodeAsCBOR() const { - return { - static_cast<uint8_t>(CtapRequestCommand::kAuthenticatorGetNextAssertion)}; +std::pair<CtapRequestCommand, base::Optional<cbor::Value>> +CtapGetNextAssertionRequest::EncodeAsCBOR() const { + return std::make_pair(CtapRequestCommand::kAuthenticatorGetNextAssertion, + base::nullopt); } } // namespace device
diff --git a/device/fido/ctap_get_assertion_request.h b/device/fido/ctap_get_assertion_request.h index 9191ea6..d6131e0 100644 --- a/device/fido/ctap_get_assertion_request.h +++ b/device/fido/ctap_get_assertion_request.h
@@ -20,6 +20,10 @@ #include "device/fido/fido_constants.h" #include "device/fido/public_key_credential_descriptor.h" +namespace cbor { +class Value; +} + namespace device { // Object that encapsulates request parameters for AuthenticatorGetAssertion as @@ -39,7 +43,8 @@ // Serializes GetAssertion request parameter into CBOR encoded map with // integer keys and CBOR encoded values as defined by the CTAP spec. // https://drafts.fidoalliance.org/fido-2/latest/fido-client-to-authenticator-protocol-v2.0-wd-20180305.html#authenticatorGetAssertion - std::vector<uint8_t> EncodeAsCBOR() const; + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR() + const; CtapGetAssertionRequest& SetUserVerification( UserVerificationRequirement user_verfication); @@ -114,7 +119,8 @@ class CtapGetNextAssertionRequest { public: - std::vector<uint8_t> EncodeAsCBOR() const; + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR() + const; }; } // namespace device
diff --git a/device/fido/ctap_make_credential_request.cc b/device/fido/ctap_make_credential_request.cc index b01aff6f..549a2b8 100644 --- a/device/fido/ctap_make_credential_request.cc +++ b/device/fido/ctap_make_credential_request.cc
@@ -9,7 +9,7 @@ #include <utility> #include "base/numerics/safe_conversions.h" -#include "components/cbor/writer.h" +#include "components/cbor/values.h" #include "device/fido/fido_constants.h" #include "device/fido/fido_parsing_utils.h" @@ -41,7 +41,8 @@ CtapMakeCredentialRequest::~CtapMakeCredentialRequest() = default; -std::vector<uint8_t> CtapMakeCredentialRequest::EncodeAsCBOR() const { +std::pair<CtapRequestCommand, base::Optional<cbor::Value>> +CtapMakeCredentialRequest::EncodeAsCBOR() const { cbor::Value::MapValue cbor_map; cbor_map[cbor::Value(1)] = cbor::Value(client_data_hash_); cbor_map[cbor::Value(2)] = rp_.ConvertToCBOR(); @@ -86,14 +87,8 @@ cbor_map[cbor::Value(7)] = cbor::Value(std::move(option_map)); } - auto serialized_param = cbor::Writer::Write(cbor::Value(std::move(cbor_map))); - DCHECK(serialized_param); - - std::vector<uint8_t> cbor_request({base::strict_cast<uint8_t>( - CtapRequestCommand::kAuthenticatorMakeCredential)}); - cbor_request.insert(cbor_request.end(), serialized_param->begin(), - serialized_param->end()); - return cbor_request; + return std::make_pair(CtapRequestCommand::kAuthenticatorMakeCredential, + cbor::Value(std::move(cbor_map))); } CtapMakeCredentialRequest&
diff --git a/device/fido/ctap_make_credential_request.h b/device/fido/ctap_make_credential_request.h index 2554344..e51050b4 100644 --- a/device/fido/ctap_make_credential_request.h +++ b/device/fido/ctap_make_credential_request.h
@@ -21,6 +21,10 @@ #include "device/fido/public_key_credential_rp_entity.h" #include "device/fido/public_key_credential_user_entity.h" +namespace cbor { +class Value; +} + namespace device { // Object containing request parameters for AuthenticatorMakeCredential command @@ -44,7 +48,8 @@ // Serializes MakeCredential request parameter into CBOR encoded map with // integer keys and CBOR encoded values as defined by the CTAP spec. // https://drafts.fidoalliance.org/fido-2/latest/fido-client-to-authenticator-protocol-v2.0-wd-20180305.html#authenticatorMakeCredential - std::vector<uint8_t> EncodeAsCBOR() const; + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR() + const; CtapMakeCredentialRequest& SetAuthenticatorAttachment( AuthenticatorAttachment authenticator_attachment);
diff --git a/device/fido/ctap_request_unittest.cc b/device/fido/ctap_request_unittest.cc index 83a0c13c..31cc2b2 100644 --- a/device/fido/ctap_request_unittest.cc +++ b/device/fido/ctap_request_unittest.cc
@@ -8,6 +8,7 @@ #include "device/fido/fido_constants.h" #include "device/fido/fido_parsing_utils.h" #include "device/fido/fido_test_data.h" +#include "device/fido/mock_fido_device.h" #include "device/fido/virtual_ctap2_device.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,10 +31,10 @@ test_data::kClientDataJson, std::move(rp), std::move(user), PublicKeyCredentialParams({{CredentialType::kPublicKey, 7}, {CredentialType::kPublicKey, 257}})); - auto serialized_data = + auto serialized_data = MockFidoDevice::EncodeCBORRequest( make_credential_param.SetResidentKeyRequired(true) .SetUserVerification(UserVerificationRequirement::kRequired) - .EncodeAsCBOR(); + .EncodeAsCBOR()); EXPECT_THAT(serialized_data, ::testing::ElementsAreArray( test_data::kCtapMakeCredentialRequest)); } @@ -63,7 +64,8 @@ .SetUserPresenceRequired(false) .SetUserVerification(UserVerificationRequirement::kRequired); - auto serialized_data = get_assertion_req.EncodeAsCBOR(); + auto serialized_data = + MockFidoDevice::EncodeCBORRequest(get_assertion_req.EncodeAsCBOR()); EXPECT_THAT(serialized_data, ::testing::ElementsAreArray( test_data::kTestComplexCtapGetAssertionRequest));
diff --git a/device/fido/ctap_response_fuzzer.cc b/device/fido/ctap_response_fuzzer.cc index c3abf10..4bec69e 100644 --- a/device/fido/ctap_response_fuzzer.cc +++ b/device/fido/ctap_response_fuzzer.cc
@@ -9,6 +9,7 @@ #include "base/at_exit.h" #include "base/i18n/icu_util.h" +#include "components/cbor/reader.h" #include "device/fido/authenticator_get_assertion_response.h" #include "device/fido/authenticator_get_info_response.h" #include "device/fido/authenticator_make_credential_response.h" @@ -31,9 +32,10 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { std::vector<uint8_t> input(data, data + size); + base::Optional<cbor::Value> input_cbor = cbor::Reader::Read(input); std::array<uint8_t, 32> relying_party_id_hash = {}; auto response = device::ReadCTAPMakeCredentialResponse( - FidoTransportProtocol::kUsbHumanInterfaceDevice, input); + FidoTransportProtocol::kUsbHumanInterfaceDevice, input_cbor); if (response) response->EraseAttestationStatement(AttestationObject::AAGUID::kErase); @@ -44,7 +46,7 @@ if (response) response->EraseAttestationStatement(AttestationObject::AAGUID::kErase); - device::ReadCTAPGetAssertionResponse(input); + device::ReadCTAPGetAssertionResponse(input_cbor); std::vector<uint8_t> u2f_response_data(data, data + size); std::vector<uint8_t> key_handle(data, data + size); device::AuthenticatorGetAssertionResponse::CreateFromU2fSignResponse(
diff --git a/device/fido/ctap_response_unittest.cc b/device/fido/ctap_response_unittest.cc index 8b48791..87edc93 100644 --- a/device/fido/ctap_response_unittest.cc +++ b/device/fido/ctap_response_unittest.cc
@@ -313,6 +313,13 @@ return fido_parsing_utils::Materialize(test_data::kU2fSignKeyHandle); } +// DecodeCBOR parses a CBOR structure, ignoring the first byte of |in|, which is +// assumed to be a CTAP2 status byte. +base::Optional<cbor::Value> DecodeCBOR(base::span<const uint8_t> in) { + CHECK(!in.empty()); + return cbor::Reader::Read(in.subspan(1)); +} + } // namespace // Leveraging example 4 of section 6.1 of the spec https://fidoalliance.org @@ -321,7 +328,7 @@ TEST(CTAPResponseTest, TestReadMakeCredentialResponse) { auto make_credential_response = ReadCTAPMakeCredentialResponse( FidoTransportProtocol::kUsbHumanInterfaceDevice, - test_data::kTestMakeCredentialResponse); + DecodeCBOR(test_data::kTestMakeCredentialResponse)); ASSERT_TRUE(make_credential_response); auto cbor_attestation_object = cbor::Reader::Read( make_credential_response->GetCBOREncodedAttestationObject()); @@ -376,7 +383,7 @@ TEST(CTAPResponseTest, TestMakeCredentialNoneAttestationResponse) { auto make_credential_response = ReadCTAPMakeCredentialResponse( FidoTransportProtocol::kUsbHumanInterfaceDevice, - test_data::kTestMakeCredentialResponse); + DecodeCBOR(test_data::kTestMakeCredentialResponse)); ASSERT_TRUE(make_credential_response); make_credential_response->EraseAttestationStatement( AttestationObject::AAGUID::kErase); @@ -387,8 +394,8 @@ // Leveraging example 5 of section 6.1 of the CTAP spec. // https://fidoalliance.org/specs/fido-v2.0-rd-20170927/fido-client-to-authenticator-protocol-v2.0-rd-20170927.html TEST(CTAPResponseTest, TestReadGetAssertionResponse) { - auto get_assertion_response = - ReadCTAPGetAssertionResponse(test_data::kDeviceGetAssertionResponse); + auto get_assertion_response = ReadCTAPGetAssertionResponse( + DecodeCBOR(test_data::kDeviceGetAssertionResponse)); ASSERT_TRUE(get_assertion_response); ASSERT_TRUE(get_assertion_response->num_credentials()); EXPECT_EQ(*get_assertion_response->num_credentials(), 1u);
diff --git a/device/fido/device_response_converter.cc b/device/fido/device_response_converter.cc index 40e6e67..bff3fe5 100644 --- a/device/fido/device_response_converter.cc +++ b/device/fido/device_response_converter.cc
@@ -12,6 +12,7 @@ #include "base/numerics/safe_conversions.h" #include "base/optional.h" #include "base/stl_util.h" +#include "components/cbor/diagnostic_writer.h" #include "components/cbor/reader.h" #include "components/cbor/writer.h" #include "components/device_event_log/device_event_log.h" @@ -53,15 +54,11 @@ // checks for correct encoding format. base::Optional<AuthenticatorMakeCredentialResponse> ReadCTAPMakeCredentialResponse(FidoTransportProtocol transport_used, - base::span<const uint8_t> buffer) { - if (buffer.size() <= kResponseCodeLength) + const base::Optional<cbor::Value>& cbor) { + if (!cbor || !cbor->is_map()) return base::nullopt; - base::Optional<CBOR> decoded_response = cbor::Reader::Read(buffer.subspan(1)); - if (!decoded_response || !decoded_response->is_map()) - return base::nullopt; - - const auto& decoded_map = decoded_response->GetMap(); + const auto& decoded_map = cbor->GetMap(); auto it = decoded_map.find(CBOR(1)); if (it == decoded_map.end() || !it->second.is_string()) return base::nullopt; @@ -88,16 +85,11 @@ } base::Optional<AuthenticatorGetAssertionResponse> ReadCTAPGetAssertionResponse( - base::span<const uint8_t> buffer) { - if (buffer.size() <= kResponseCodeLength) + const base::Optional<cbor::Value>& cbor) { + if (!cbor || !cbor->is_map()) return base::nullopt; - base::Optional<CBOR> decoded_response = cbor::Reader::Read(buffer.subspan(1)); - - if (!decoded_response || !decoded_response->is_map()) - return base::nullopt; - - auto& response_map = decoded_response->GetMap(); + auto& response_map = cbor->GetMap(); auto it = response_map.find(CBOR(2)); if (it == response_map.end() || !it->second.is_bytestring()) @@ -155,6 +147,7 @@ if (!decoded_response || !decoded_response->is_map()) return base::nullopt; + FIDO_LOG(DEBUG) << "-> " << cbor::DiagnosticWriter::Write(*decoded_response); const auto& response_map = decoded_response->GetMap(); auto it = response_map.find(CBOR(1));
diff --git a/device/fido/device_response_converter.h b/device/fido/device_response_converter.h index 201a42e..bfd7b26 100644 --- a/device/fido/device_response_converter.h +++ b/device/fido/device_response_converter.h
@@ -27,21 +27,20 @@ COMPONENT_EXPORT(DEVICE_FIDO) CtapDeviceResponseCode GetResponseCode(base::span<const uint8_t> buffer); -// De-serializes CBOR encoded response, checks for valid CBOR map formatting, -// and converts response to AuthenticatorMakeCredentialResponse object with -// CBOR map keys that conform to format of attestation object defined by the -// WebAuthN spec : https://w3c.github.io/webauthn/#fig-attStructs +// Converts |cbor| to an |AuthenticatorMakeCredentialResponse| using map keys +// that conform to format of attestation object defined by the Webauthn spec: +// https://w3c.github.io/webauthn/#fig-attStructs COMPONENT_EXPORT(DEVICE_FIDO) base::Optional<AuthenticatorMakeCredentialResponse> ReadCTAPMakeCredentialResponse(FidoTransportProtocol transport_used, - base::span<const uint8_t> buffer); + const base::Optional<cbor::Value>& cbor); -// De-serializes CBOR encoded response to AuthenticatorGetAssertion / -// AuthenticatorGetNextAssertion request to AuthenticatorGetAssertionResponse -// object. +// Converts |cbor|, the response to an |AuthenticatorGetAssertion| / +// |AuthenticatorGetNextAssertion| request, to an +// |AuthenticatorGetAssertionResponse|. COMPONENT_EXPORT(DEVICE_FIDO) base::Optional<AuthenticatorGetAssertionResponse> ReadCTAPGetAssertionResponse( - base::span<const uint8_t> buffer); + const base::Optional<cbor::Value>& cbor); // De-serializes CBOR encoded response to AuthenticatorGetInfo request to // AuthenticatorGetInfoResponse object.
diff --git a/device/fido/get_assertion_handler_unittest.cc b/device/fido/get_assertion_handler_unittest.cc index 91766cb..1a3d33b 100644 --- a/device/fido/get_assertion_handler_unittest.cc +++ b/device/fido/get_assertion_handler_unittest.cc
@@ -278,7 +278,8 @@ auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation( test_data::kTestGetInfoResponseWithoutUvSupport); device->ExpectRequestAndRespondWith( - MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR(), + MockFidoDevice::EncodeCBORRequest( + MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR()), test_data::kTestMakeCredentialResponse); discovery()->AddDevice(std::move(device));
diff --git a/device/fido/get_assertion_request_handler.cc b/device/fido/get_assertion_request_handler.cc index be9043b..4cb6003 100644 --- a/device/fido/get_assertion_request_handler.cc +++ b/device/fido/get_assertion_request_handler.cc
@@ -370,10 +370,6 @@ DCHECK_LT(0u, remaining_responses_); state_ = State::kFinished; - if (status == CtapDeviceResponseCode::kSuccess && !response) { - status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; - } - if (status != CtapDeviceResponseCode::kSuccess) { OnAuthenticatorResponse(authenticator, status, base::nullopt); return; @@ -434,10 +430,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); DCHECK_EQ(state_, State::kGettingRetries); - if (status == CtapDeviceResponseCode::kSuccess && !response) { - status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; - } - if (status != CtapDeviceResponseCode::kSuccess) { state_ = State::kFinished; FidoReturnCode ret = FidoReturnCode::kAuthenticatorResponseInvalid; @@ -479,10 +471,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); DCHECK_EQ(State::kGetEphemeralKey, state_); - if (status == CtapDeviceResponseCode::kSuccess && !response) { - status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; - } - if (status != CtapDeviceResponseCode::kSuccess) { state_ = State::kFinished; std::move(completion_callback_) @@ -512,10 +500,6 @@ return; } - if (status == CtapDeviceResponseCode::kSuccess && !response) { - status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; - } - if (status != CtapDeviceResponseCode::kSuccess) { state_ = State::kFinished; FidoReturnCode ret;
diff --git a/device/fido/make_credential_handler_unittest.cc b/device/fido/make_credential_handler_unittest.cc index b906ecf1..dd9971b 100644 --- a/device/fido/make_credential_handler_unittest.cc +++ b/device/fido/make_credential_handler_unittest.cc
@@ -242,7 +242,8 @@ auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation( test_data::kTestGetInfoResponseWithoutUvSupport); device->ExpectRequestAndRespondWith( - MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR(), + MockFidoDevice::EncodeCBORRequest( + MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR()), test_data::kTestMakeCredentialResponse); discovery()->AddDevice(std::move(device)); @@ -328,7 +329,8 @@ auto device = MockFidoDevice::MakeCtapWithGetInfoExpectation( test_data::kTestGetInfoResponseWithoutResidentKeySupport); device->ExpectRequestAndRespondWith( - MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR(), + MockFidoDevice::EncodeCBORRequest( + MakeCredentialTask::GetTouchRequest(device.get()).EncodeAsCBOR()), test_data::kTestMakeCredentialResponse); discovery()->AddDevice(std::move(device));
diff --git a/device/fido/make_credential_request_handler.cc b/device/fido/make_credential_request_handler.cc index d9a0be9..1e20ec10 100644 --- a/device/fido/make_credential_request_handler.cc +++ b/device/fido/make_credential_request_handler.cc
@@ -361,10 +361,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); DCHECK_EQ(state_, State::kGettingRetries); - if (status == CtapDeviceResponseCode::kSuccess && !response) { - status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; - } - if (status != CtapDeviceResponseCode::kSuccess) { state_ = State::kFinished; FidoReturnCode ret = FidoReturnCode::kAuthenticatorResponseInvalid; @@ -390,10 +386,6 @@ DCHECK(state_ == State::kGetEphemeralKey || state_ == State::kGetEphemeralKeyForNewPIN); - if (status == CtapDeviceResponseCode::kSuccess && !response) { - status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; - } - if (status != CtapDeviceResponseCode::kSuccess) { state_ = State::kFinished; std::move(completion_callback_) @@ -448,10 +440,6 @@ return; } - if (status == CtapDeviceResponseCode::kSuccess && !response) { - status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; - } - if (status != CtapDeviceResponseCode::kSuccess) { state_ = State::kFinished; FidoReturnCode ret;
diff --git a/device/fido/mock_fido_device.cc b/device/fido/mock_fido_device.cc index 3185606..99af57b 100644 --- a/device/fido/mock_fido_device.cc +++ b/device/fido/mock_fido_device.cc
@@ -11,6 +11,7 @@ #include "base/strings/strcat.h" #include "base/threading/thread_task_runner_handle.h" #include "components/apdu/apdu_response.h" +#include "components/cbor/writer.h" #include "device/fido/device_response_converter.h" #include "device/fido/fido_constants.h" #include "device/fido/fido_parsing_utils.h" @@ -65,6 +66,21 @@ return device; } +std::vector<uint8_t> MockFidoDevice::EncodeCBORRequest( + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> request) { + std::vector<uint8_t> request_bytes; + + if (request.second) { + base::Optional<std::vector<uint8_t>> cbor_bytes = + cbor::Writer::Write(*request.second); + DCHECK(cbor_bytes); + request_bytes = std::move(*cbor_bytes); + } + request_bytes.insert(request_bytes.begin(), + static_cast<uint8_t>(request.first)); + return request_bytes; +} + // Matcher to compare the fist byte of the incoming requests. MATCHER_P(IsCtap2Command, expected_command, "") { return !arg.empty() && arg[0] == base::strict_cast<uint8_t>(expected_command);
diff --git a/device/fido/mock_fido_device.h b/device/fido/mock_fido_device.h index dbecfa67..28c7a34 100644 --- a/device/fido/mock_fido_device.h +++ b/device/fido/mock_fido_device.h
@@ -21,6 +21,10 @@ #include "device/fido/fido_transport_protocol.h" #include "testing/gmock/include/gmock/gmock.h" +namespace cbor { +class Value; +} + namespace device { class MockFidoDevice : public ::testing::StrictMock<FidoDevice> { @@ -46,6 +50,10 @@ static std::unique_ptr<MockFidoDevice> MakeCtapWithGetInfoExpectation( base::Optional<base::span<const uint8_t>> get_info_response = base::nullopt); + // EncodeCBORRequest is a helper function for use with the |Expect*| + // functions, below, that take a serialised request. + static std::vector<uint8_t> EncodeCBORRequest( + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> request); MockFidoDevice(); MockFidoDevice(ProtocolVersion protocol_version,
diff --git a/device/fido/pin.cc b/device/fido/pin.cc index 2d12008..307add2 100644 --- a/device/fido/pin.cc +++ b/device/fido/pin.cc
@@ -40,10 +40,11 @@ HasAtLeastFourCodepoints(pin); } -// EncodePINCommand returns a serialised CTAP2 PIN command for the operation -// |subcommand|. Additional elements of the top-level CBOR map can be added with -// the optional |add_additional| callback. -static std::vector<uint8_t> EncodePINCommand( +// EncodePINCommand returns a CTAP2 PIN command for the operation |subcommand|. +// Additional elements of the top-level CBOR map can be added with the optional +// |add_additional| callback. +static std::pair<CtapRequestCommand, base::Optional<cbor::Value>> +EncodePINCommand( Subcommand subcommand, std::function<void(cbor::Value::MapValue*)> add_additional = nullptr) { cbor::Value::MapValue map; @@ -55,14 +56,12 @@ add_additional(&map); } - auto serialized = cbor::Writer::Write(cbor::Value(map)); - serialized->insert( - serialized->begin(), - static_cast<uint8_t>(CtapRequestCommand::kAuthenticatorClientPin)); - return *serialized; + return std::make_pair(CtapRequestCommand::kAuthenticatorClientPin, + cbor::Value(std::move(map))); } -std::vector<uint8_t> RetriesRequest::EncodeAsCBOR() const { +std::pair<CtapRequestCommand, base::Optional<cbor::Value>> +RetriesRequest::EncodeAsCBOR() const { return EncodePINCommand(Subcommand::kGetRetries); } @@ -70,19 +69,11 @@ // static base::Optional<RetriesResponse> RetriesResponse::Parse( - base::span<const uint8_t> buffer) { - // The response status code (the first byte) has already been processed by - // this point. - if (buffer.empty()) { + const base::Optional<cbor::Value>& cbor) { + if (!cbor || !cbor->is_map()) { return base::nullopt; } - - base::Optional<cbor::Value> decoded_response = - cbor::Reader::Read(buffer.subspan(1)); - if (!decoded_response || !decoded_response->is_map()) { - return base::nullopt; - } - const auto& response_map = decoded_response->GetMap(); + const auto& response_map = cbor->GetMap(); auto it = response_map.find(cbor::Value(static_cast<int>(ResponseKey::kRetries))); @@ -100,7 +91,8 @@ return ret; } -std::vector<uint8_t> KeyAgreementRequest::EncodeAsCBOR() const { +std::pair<CtapRequestCommand, base::Optional<cbor::Value>> +KeyAgreementRequest::EncodeAsCBOR() const { return EncodePINCommand(Subcommand::kGetKeyAgreement); } @@ -134,19 +126,11 @@ // static base::Optional<KeyAgreementResponse> KeyAgreementResponse::Parse( - base::span<const uint8_t> buffer) { - // The response status code (the first byte) has already been processed by - // this point. - if (buffer.empty()) { + const base::Optional<cbor::Value>& cbor) { + if (!cbor || !cbor->is_map()) { return base::nullopt; } - - base::Optional<cbor::Value> decoded_response = - cbor::Reader::Read(buffer.subspan(1)); - if (!decoded_response || !decoded_response->is_map()) { - return base::nullopt; - } - const auto& response_map = decoded_response->GetMap(); + const auto& response_map = cbor->GetMap(); // The ephemeral key is encoded as a COSE structure. auto it = response_map.find( @@ -289,7 +273,8 @@ EVP_CIPHER_CTX_cleanup(&aes_ctx); } -std::vector<uint8_t> SetRequest::EncodeAsCBOR() const { +std::pair<CtapRequestCommand, base::Optional<cbor::Value>> +SetRequest::EncodeAsCBOR() const { // See // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#settingNewPin uint8_t shared_key[SHA256_DIGEST_LENGTH]; @@ -335,10 +320,12 @@ // static base::Optional<EmptyResponse> EmptyResponse::Parse( - base::span<const uint8_t> buffer) { - // The response status code (the first byte) has already been processed by - // this point. - if (buffer.size() != 1) { + const base::Optional<cbor::Value>& cbor) { + // Yubikeys can return just the status byte, and no CBOR bytes, for the empty + // response, which will end up here with |cbor| being |nullopt|. This seems + // wrong, but is handled. (The response should, instead, encode an empty CBOR + // map.) + if (cbor && (!cbor->is_map() || !cbor->GetMap().empty())) { return base::nullopt; } @@ -346,7 +333,8 @@ return ret; } -std::vector<uint8_t> ChangeRequest::EncodeAsCBOR() const { +std::pair<CtapRequestCommand, base::Optional<cbor::Value>> +ChangeRequest::EncodeAsCBOR() const { // See // https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-client-to-authenticator-protocol-v2.0-rd-20180702.html#changingExistingPin uint8_t shared_key[SHA256_DIGEST_LENGTH]; @@ -389,8 +377,9 @@ }); } -std::vector<uint8_t> ResetRequest::EncodeAsCBOR() const { - return {static_cast<uint8_t>(CtapRequestCommand::kAuthenticatorReset)}; +std::pair<CtapRequestCommand, base::Optional<cbor::Value>> +ResetRequest::EncodeAsCBOR() const { + return std::make_pair(CtapRequestCommand::kAuthenticatorReset, base::nullopt); } TokenRequest::TokenRequest(const std::string& pin, @@ -410,7 +399,8 @@ return shared_key_; } -std::vector<uint8_t> TokenRequest::EncodeAsCBOR() const { +std::pair<CtapRequestCommand, base::Optional<cbor::Value>> +TokenRequest::EncodeAsCBOR() const { static_assert((sizeof(pin_hash_) % AES_BLOCK_SIZE) == 0, "pin_hash_ is not a multiple of the AES block size"); uint8_t encrypted_pin[sizeof(pin_hash_)]; @@ -451,19 +441,11 @@ base::Optional<TokenResponse> TokenResponse::Parse( std::array<uint8_t, 32> shared_key, - base::span<const uint8_t> buffer) { - // The response status code (the first byte) has already been processed by - // this point. - if (buffer.empty()) { + const base::Optional<cbor::Value>& cbor) { + if (!cbor || !cbor->is_map()) { return base::nullopt; } - - base::Optional<cbor::Value> decoded_response = - cbor::Reader::Read(buffer.subspan(1)); - if (!decoded_response || !decoded_response->is_map()) { - return base::nullopt; - } - const auto& response_map = decoded_response->GetMap(); + const auto& response_map = cbor->GetMap(); auto it = response_map.find(cbor::Value(static_cast<int>(ResponseKey::kPINToken)));
diff --git a/device/fido/pin.h b/device/fido/pin.h index 3a59518..4cd0fae 100644 --- a/device/fido/pin.h +++ b/device/fido/pin.h
@@ -43,13 +43,14 @@ // RetriesRequest asks an authenticator for the number of remaining PIN attempts // before the device is locked. struct RetriesRequest { - std::vector<uint8_t> EncodeAsCBOR() const; + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR() + const; }; // RetriesResponse reflects an authenticator's response to a |RetriesRequest|. struct RetriesResponse { static base::Optional<RetriesResponse> Parse( - base::span<const uint8_t> buffer); + const base::Optional<cbor::Value>& cbor); // retries is the number of PIN attempts remaining before the authenticator // locks. @@ -62,7 +63,8 @@ // KeyAgreementRequest asks an authenticator for an ephemeral ECDH key for // encrypting PIN material in future requests. struct KeyAgreementRequest { - std::vector<uint8_t> EncodeAsCBOR() const; + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR() + const; }; // KeyAgreementResponse reflects an authenticator's response to a @@ -70,7 +72,7 @@ // authenticator's ephemeral key. struct KeyAgreementResponse { static base::Optional<KeyAgreementResponse> Parse( - base::span<const uint8_t> buffer); + const base::Optional<cbor::Value>& cbor); static base::Optional<KeyAgreementResponse> ParseFromCOSE( const cbor::Value::MapValue& cose_key); @@ -89,7 +91,8 @@ // IsValid(pin) must be true. SetRequest(const std::string& pin, const KeyAgreementResponse& peer_key); - std::vector<uint8_t> EncodeAsCBOR() const; + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR() + const; private: const KeyAgreementResponse peer_key_; @@ -97,7 +100,8 @@ }; struct EmptyResponse { - static base::Optional<EmptyResponse> Parse(base::span<const uint8_t> buffer); + static base::Optional<EmptyResponse> Parse( + const base::Optional<cbor::Value>& cbor); }; // ChangeRequest changes the PIN on an authenticator that already has a PIN set. @@ -109,7 +113,8 @@ const std::string& new_pin, const KeyAgreementResponse& peer_key); - std::vector<uint8_t> EncodeAsCBOR() const; + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR() + const; private: const KeyAgreementResponse peer_key_; @@ -122,7 +127,8 @@ // PIN-related command, but is generally used to reset a PIN and so is // included here. struct ResetRequest { - std::vector<uint8_t> EncodeAsCBOR() const; + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR() + const; }; using ResetResponse = EmptyResponse; @@ -141,7 +147,8 @@ // This is needed to decrypt the response. const std::array<uint8_t, 32>& shared_key() const; - std::vector<uint8_t> EncodeAsCBOR() const; + std::pair<CtapRequestCommand, base::Optional<cbor::Value>> EncodeAsCBOR() + const; private: std::array<uint8_t, 32> shared_key_; @@ -158,8 +165,9 @@ ~TokenResponse(); TokenResponse(const TokenResponse&); - static base::Optional<TokenResponse> Parse(std::array<uint8_t, 32> shared_key, - base::span<const uint8_t> buffer); + static base::Optional<TokenResponse> Parse( + std::array<uint8_t, 32> shared_key, + const base::Optional<cbor::Value>& cbor); // PinAuth returns a pinAuth parameter for a request that will use the given // client-data hash.
diff --git a/device/fido/reset_request_handler.cc b/device/fido/reset_request_handler.cc index 95962060..aecad53f 100644 --- a/device/fido/reset_request_handler.cc +++ b/device/fido/reset_request_handler.cc
@@ -65,10 +65,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); DCHECK(processed_touch_); - if (status == CtapDeviceResponseCode::kSuccess && !response) { - status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; - } - std::move(finished_callback_).Run(status); }
diff --git a/device/fido/set_pin_request_handler.cc b/device/fido/set_pin_request_handler.cc index 6b60b30f..dfe179f 100644 --- a/device/fido/set_pin_request_handler.cc +++ b/device/fido/set_pin_request_handler.cc
@@ -108,10 +108,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); DCHECK_EQ(state_, State::kGettingRetries); - if (status == CtapDeviceResponseCode::kSuccess && !response) { - status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; - } - if (status != CtapDeviceResponseCode::kSuccess) { state_ = State::kFinished; finished_callback_.Run(status); @@ -130,10 +126,6 @@ DCHECK_CALLED_ON_VALID_SEQUENCE(my_sequence_checker_); DCHECK_EQ(state_, State::kGetEphemeralKey); - if (status == CtapDeviceResponseCode::kSuccess && !response) { - status = CtapDeviceResponseCode::kCtap2ErrInvalidCBOR; - } - if (status != CtapDeviceResponseCode::kSuccess) { state_ = State::kFinished; finished_callback_.Run(status);
diff --git a/fuchsia/BUILD.gn b/fuchsia/BUILD.gn index 04cf728..5c84563 100644 --- a/fuchsia/BUILD.gn +++ b/fuchsia/BUILD.gn
@@ -41,6 +41,7 @@ public_deps = [ ":web_fidl", + "//third_party/fuchsia-sdk/sdk:web", ] }
diff --git a/fuchsia/fidl/cast/cast_channel.fidl b/fuchsia/fidl/cast/cast_channel.fidl index f6274a6f..8fb702e 100644 --- a/fuchsia/fidl/cast/cast_channel.fidl +++ b/fuchsia/fidl/cast/cast_channel.fidl
@@ -5,12 +5,16 @@ library chromium.cast; using chromium.web; +using fuchsia.web; [Discoverable] protocol CastChannel { /// Receives an opened Cast |channel| from the Cast application. - /// The return callback is invoked when the service is ready to accept a new - /// Cast Channel. OnOpened() should not be called again until this happens. + /// Open() must not be called again until the preceding call has returned. + [Transitional="Transitional method to migrate the fuchsia.web API."] + Open(fuchsia.web.MessagePort channel) -> (); + + // TODO(crbug.com/946732): Remove this once callers have migrated to Open(). OnOpened(chromium.web.MessagePort channel) -> (); };
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h index 99c6893..052b441e 100644 --- a/gpu/GLES2/gl2chromium_autogen.h +++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -413,8 +413,8 @@ #define glDestroyGpuFenceCHROMIUM GLES2_GET_FUN(DestroyGpuFenceCHROMIUM) #define glInvalidateReadbackBufferShadowDataCHROMIUM \ GLES2_GET_FUN(InvalidateReadbackBufferShadowDataCHROMIUM) -#define glFramebufferTextureMultiviewLayeredANGLE \ - GLES2_GET_FUN(FramebufferTextureMultiviewLayeredANGLE) +#define glFramebufferTextureMultiviewOVR \ + GLES2_GET_FUN(FramebufferTextureMultiviewOVR) #define glMaxShaderCompilerThreadsKHR GLES2_GET_FUN(MaxShaderCompilerThreadsKHR) #define glCreateAndTexStorage2DSharedImageCHROMIUM \ GLES2_GET_FUN(CreateAndTexStorage2DSharedImageCHROMIUM)
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py index 61cf9c14..255f6eb5 100755 --- a/gpu/command_buffer/build_gles2_cmd_buffer.py +++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -4261,11 +4261,11 @@ 'extension': 'MESA_framebuffer_flip_y', 'extension_flag': 'mesa_framebuffer_flip_y', }, - 'FramebufferTextureMultiviewLayeredANGLE': { - 'decoder_func': 'DoFramebufferTextureMultiviewLayeredANGLE', + 'FramebufferTextureMultiviewOVR': { + 'decoder_func': 'DoFramebufferTextureMultiviewOVR', 'unit_test': False, - 'extension': 'ANGLE_multiview', - 'extension_flag': 'angle_multiview', + 'extension': 'OVR_multiview2', + 'extension_flag': 'ovr_multiview2', 'trace_level': 1, 'es3': True },
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h index 6a04d6c5..1772133b 100644 --- a/gpu/command_buffer/client/gles2_c_lib_autogen.h +++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1900,14 +1900,13 @@ GLES2InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) { gles2::GetGLContext()->InvalidateReadbackBufferShadowDataCHROMIUM(buffer_id); } -void GL_APIENTRY -GLES2FramebufferTextureMultiviewLayeredANGLE(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) { - gles2::GetGLContext()->FramebufferTextureMultiviewLayeredANGLE( +void GL_APIENTRY GLES2FramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) { + gles2::GetGLContext()->FramebufferTextureMultiviewOVR( target, attachment, texture, level, baseViewIndex, numViews); } void GL_APIENTRY GLES2MaxShaderCompilerThreadsKHR(GLuint count) { @@ -3410,9 +3409,9 @@ glInvalidateReadbackBufferShadowDataCHROMIUM), }, { - "glFramebufferTextureMultiviewLayeredANGLE", + "glFramebufferTextureMultiviewOVR", reinterpret_cast<GLES2FunctionPointer>( - glFramebufferTextureMultiviewLayeredANGLE), + glFramebufferTextureMultiviewOVR), }, { "glMaxShaderCompilerThreadsKHR",
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h index dc77c30b..dbe1d60 100644 --- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h +++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -3524,14 +3524,14 @@ } } -void FramebufferTextureMultiviewLayeredANGLE(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) { - gles2::cmds::FramebufferTextureMultiviewLayeredANGLE* c = - GetCmdSpace<gles2::cmds::FramebufferTextureMultiviewLayeredANGLE>(); +void FramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) { + gles2::cmds::FramebufferTextureMultiviewOVR* c = + GetCmdSpace<gles2::cmds::FramebufferTextureMultiviewOVR>(); if (c) { c->Init(target, attachment, texture, level, baseViewIndex, numViews); }
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h index adfb552..dd25fd000 100644 --- a/gpu/command_buffer/client/gles2_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1339,12 +1339,12 @@ void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) override; -void FramebufferTextureMultiviewLayeredANGLE(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) override; +void FramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) override; void MaxShaderCompilerThreadsKHR(GLuint count) override;
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h index 13b3676..123fcfe0 100644 --- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3790,26 +3790,25 @@ CheckGLError(); } -void GLES2Implementation::FramebufferTextureMultiviewLayeredANGLE( - GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) { +void GLES2Implementation::FramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) { GPU_CLIENT_SINGLE_THREAD_CHECK(); - GPU_CLIENT_LOG( - "[" << GetLogPrefix() << "] glFramebufferTextureMultiviewLayeredANGLE(" - << GLES2Util::GetStringEnum(target) << ", " - << GLES2Util::GetStringEnum(attachment) << ", " << texture << ", " - << level << ", " << baseViewIndex << ", " << numViews << ")"); + GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFramebufferTextureMultiviewOVR(" + << GLES2Util::GetStringEnum(target) << ", " + << GLES2Util::GetStringEnum(attachment) << ", " << texture + << ", " << level << ", " << baseViewIndex << ", " + << numViews << ")"); if (numViews < 0) { - SetGLError(GL_INVALID_VALUE, "glFramebufferTextureMultiviewLayeredANGLE", + SetGLError(GL_INVALID_VALUE, "glFramebufferTextureMultiviewOVR", "numViews < 0"); return; } - helper_->FramebufferTextureMultiviewLayeredANGLE( - target, attachment, texture, level, baseViewIndex, numViews); + helper_->FramebufferTextureMultiviewOVR(target, attachment, texture, level, + baseViewIndex, numViews); CheckGLError(); }
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h index b14a3e39..bc43ccd 100644 --- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h +++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -3227,14 +3227,14 @@ EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); } -TEST_F(GLES2ImplementationTest, FramebufferTextureMultiviewLayeredANGLE) { +TEST_F(GLES2ImplementationTest, FramebufferTextureMultiviewOVR) { struct Cmds { - cmds::FramebufferTextureMultiviewLayeredANGLE cmd; + cmds::FramebufferTextureMultiviewOVR cmd; }; Cmds expected; expected.cmd.Init(1, 2, 3, 4, 5, 6); - gl_->FramebufferTextureMultiviewLayeredANGLE(1, 2, 3, 4, 5, 6); + gl_->FramebufferTextureMultiviewOVR(1, 2, 3, 4, 5, 6); EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected))); }
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h index addc988..dcf283b6 100644 --- a/gpu/command_buffer/client/gles2_interface_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -1007,12 +1007,12 @@ virtual void WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) = 0; virtual void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) = 0; virtual void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) = 0; -virtual void FramebufferTextureMultiviewLayeredANGLE(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) = 0; +virtual void FramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) = 0; virtual void MaxShaderCompilerThreadsKHR(GLuint count) = 0; virtual GLuint CreateAndTexStorage2DSharedImageCHROMIUM( const GLbyte* mailbox) = 0;
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h index ae86d59..bd728ed 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -977,12 +977,12 @@ void WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) override; void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) override; void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) override; -void FramebufferTextureMultiviewLayeredANGLE(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) override; +void FramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) override; void MaxShaderCompilerThreadsKHR(GLuint count) override; GLuint CreateAndTexStorage2DSharedImageCHROMIUM(const GLbyte* mailbox) override; GLuint CreateAndTexStorage2DSharedImageWithInternalFormatCHROMIUM(
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h index 84434791..3057310 100644 --- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1298,7 +1298,7 @@ void GLES2InterfaceStub::DestroyGpuFenceCHROMIUM(GLuint /* gpu_fence_id */) {} void GLES2InterfaceStub::InvalidateReadbackBufferShadowDataCHROMIUM( GLuint /* buffer_id */) {} -void GLES2InterfaceStub::FramebufferTextureMultiviewLayeredANGLE( +void GLES2InterfaceStub::FramebufferTextureMultiviewOVR( GLenum /* target */, GLenum /* attachment */, GLuint /* texture */,
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h index dc5f349..6f6b8dde 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -977,12 +977,12 @@ void WaitGpuFenceCHROMIUM(GLuint gpu_fence_id) override; void DestroyGpuFenceCHROMIUM(GLuint gpu_fence_id) override; void InvalidateReadbackBufferShadowDataCHROMIUM(GLuint buffer_id) override; -void FramebufferTextureMultiviewLayeredANGLE(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) override; +void FramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) override; void MaxShaderCompilerThreadsKHR(GLuint count) override; GLuint CreateAndTexStorage2DSharedImageCHROMIUM(const GLbyte* mailbox) override; GLuint CreateAndTexStorage2DSharedImageWithInternalFormatCHROMIUM(
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h index 1715ee82..4a0a5288 100644 --- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h +++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2731,17 +2731,17 @@ gl_->InvalidateReadbackBufferShadowDataCHROMIUM(buffer_id); } -void GLES2TraceImplementation::FramebufferTextureMultiviewLayeredANGLE( +void GLES2TraceImplementation::FramebufferTextureMultiviewOVR( GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews) { - TRACE_EVENT_BINARY_EFFICIENT0( - "gpu", "GLES2Trace::FramebufferTextureMultiviewLayeredANGLE"); - gl_->FramebufferTextureMultiviewLayeredANGLE(target, attachment, texture, - level, baseViewIndex, numViews); + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "GLES2Trace::FramebufferTextureMultiviewOVR"); + gl_->FramebufferTextureMultiviewOVR(target, attachment, texture, level, + baseViewIndex, numViews); } void GLES2TraceImplementation::MaxShaderCompilerThreadsKHR(GLuint count) {
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h index ebc1f78..cf009da4 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -17353,9 +17353,9 @@ offsetof(SetReadbackBufferShadowAllocationINTERNAL, size) == 16, "offset of SetReadbackBufferShadowAllocationINTERNAL size should be 16"); -struct FramebufferTextureMultiviewLayeredANGLE { - typedef FramebufferTextureMultiviewLayeredANGLE ValueType; - static const CommandId kCmdId = kFramebufferTextureMultiviewLayeredANGLE; +struct FramebufferTextureMultiviewOVR { + typedef FramebufferTextureMultiviewOVR ValueType; + static const CommandId kCmdId = kFramebufferTextureMultiviewOVR; static const cmd::ArgFlags kArgFlags = cmd::kFixed; static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(1); @@ -17401,30 +17401,24 @@ int32_t numViews; }; -static_assert(sizeof(FramebufferTextureMultiviewLayeredANGLE) == 28, - "size of FramebufferTextureMultiviewLayeredANGLE should be 28"); +static_assert(sizeof(FramebufferTextureMultiviewOVR) == 28, + "size of FramebufferTextureMultiviewOVR should be 28"); +static_assert(offsetof(FramebufferTextureMultiviewOVR, header) == 0, + "offset of FramebufferTextureMultiviewOVR header should be 0"); +static_assert(offsetof(FramebufferTextureMultiviewOVR, target) == 4, + "offset of FramebufferTextureMultiviewOVR target should be 4"); static_assert( - offsetof(FramebufferTextureMultiviewLayeredANGLE, header) == 0, - "offset of FramebufferTextureMultiviewLayeredANGLE header should be 0"); + offsetof(FramebufferTextureMultiviewOVR, attachment) == 8, + "offset of FramebufferTextureMultiviewOVR attachment should be 8"); +static_assert(offsetof(FramebufferTextureMultiviewOVR, texture) == 12, + "offset of FramebufferTextureMultiviewOVR texture should be 12"); +static_assert(offsetof(FramebufferTextureMultiviewOVR, level) == 16, + "offset of FramebufferTextureMultiviewOVR level should be 16"); static_assert( - offsetof(FramebufferTextureMultiviewLayeredANGLE, target) == 4, - "offset of FramebufferTextureMultiviewLayeredANGLE target should be 4"); -static_assert( - offsetof(FramebufferTextureMultiviewLayeredANGLE, attachment) == 8, - "offset of FramebufferTextureMultiviewLayeredANGLE attachment should be 8"); -static_assert( - offsetof(FramebufferTextureMultiviewLayeredANGLE, texture) == 12, - "offset of FramebufferTextureMultiviewLayeredANGLE texture should be 12"); -static_assert( - offsetof(FramebufferTextureMultiviewLayeredANGLE, level) == 16, - "offset of FramebufferTextureMultiviewLayeredANGLE level should be 16"); -static_assert(offsetof(FramebufferTextureMultiviewLayeredANGLE, - baseViewIndex) == 20, - "offset of FramebufferTextureMultiviewLayeredANGLE baseViewIndex " - "should be 20"); -static_assert( - offsetof(FramebufferTextureMultiviewLayeredANGLE, numViews) == 24, - "offset of FramebufferTextureMultiviewLayeredANGLE numViews should be 24"); + offsetof(FramebufferTextureMultiviewOVR, baseViewIndex) == 20, + "offset of FramebufferTextureMultiviewOVR baseViewIndex should be 20"); +static_assert(offsetof(FramebufferTextureMultiviewOVR, numViews) == 24, + "offset of FramebufferTextureMultiviewOVR numViews should be 24"); struct MaxShaderCompilerThreadsKHR { typedef MaxShaderCompilerThreadsKHR ValueType;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h index fd913f8..ee423c7 100644 --- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -5727,15 +5727,14 @@ CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd)); } -TEST_F(GLES2FormatTest, FramebufferTextureMultiviewLayeredANGLE) { - cmds::FramebufferTextureMultiviewLayeredANGLE& cmd = - *GetBufferAs<cmds::FramebufferTextureMultiviewLayeredANGLE>(); +TEST_F(GLES2FormatTest, FramebufferTextureMultiviewOVR) { + cmds::FramebufferTextureMultiviewOVR& cmd = + *GetBufferAs<cmds::FramebufferTextureMultiviewOVR>(); void* next_cmd = cmd.Set(&cmd, static_cast<GLenum>(11), static_cast<GLenum>(12), static_cast<GLuint>(13), static_cast<GLint>(14), static_cast<GLint>(15), static_cast<GLsizei>(16)); - EXPECT_EQ(static_cast<uint32_t>( - cmds::FramebufferTextureMultiviewLayeredANGLE::kCmdId), + EXPECT_EQ(static_cast<uint32_t>(cmds::FramebufferTextureMultiviewOVR::kCmdId), cmd.header.command); EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u); EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h index 5fab1e6..3f3f1598 100644 --- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h +++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -356,7 +356,7 @@ OP(WaitGpuFenceCHROMIUM) /* 597 */ \ OP(DestroyGpuFenceCHROMIUM) /* 598 */ \ OP(SetReadbackBufferShadowAllocationINTERNAL) /* 599 */ \ - OP(FramebufferTextureMultiviewLayeredANGLE) /* 600 */ \ + OP(FramebufferTextureMultiviewOVR) /* 600 */ \ OP(MaxShaderCompilerThreadsKHR) /* 601 */ \ OP(CreateAndTexStorage2DSharedImageINTERNALImmediate) /* 602 */ \ OP(BeginSharedImageAccessDirectCHROMIUM) /* 603 */ \
diff --git a/gpu/command_buffer/gles2_cmd_buffer_functions.txt b/gpu/command_buffer/gles2_cmd_buffer_functions.txt index e56a66c..7c3d121 100644 --- a/gpu/command_buffer/gles2_cmd_buffer_functions.txt +++ b/gpu/command_buffer/gles2_cmd_buffer_functions.txt
@@ -417,8 +417,8 @@ // (used for CHROMIUM_nonblocking_readback implementation) GL_APICALL void GL_APIENTRY glSetReadbackBufferShadowAllocationINTERNAL (GLidBuffer buffer_id, GLint shm_id, GLuint shm_offset, GLuint size); -// Extension ANGLE_multiview -GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewLayeredANGLE (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); +// Extension OVR_multiview2 +GL_APICALL void GL_APIENTRY glFramebufferTextureMultiviewOVR (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint baseViewIndex, GLsizei numViews); // Extension KHR_parallel_shader_compile GL_APICALL void GL_APIENTRY glMaxShaderCompilerThreadsKHR (GLuint count);
diff --git a/gpu/command_buffer/service/external_vk_image_skia_representation.cc b/gpu/command_buffer/service/external_vk_image_skia_representation.cc index e5d11dc..d8b662fd 100644 --- a/gpu/command_buffer/service/external_vk_image_skia_representation.cc +++ b/gpu/command_buffer/service/external_vk_image_skia_representation.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/trace_event/trace_event.h" +#include "gpu/vulkan/vulkan_fence_helper.h" #include "gpu/vulkan/vulkan_function_pointers.h" #include "gpu/vulkan/vulkan_util.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" @@ -20,27 +21,9 @@ SharedImageBacking* backing, MemoryTypeTracker* tracker) : SharedImageRepresentationSkia(manager, backing, tracker) { - VkFenceCreateInfo create_info = { - .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - }; - VkResult result = - vkCreateFence(vk_device(), &create_info, nullptr /* pAllocator */, - &begin_access_fence_); - DCHECK_EQ(result, VK_SUCCESS); - result = vkCreateFence(vk_device(), &create_info, nullptr /* pAllocator */, - &end_access_fence_); - DCHECK_EQ(result, VK_SUCCESS); } ExternalVkImageSkiaRepresentation::~ExternalVkImageSkiaRepresentation() { - DestroySemaphores(std::move(begin_access_semaphores_), begin_access_fence_); - begin_access_semaphores_.clear(); - DestroySemaphore(end_access_semaphore_, end_access_fence_); - end_access_semaphore_ = VK_NULL_HANDLE; - vkDestroyFence(vk_device(), begin_access_fence_, nullptr /* pAllocator */); - vkDestroyFence(vk_device(), end_access_fence_, nullptr /* pAllocator */); } sk_sp<SkSurface> ExternalVkImageSkiaRepresentation::BeginWriteAccess( @@ -95,32 +78,33 @@ sk_sp<SkPromiseImageTexture> ExternalVkImageSkiaRepresentation::BeginAccess( bool readonly) { DCHECK_EQ(access_mode_, kNone); - DestroySemaphores(std::move(begin_access_semaphores_), begin_access_fence_); - begin_access_semaphores_.clear(); std::vector<SemaphoreHandle> handles; if (!backing_impl()->BeginAccess(readonly, &handles)) return nullptr; + std::vector<VkSemaphore> begin_access_semaphores; for (auto& handle : handles) { VkSemaphore semaphore = vk_implementation()->ImportSemaphoreHandle( vk_device(), std::move(handle)); if (semaphore != VK_NULL_HANDLE) - begin_access_semaphores_.push_back(semaphore); + begin_access_semaphores.push_back(semaphore); } - if (!begin_access_semaphores_.empty()) { + if (!begin_access_semaphores.empty()) { // Submit wait semaphore to the queue. Note that Skia uses the same queue // exposed by vk_queue(), so this will work due to Vulkan queue ordering. - if (!SubmitWaitVkSemaphores(vk_queue(), begin_access_semaphores_, - begin_access_fence_)) { + if (!SubmitWaitVkSemaphores(vk_queue(), begin_access_semaphores)) { LOG(ERROR) << "Failed to wait on semaphore"; // Since the semaphore was not actually sent to the queue, it is safe to - // destroy the |begin_access_semaphores_| here. - DestroySemaphores(std::move(begin_access_semaphores_)); - begin_access_semaphores_.clear(); + // destroy the |begin_access_semaphores| here. + DestroySemaphoresImmediate(std::move(begin_access_semaphores)); return nullptr; } + + // Enqueue delayed cleanup of the semaphores. + fence_helper()->EnqueueSemaphoresCleanupForSubmittedWork( + std::move(begin_access_semaphores)); } // Create backend texture from the VkImage. @@ -137,58 +121,59 @@ void ExternalVkImageSkiaRepresentation::EndAccess(bool readonly) { DCHECK_NE(access_mode_, kNone); - // Cleanup resources for previous accessing. - DestroySemaphore(end_access_semaphore_, end_access_fence_); - end_access_semaphore_ = + VkSemaphore end_access_semaphore = vk_implementation()->CreateExternalSemaphore(backing_impl()->device()); - // Submit wait semaphore to the queue. Note that Skia uses the same queue - // exposed by vk_queue(), so this will work due to Vulkan queue ordering. - if (!SubmitSignalVkSemaphore(vk_queue(), end_access_semaphore_, - end_access_fence_)) { - LOG(ERROR) << "Failed to wait on semaphore"; - // Since the semaphore was not actually sent to the queue, it is safe to - // destroy the |end_access_semaphore_| here. - DestroySemaphore(end_access_semaphore_); - end_access_semaphore_ = VK_NULL_HANDLE; + VkFence end_access_fence = VK_NULL_HANDLE; + if (end_access_semaphore != VK_NULL_HANDLE) { + if (VK_SUCCESS != fence_helper()->GetFence(&end_access_fence)) { + // Since the semaphore was not actually sent to the queue, it is safe to + // destroy the |end_access_semaphore| here. + DestroySemaphoreImmediate(end_access_semaphore); + } + // Submit wait semaphore to the queue. Note that Skia uses the same queue + // exposed by vk_queue(), so this will work due to Vulkan queue ordering. + if (!SubmitSignalVkSemaphore(vk_queue(), end_access_semaphore, + end_access_fence)) { + LOG(ERROR) << "Failed to wait on semaphore"; + // Since the semaphore was not actually sent to the queue, it is safe to + // destroy the |end_access_semaphore| here. + DestroySemaphoreImmediate(end_access_semaphore); + // Same for the fence. + vkDestroyFence(vk_device(), end_access_fence, nullptr); + end_access_fence = VK_NULL_HANDLE; + end_access_semaphore = VK_NULL_HANDLE; + } } SemaphoreHandle handle; - if (end_access_semaphore_ != VK_NULL_HANDLE) { + if (end_access_semaphore != VK_NULL_HANDLE) { handle = vk_implementation()->GetSemaphoreHandle(vk_device(), - end_access_semaphore_); + end_access_semaphore); if (!handle.is_valid()) LOG(FATAL) << "Failed to get handle from a semaphore."; + + // We're done with the semaphore, enqueue deferred cleanup. + fence_helper()->EnqueueSemaphoreCleanupForSubmittedWork( + end_access_semaphore); + fence_helper()->EnqueueFence(end_access_fence); } backing_impl()->EndAccess(readonly, std::move(handle)); } -void ExternalVkImageSkiaRepresentation::DestroySemaphores( - std::vector<VkSemaphore> semaphores, - VkFence fence) { +void ExternalVkImageSkiaRepresentation::DestroySemaphoresImmediate( + std::vector<VkSemaphore> semaphores) { if (semaphores.empty()) return; - if (fence != VK_NULL_HANDLE) - WaitAndResetFence(fence); for (VkSemaphore semaphore : semaphores) vkDestroySemaphore(vk_device(), semaphore, nullptr /* pAllocator */); } -void ExternalVkImageSkiaRepresentation::DestroySemaphore(VkSemaphore semaphore, - VkFence fence) { +void ExternalVkImageSkiaRepresentation::DestroySemaphoreImmediate( + VkSemaphore semaphore) { if (semaphore == VK_NULL_HANDLE) return; - if (fence != VK_NULL_HANDLE) - WaitAndResetFence(fence); - vkDestroySemaphore(vk_device(), semaphore, nullptr /* pAllocator */); -} - -void ExternalVkImageSkiaRepresentation::WaitAndResetFence(VkFence fence) { - TRACE_EVENT0("gpu", "ExternalVkImageSkiaRepresentation::WaitAndResetFence"); - VkResult result = vkWaitForFences(vk_device(), 1, &fence, VK_TRUE, - std::numeric_limits<uint64_t>::max()); - LOG_IF(FATAL, result != VK_SUCCESS) << "vkWaitForFences failed."; - vkResetFences(vk_device(), 1, &fence); + return DestroySemaphoresImmediate({semaphore}); } } // namespace gpu
diff --git a/gpu/command_buffer/service/external_vk_image_skia_representation.h b/gpu/command_buffer/service/external_vk_image_skia_representation.h index 18adf54..516766f 100644 --- a/gpu/command_buffer/service/external_vk_image_skia_representation.h +++ b/gpu/command_buffer/service/external_vk_image_skia_representation.h
@@ -55,18 +55,24 @@ ->GetVulkanQueue(); } + VulkanFenceHelper* fence_helper() { + return backing_impl() + ->context_state() + ->vk_context_provider() + ->GetDeviceQueue() + ->GetFenceHelper(); + } + ExternalVkImageBacking* backing_impl() { return static_cast<ExternalVkImageBacking*>(backing()); } sk_sp<SkPromiseImageTexture> BeginAccess(bool readonly); void EndAccess(bool readonly); - void DestroySemaphores(std::vector<VkSemaphore> semaphores, - VkFence fence = VK_NULL_HANDLE); - void DestroySemaphore(VkSemaphore semaphores, VkFence fence = VK_NULL_HANDLE); - void WaitAndResetFence(VkFence fence); - VkFence CreateFence(); + // Functions used in error cases - immediately clean up semaphores. + void DestroySemaphoresImmediate(std::vector<VkSemaphore> semaphores); + void DestroySemaphoreImmediate(VkSemaphore semaphores); enum AccessMode { kNone = 0, @@ -75,12 +81,6 @@ }; AccessMode access_mode_ = kNone; sk_sp<SkSurface> surface_; - - std::vector<VkSemaphore> begin_access_semaphores_; - VkFence begin_access_fence_ = VK_NULL_HANDLE; - - VkSemaphore end_access_semaphore_ = VK_NULL_HANDLE; - VkFence end_access_fence_ = VK_NULL_HANDLE; }; } // namespace gpu
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index 0716c4f..a2ed6be 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc
@@ -1523,13 +1523,13 @@ AddExtensionString("GL_MESA_framebuffer_flip_y"); } - // Only supporting ANGLE_multiview in passthrough mode - not implemented in + // Only supporting OVR_multiview in passthrough mode - not implemented in // validating command decoder. The extension is only available in ANGLE and in // that case Chromium should be using passthrough by default. if (is_passthrough_cmd_decoder_ && - gfx::HasExtension(extensions, "GL_ANGLE_multiview")) { - AddExtensionString("GL_ANGLE_multiview"); - feature_flags_.angle_multiview = true; + gfx::HasExtension(extensions, "GL_OVR_multiview2")) { + AddExtensionString("GL_OVR_multiview2"); + feature_flags_.ovr_multiview2 = true; } if (is_passthrough_cmd_decoder_ &&
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index c5ceec10f..9ad2b78 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h
@@ -137,7 +137,7 @@ bool unpremultiply_and_dither_copy = false; bool separate_stencil_ref_mask_writemask = false; bool mesa_framebuffer_flip_y = false; - bool angle_multiview = false; + bool ovr_multiview2 = false; bool khr_parallel_shader_compile = false; bool android_surface_control = false; bool khr_robust_buffer_access_behavior = false;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 9459fd0..881c4d0 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1759,12 +1759,12 @@ GLint layer); // Wrapper for glFramebufferTextureLayer. - void DoFramebufferTextureMultiviewLayeredANGLE(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint base_view_index, - GLsizei num_views); + void DoFramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint base_view_index, + GLsizei num_views); // Wrapper for glGenerateMipmap void DoGenerateMipmap(GLenum target); @@ -8622,7 +8622,7 @@ } } -void GLES2DecoderImpl::DoFramebufferTextureMultiviewLayeredANGLE( +void GLES2DecoderImpl::DoFramebufferTextureMultiviewOVR( GLenum target, GLenum attachment, GLuint client_texture_id,
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h index 8c4d715..d79dc20 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -5561,16 +5561,15 @@ return error::kNoError; } -error::Error GLES2DecoderImpl::HandleFramebufferTextureMultiviewLayeredANGLE( +error::Error GLES2DecoderImpl::HandleFramebufferTextureMultiviewOVR( uint32_t immediate_data_size, const volatile void* cmd_data) { if (!feature_info_->IsWebGL2OrES3OrHigherContext()) return error::kUnknownCommand; - const volatile gles2::cmds::FramebufferTextureMultiviewLayeredANGLE& c = - *static_cast< - const volatile gles2::cmds::FramebufferTextureMultiviewLayeredANGLE*>( + const volatile gles2::cmds::FramebufferTextureMultiviewOVR& c = + *static_cast<const volatile gles2::cmds::FramebufferTextureMultiviewOVR*>( cmd_data); - if (!features().angle_multiview) { + if (!features().ovr_multiview2) { return error::kUnknownCommand; } @@ -5581,13 +5580,12 @@ GLint baseViewIndex = static_cast<GLint>(c.baseViewIndex); GLsizei numViews = static_cast<GLsizei>(c.numViews); if (numViews < 0) { - LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, - "glFramebufferTextureMultiviewLayeredANGLE", + LOCAL_SET_GL_ERROR(GL_INVALID_VALUE, "glFramebufferTextureMultiviewOVR", "numViews < 0"); return error::kNoError; } - DoFramebufferTextureMultiviewLayeredANGLE(target, attachment, texture, level, - baseViewIndex, numViews); + DoFramebufferTextureMultiviewOVR(target, attachment, texture, level, + baseViewIndex, numViews); return error::kNoError; }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h index 6605a36..1fb7aa15 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
@@ -200,12 +200,12 @@ GLuint texture, GLint level, GLint layer); -error::Error DoFramebufferTextureMultiviewLayeredANGLE(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint base_view_index, - GLsizei num_views); +error::Error DoFramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint base_view_index, + GLsizei num_views); error::Error DoFrontFace(GLenum mode); error::Error DoGenBuffers(GLsizei n, volatile GLuint* buffers); error::Error DoGenerateMipmap(GLenum target);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc index 3f1d15f..6c2d585fc 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -1299,8 +1299,7 @@ return error::kNoError; } -error::Error -GLES2DecoderPassthroughImpl::DoFramebufferTextureMultiviewLayeredANGLE( +error::Error GLES2DecoderPassthroughImpl::DoFramebufferTextureMultiviewOVR( GLenum target, GLenum attachment, GLuint texture, @@ -1312,7 +1311,7 @@ "Cannot change the attachments of the default framebuffer."); return error::kNoError; } - api()->glFramebufferTextureMultiviewLayeredANGLEFn( + api()->glFramebufferTextureMultiviewOVRFn( target, attachment, GetTextureServiceID(api(), texture, resources_, false), level, base_view_index, num_views);
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc index 3266134..0abeb0b 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
@@ -4835,17 +4835,15 @@ return error::kNoError; } -error::Error -GLES2DecoderPassthroughImpl::HandleFramebufferTextureMultiviewLayeredANGLE( +error::Error GLES2DecoderPassthroughImpl::HandleFramebufferTextureMultiviewOVR( uint32_t immediate_data_size, const volatile void* cmd_data) { if (!feature_info_->IsWebGL2OrES3OrHigherContext()) return error::kUnknownCommand; - const volatile gles2::cmds::FramebufferTextureMultiviewLayeredANGLE& c = - *static_cast< - const volatile gles2::cmds::FramebufferTextureMultiviewLayeredANGLE*>( + const volatile gles2::cmds::FramebufferTextureMultiviewOVR& c = + *static_cast<const volatile gles2::cmds::FramebufferTextureMultiviewOVR*>( cmd_data); - if (!features().angle_multiview) { + if (!features().ovr_multiview2) { return error::kUnknownCommand; } @@ -4855,7 +4853,7 @@ GLint level = static_cast<GLint>(c.level); GLint baseViewIndex = static_cast<GLint>(c.baseViewIndex); GLsizei numViews = static_cast<GLsizei>(c.numViews); - error::Error error = DoFramebufferTextureMultiviewLayeredANGLE( + error::Error error = DoFramebufferTextureMultiviewOVR( target, attachment, texture, level, baseViewIndex, numViews); if (error != error::kNoError) { return error;
diff --git a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc index a83edf30..0c9de256 100644 --- a/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc +++ b/gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.cc
@@ -33,6 +33,7 @@ #include "gpu/command_buffer/service/texture_manager.h" #include "gpu/ipc/common/android/android_image_reader_utils.h" #include "gpu/vulkan/vulkan_device_queue.h" +#include "gpu/vulkan/vulkan_fence_helper.h" #include "gpu/vulkan/vulkan_function_pointers.h" #include "gpu/vulkan/vulkan_implementation.h" #include "gpu/vulkan/vulkan_util.h" @@ -72,71 +73,52 @@ return os; } -void DestroySemaphore(VkDevice vk_device, - VkQueue vk_queue, - VkSemaphore semaphore) { - if (semaphore == VK_NULL_HANDLE) - return; +bool BeginVulkanAccess(viz::VulkanContextProvider* context_provider, + base::ScopedFD begin_sync_fd) { + VkDevice vk_device = context_provider->GetDeviceQueue()->GetVulkanDevice(); + VulkanImplementation* vk_implementation = + context_provider->GetVulkanImplementation(); + VulkanFenceHelper* fence_helper = + context_provider->GetDeviceQueue()->GetFenceHelper(); + VkQueue vk_queue = context_provider->GetDeviceQueue()->GetVulkanQueue(); - // TODO(vikassoni): Need to do better semaphore cleanup management. Waiting - // on device to be idle to delete the semaphore is costly. Instead use a - // fence to get signal when semaphore submission is done. - VkResult result = vkQueueWaitIdle(vk_queue); - if (result != VK_SUCCESS) { - LOG(ERROR) << "vkQueueWaitIdle failed: " << result; - return; + // Wait on the provided |begin_sync_fd|. + VkSemaphore semaphore = VK_NULL_HANDLE; + if (begin_sync_fd.is_valid()) { + semaphore = vk_implementation->ImportSemaphoreHandle( + vk_device, + SemaphoreHandle(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, + std::move(begin_sync_fd))); + if (semaphore == VK_NULL_HANDLE) { + return false; + } + + // Submit wait semaphore to the queue. Note that Skia uses the same queue + // exposed by vk_queue(), so this will work due to Vulkan queue ordering. + if (!SubmitWaitVkSemaphore(vk_queue, semaphore)) { + vkDestroySemaphore(vk_device, semaphore, nullptr); + return false; + } + + // Enqueue destruction of the semaphore here. + // TODO(ericrk): Don't worry about generating a fence above, we will + // generate one in EndVulkanAccess. Refactoring will remove this path + // soon. + fence_helper->EnqueueSemaphoreCleanupForSubmittedWork(semaphore); } - vkDestroySemaphore(vk_device, semaphore, nullptr); + return true; } -sk_sp<SkPromiseImageTexture> BeginVulkanAccess( - gpu::VulkanImplementation* vk_implementation, - VkDevice vk_device, - VkPhysicalDevice vk_physical_device, - VkQueue vk_queue, - base::android::ScopedHardwareBufferHandle ahb_handle, - gfx::Size size, - viz::ResourceFormat format, - VkSemaphore semaphore_to_clean) { - // Create a VkImage and import AHB. - VkImage vk_image; - VkImageCreateInfo vk_image_info; - VkDeviceMemory vk_device_memory; - VkDeviceSize mem_allocation_size; - if (!vk_implementation->CreateVkImageAndImportAHB( - vk_device, vk_physical_device, size, std::move(ahb_handle), &vk_image, - &vk_image_info, &vk_device_memory, &mem_allocation_size)) { - return nullptr; - } - - // Create backend texture from the VkImage. - GrVkAlloc alloc = {vk_device_memory, 0, mem_allocation_size, 0}; - GrVkImageInfo vk_info = {vk_image, - alloc, - vk_image_info.tiling, - vk_image_info.initialLayout, - vk_image_info.format, - vk_image_info.mipLevels}; - // TODO(bsalomon): Determine whether it makes sense to attempt to reuse this - // if the vk_info stays the same on subsequent calls. - auto promise_texture = SkPromiseImageTexture::Make( - GrBackendTexture(size.width(), size.height(), vk_info)); - if (!promise_texture) { - vkDestroyImage(vk_device, vk_image, nullptr); - vkFreeMemory(vk_device, vk_device_memory, nullptr); - return nullptr; - } - - DestroySemaphore(vk_device, vk_queue, semaphore_to_clean); - - return promise_texture; -} - -void EndVulkanAccess(gpu::VulkanImplementation* vk_implementation, - VkDevice vk_device, - VkQueue vk_queue, +void EndVulkanAccess(viz::VulkanContextProvider* context_provider, base::ScopedFD* sync_fd) { + VulkanImplementation* vk_implementation = + context_provider->GetVulkanImplementation(); + VkDevice vk_device = context_provider->GetDeviceQueue()->GetVulkanDevice(); + VkQueue vk_queue = context_provider->GetDeviceQueue()->GetVulkanQueue(); + VulkanFenceHelper* fence_helper = + context_provider->GetDeviceQueue()->GetFenceHelper(); + // Create a vk semaphore which can be exported. VkExportSemaphoreCreateInfo export_info; export_info.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO; @@ -155,8 +137,15 @@ return; } - if (!SubmitSignalVkSemaphore(vk_queue, vk_semaphore, - VK_NULL_HANDLE /* vk_fence */)) { + VkFence vk_fence; + result = fence_helper->GetFence(&vk_fence); + if (result != VK_SUCCESS) { + LOG(ERROR) << "Failed to create fence."; + vkDestroySemaphore(vk_device, vk_semaphore, nullptr); + return; + } + + if (!SubmitSignalVkSemaphore(vk_queue, vk_semaphore, vk_fence)) { LOG(ERROR) << "Failed to wait on semaphore"; vkDestroySemaphore(vk_device, vk_semaphore, nullptr); return; @@ -167,18 +156,69 @@ vk_implementation->GetSemaphoreHandle(vk_device, vk_semaphore); *sync_fd = semaphore_handle.TakeHandle(); - // TODO(vikassoni): We need to wait for the queue submission to complete - // before we can destroy the semaphore. This will decrease the performance. - // Add a future patch to handle this in more efficient way. Keep semaphores - // in a STL queue instead of destroying it. Later use a fence to check if - // the batch that refers the semaphore has completed execution. Delete the - // semaphore once the fence is signalled. - result = vkQueueWaitIdle(vk_queue); - if (result != VK_SUCCESS) { - LOG(ERROR) << "vkQueueWaitIdle failed: " << result; - return; + // Enqueue cleanup of the semaphore based on the submission fence. + fence_helper->EnqueueSemaphoreCleanupForSubmittedWork(vk_semaphore); + fence_helper->EnqueueFence(vk_fence); +} + +sk_sp<SkPromiseImageTexture> CreatePromiseTexture( + viz::VulkanContextProvider* context_provider, + base::android::ScopedHardwareBufferHandle ahb_handle, + gfx::Size size, + viz::ResourceFormat format) { + VulkanImplementation* vk_implementation = + context_provider->GetVulkanImplementation(); + VkDevice vk_device = context_provider->GetDeviceQueue()->GetVulkanDevice(); + VkPhysicalDevice vk_physical_device = + context_provider->GetDeviceQueue()->GetVulkanPhysicalDevice(); + + // Create a VkImage and import AHB. + VkImage vk_image; + VkImageCreateInfo vk_image_info; + VkDeviceMemory vk_device_memory; + VkDeviceSize mem_allocation_size; + if (!vk_implementation->CreateVkImageAndImportAHB( + vk_device, vk_physical_device, size, std::move(ahb_handle), &vk_image, + &vk_image_info, &vk_device_memory, &mem_allocation_size)) { + return nullptr; } - vkDestroySemaphore(vk_device, vk_semaphore, nullptr); + + // Create backend texture from the VkImage. + GrVkAlloc alloc = {vk_device_memory, 0, mem_allocation_size, 0}; + GrVkImageInfo vk_info = {vk_image, + alloc, + vk_image_info.tiling, + vk_image_info.initialLayout, + vk_image_info.format, + vk_image_info.mipLevels, + VK_QUEUE_FAMILY_EXTERNAL}; + // TODO(bsalomon): Determine whether it makes sense to attempt to reuse this + // if the vk_info stays the same on subsequent calls. + auto promise_texture = SkPromiseImageTexture::Make( + GrBackendTexture(size.width(), size.height(), vk_info)); + if (!promise_texture) { + vkDestroyImage(vk_device, vk_image, nullptr); + vkFreeMemory(vk_device, vk_device_memory, nullptr); + return nullptr; + } + + return promise_texture; +} + +void DestroyVkPromiseTexture(viz::VulkanContextProvider* context_provider, + sk_sp<SkPromiseImageTexture> promise_texture) { + DCHECK(promise_texture); + DCHECK(promise_texture->unique()); + + GrVkImageInfo vk_image_info; + bool result = + promise_texture->backendTexture().getVkImageInfo(&vk_image_info); + DCHECK(result); + + VulkanFenceHelper* fence_helper = + context_provider->GetDeviceQueue()->GetFenceHelper(); + fence_helper->EnqueueImageCleanupForSubmittedWork( + vk_image_info.fImage, vk_image_info.fAlloc.fMemory); } } // namespace @@ -324,12 +364,12 @@ SharedImageManager* manager, SharedImageBacking* backing, scoped_refptr<SharedContextState> context_state, - sk_sp<SkPromiseImageTexture> cached_promise_image_texture, + sk_sp<SkPromiseImageTexture> promise_texture, MemoryTypeTracker* tracker, gles2::Texture* texture) : SharedImageRepresentationSkia(manager, backing, tracker), context_state_(std::move(context_state)), - promise_texture_(cached_promise_image_texture), + promise_texture_(std::move(promise_texture)), texture_(std::move(texture)) { #if DCHECK_IS_ON() context_ = gl::GLContext::GetCurrent(); @@ -461,17 +501,19 @@ SharedImageRepresentationSkiaVkAHB( SharedImageManager* manager, SharedImageBacking* backing, - scoped_refptr<SharedContextState> context_state) + scoped_refptr<SharedContextState> context_state, + sk_sp<SkPromiseImageTexture> promise_texture) : SharedImageRepresentationSkia(manager, backing, nullptr), + promise_texture_(std::move(promise_texture)), context_state_(std::move(context_state)) { - SharedImageBackingAHB* ahb_backing = - static_cast<SharedImageBackingAHB*>(backing); - DCHECK(ahb_backing); + DCHECK(promise_texture_); DCHECK(context_state_); DCHECK(context_state_->vk_context_provider()); } ~SharedImageRepresentationSkiaVkAHB() override { + DestroyVkPromiseTexture(context_state_->vk_context_provider(), + std::move(promise_texture_)); DCHECK_EQ(mode_, RepresentationAccessMode::kNone); DCHECK(!surface_); } @@ -487,29 +529,10 @@ if (!ahb_backing()->BeginWrite(&sync_fd)) return nullptr; - VkSemaphore semaphore = VK_NULL_HANDLE; - if (sync_fd.is_valid()) { - semaphore = vk_implementation()->ImportSemaphoreHandle( - vk_device(), - SemaphoreHandle(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, - std::move(sync_fd))); - if (semaphore == VK_NULL_HANDLE) { - return nullptr; - } - - // Submit wait semaphore to the queue. Note that Skia uses the same queue - // exposed by vk_queue(), so this will work due to Vulkan queue ordering. - if (!SubmitWaitVkSemaphore(vk_queue(), semaphore)) { - DestroySemaphore(vk_device(), vk_queue(), semaphore); - return nullptr; - } - } - - promise_texture_ = BeginVulkanAccess( - vk_implementation(), vk_device(), vk_phy_device(), vk_queue(), - ahb_backing()->GetAhbHandle(), size(), format(), semaphore); - if (!promise_texture_) + if (!BeginVulkanAccess(context_state_->vk_context_provider(), + std::move(sync_fd))) { return nullptr; + } SkColorType sk_color_type = viz::ResourceFormatToClosestSkColorType( /*gpu_compositing=*/true, format()); @@ -543,32 +566,9 @@ if (!ahb_backing()->BeginRead(this, &sync_fd)) return nullptr; - VkSemaphore semaphore = VK_NULL_HANDLE; - // We need to wait only if there is a valid fd. - if (sync_fd.is_valid()) { - // Import the above sync fd into a semaphore. - semaphore = vk_implementation()->ImportSemaphoreHandle( - vk_device(), - SemaphoreHandle(VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT, - std::move(sync_fd))); - if (semaphore == VK_NULL_HANDLE) - return nullptr; - - // Submit wait semaphore to the queue. Note that Skia uses the same queue - // exposed by vk_queue(), so this will work due to Vulkan queue ordering. - if (!SubmitWaitVkSemaphore(vk_queue(), semaphore)) { - vkDestroySemaphore(vk_device(), semaphore, nullptr); - return nullptr; - } - } - - auto promise_texture = BeginVulkanAccess( - vk_implementation(), vk_device(), vk_phy_device(), vk_queue(), - ahb_backing()->GetAhbHandle(), size(), format(), std::move(semaphore)); - mode_ = RepresentationAccessMode::kRead; - return promise_texture; + return promise_texture_; } void EndReadAccess() override { @@ -576,7 +576,7 @@ DCHECK(!surface_); base::ScopedFD sync_fd; - EndVulkanAccess(vk_implementation(), vk_device(), vk_queue(), &sync_fd); + EndVulkanAccess(context_state_->vk_context_provider(), &sync_fd); // pass this sync fd to the backing. ahb_backing()->EndRead(this, std::move(sync_fd)); @@ -616,7 +616,7 @@ DCHECK(surface_); base::ScopedFD sync_fd; - EndVulkanAccess(vk_implementation(), vk_device(), vk_queue(), &sync_fd); + EndVulkanAccess(context_state_->vk_context_provider(), &sync_fd); surface_ = nullptr; ahb_backing()->EndWrite(std::move(sync_fd)); @@ -726,8 +726,12 @@ // Check whether we are in Vulkan mode OR GL mode and accordingly create // Skia representation. if (context_state->use_vulkan_gr_context()) { + sk_sp<SkPromiseImageTexture> promise_texture = CreatePromiseTexture( + context_state->vk_context_provider(), GetAhbHandle(), size(), format()); + if (!promise_texture) + return nullptr; return std::make_unique<SharedImageRepresentationSkiaVkAHB>( - manager, this, std::move(context_state)); + manager, this, std::move(context_state), std::move(promise_texture)); } auto* texture = GenGLTexture(); @@ -741,8 +745,8 @@ sk_sp<SkPromiseImageTexture> promise_texture = SkPromiseImageTexture::Make(backend_texture); return std::make_unique<SharedImageRepresentationSkiaGLAHB>( - manager, this, std::move(context_state), promise_texture, tracker, - std::move(texture)); + manager, this, std::move(context_state), std::move(promise_texture), + tracker, std::move(texture)); } bool SharedImageBackingAHB::BeginWrite(base::ScopedFD* fd_to_wait_on) {
diff --git a/gpu/command_buffer/service/webgpu_decoder.cc b/gpu/command_buffer/service/webgpu_decoder.cc index f22232b..6291b7f 100644 --- a/gpu/command_buffer/service/webgpu_decoder.cc +++ b/gpu/command_buffer/service/webgpu_decoder.cc
@@ -33,5 +33,14 @@ WebGPUDecoder::~WebGPUDecoder() {} +ContextResult WebGPUDecoder::Initialize( + const scoped_refptr<gl::GLSurface>& surface, + const scoped_refptr<gl::GLContext>& context, + bool offscreen, + const gles2::DisallowedFeatures& disallowed_features, + const ContextCreationAttribs& attrib_helper) { + return ContextResult::kSuccess; +} + } // namespace webgpu } // namespace gpu
diff --git a/gpu/command_buffer/service/webgpu_decoder.h b/gpu/command_buffer/service/webgpu_decoder.h index af9f52e..03b3137 100644 --- a/gpu/command_buffer/service/webgpu_decoder.h +++ b/gpu/command_buffer/service/webgpu_decoder.h
@@ -29,6 +29,16 @@ ~WebGPUDecoder() override; + // WebGPU-specific initialization that's different than DecoderContext's + // Initialize that is tied to GLES2 concepts and a noop for WebGPU decoders. + virtual ContextResult Initialize() = 0; + + ContextResult Initialize(const scoped_refptr<gl::GLSurface>& surface, + const scoped_refptr<gl::GLContext>& context, + bool offscreen, + const gles2::DisallowedFeatures& disallowed_features, + const ContextCreationAttribs& attrib_helper) final; + protected: WebGPUDecoder(DecoderClient* client, CommandBufferServiceBase* command_buffer_service,
diff --git a/gpu/command_buffer/service/webgpu_decoder_impl.cc b/gpu/command_buffer/service/webgpu_decoder_impl.cc index 6ae8475..9d73befd 100644 --- a/gpu/command_buffer/service/webgpu_decoder_impl.cc +++ b/gpu/command_buffer/service/webgpu_decoder_impl.cc
@@ -92,19 +92,14 @@ gles2::Outputter* outputter); ~WebGPUDecoderImpl() override; + // WebGPUDecoder implementation + ContextResult Initialize() override; + // DecoderContext implementation. base::WeakPtr<DecoderContext> AsWeakPtr() override { NOTIMPLEMENTED(); return nullptr; } - ContextResult Initialize( - const scoped_refptr<gl::GLSurface>& surface, - const scoped_refptr<gl::GLContext>& context, - bool offscreen, - const gles2::DisallowedFeatures& disallowed_features, - const ContextCreationAttribs& attrib_helper) override { - return ContextResult::kSuccess; - } const gles2::ContextState* GetContextState() override { NOTREACHED(); return nullptr; @@ -350,11 +345,7 @@ : WebGPUDecoder(client, command_buffer_service, outputter), wire_serializer_(new WireServerCommandSerializer(client)), dawn_instance_(new dawn_native::Instance()), - dawn_procs_(dawn_native::GetProcs()), - dawn_device_(CreateDefaultDevice()), - wire_server_(new dawn_wire::WireServer(dawn_device_, - dawn_procs_, - wire_serializer_.get())) {} + dawn_procs_(dawn_native::GetProcs()) {} WebGPUDecoderImpl::~WebGPUDecoderImpl() { // Reset the wire server first so all objects are destroyed before the device. @@ -365,14 +356,28 @@ } } +ContextResult WebGPUDecoderImpl::Initialize() { + dawn_device_ = CreateDefaultDevice(); + if (dawn_device_ == nullptr) { + return ContextResult::kFatalFailure; + } + + wire_server_ = std::make_unique<dawn_wire::WireServer>( + dawn_device_, dawn_procs_, wire_serializer_.get()); + + return ContextResult::kSuccess; +} + DawnDevice WebGPUDecoderImpl::CreateDefaultDevice() { dawn_instance_->DiscoverDefaultAdapters(); std::vector<dawn_native::Adapter> adapters = dawn_instance_->GetAdapters(); - for (size_t i = 0; i < adapters.size(); ++i) { - return adapters[i].CreateDevice(); + for (dawn_native::Adapter adapter : adapters) { + if (adapter.GetBackendType() != dawn_native::BackendType::Null && + adapter.GetBackendType() != dawn_native::BackendType::OpenGL) { + return adapter.CreateDevice(); + } } - NOTREACHED(); - return {}; + return nullptr; } const char* WebGPUDecoderImpl::GetCommandName(unsigned int command_id) const {
diff --git a/gpu/command_buffer/service/webgpu_decoder_unittest.cc b/gpu/command_buffer/service/webgpu_decoder_unittest.cc index e9ff2f5..5b9a81b8 100644 --- a/gpu/command_buffer/service/webgpu_decoder_unittest.cc +++ b/gpu/command_buffer/service/webgpu_decoder_unittest.cc
@@ -27,8 +27,13 @@ command_buffer_service_.reset(new FakeCommandBufferServiceBase()); decoder_.reset(WebGPUDecoder::Create(nullptr, command_buffer_service_.get(), &outputter_)); + if (decoder_->Initialize() != ContextResult::kSuccess) { + decoder_ = nullptr; + } } + bool WebGPUSupported() const { return decoder_ != nullptr; } + template <typename T> error::Error ExecuteCmd(const T& cmd) { static_assert(T::kArgFlags == cmd::kFixed, @@ -47,6 +52,11 @@ }; TEST_F(WebGPUDecoderTest, Dummy) { + if (!WebGPUSupported()) { + LOG(ERROR) << "Test skipped because WebGPU isn't supported"; + return; + } + cmds::Dummy dummy; dummy.Init(); EXPECT_EQ(error::kNoError, ExecuteCmd(dummy));
diff --git a/gpu/command_buffer/tests/webgpu_test.cc b/gpu/command_buffer/tests/webgpu_test.cc index eacdd134..c3673f4e 100644 --- a/gpu/command_buffer/tests/webgpu_test.cc +++ b/gpu/command_buffer/tests/webgpu_test.cc
@@ -22,9 +22,8 @@ WebGPUTest::WebGPUTest() = default; WebGPUTest::~WebGPUTest() = default; -bool WebGPUTest::WebGPUSupported() { - // crbug.com(941685): Vulkan driver crashes on Linux FYI Release (AMD R7 240). - return !GPUTestBotConfig::CurrentConfigMatches("Linux AMD"); +bool WebGPUTest::WebGPUSupported() const { + return context_ != nullptr; } void WebGPUTest::SetUp() { @@ -37,9 +36,11 @@ } void WebGPUTest::Initialize(const Options& options) { - if (!WebGPUSupported()) { + // crbug.com(941685): Vulkan driver crashes on Linux FYI Release (AMD R7 240). + if (GPUTestBotConfig::CurrentConfigMatches("Linux AMD")) { return; } + ContextCreationAttribs attributes; attributes.bind_generates_resource = false; attributes.enable_gles2_interface = false; @@ -53,7 +54,10 @@ context_->Initialize(gpu_thread_holder_->GetTaskExecutor(), attributes, options.shared_memory_limits, memory_buffer_manager, image_factory, channel_manager); - DCHECK_EQ(result, ContextResult::kSuccess); + if (result != ContextResult::kSuccess) { + context_ = nullptr; + return; + } DawnProcTable procs = webgpu()->GetProcs(); dawnSetProcs(&procs); @@ -69,9 +73,10 @@ TEST_F(WebGPUTest, Dummy) { if (!WebGPUSupported()) { - LOG(ERROR) << "Test skipped"; + LOG(ERROR) << "Test skipped because WebGPU isn't supported"; return; } + Initialize(WebGPUTest::Options()); webgpu()->Dummy(); }
diff --git a/gpu/command_buffer/tests/webgpu_test.h b/gpu/command_buffer/tests/webgpu_test.h index acd37899..45f4803 100644 --- a/gpu/command_buffer/tests/webgpu_test.h +++ b/gpu/command_buffer/tests/webgpu_test.h
@@ -34,7 +34,7 @@ WebGPUTest(); ~WebGPUTest() override; - bool WebGPUSupported(); + bool WebGPUSupported() const; void SetUp() override; void TearDown() override;
diff --git a/gpu/ipc/in_process_command_buffer.cc b/gpu/ipc/in_process_command_buffer.cc index 8f25b70..4dd1f2d05 100644 --- a/gpu/ipc/in_process_command_buffer.cc +++ b/gpu/ipc/in_process_command_buffer.cc
@@ -551,8 +551,16 @@ DLOG(ERROR) << "ContextResult::kFatalFailure: WebGPU not enabled"; return gpu::ContextResult::kFatalFailure; } - decoder_.reset(webgpu::WebGPUDecoder::Create(this, command_buffer_.get(), - task_executor_->outputter())); + std::unique_ptr<webgpu::WebGPUDecoder> webgpu_decoder( + webgpu::WebGPUDecoder::Create(this, command_buffer_.get(), + task_executor_->outputter())); + gpu::ContextResult result = webgpu_decoder->Initialize(); + if (result != gpu::ContextResult::kSuccess) { + DestroyOnGpuThread(); + DLOG(ERROR) << "Failed to initializ WebGPUe decoder."; + return result; + } + decoder_ = std::move(webgpu_decoder); } else { // TODO(khushalsagar): A lot of this initialization code is duplicated in // GpuChannelManager. Pull it into a common util method.
diff --git a/gpu/ipc/service/webgpu_command_buffer_stub.cc b/gpu/ipc/service/webgpu_command_buffer_stub.cc index 2241e15..a8c963d 100644 --- a/gpu/ipc/service/webgpu_command_buffer_stub.cc +++ b/gpu/ipc/service/webgpu_command_buffer_stub.cc
@@ -112,10 +112,7 @@ channel_->sync_point_manager()->CreateSyncPointClientState( CommandBufferNamespace::GPU_IO, command_buffer_id_, sequence_id_); - // Initialize the decoder with either the view or pbuffer GLContext. - ContextResult result = decoder->Initialize( - nullptr, nullptr, true /* offscreen */, gpu::gles2::DisallowedFeatures(), - init_params.attribs); + ContextResult result = decoder->Initialize(); if (result != gpu::ContextResult::kSuccess) { DLOG(ERROR) << "Failed to initialize decoder."; return result;
diff --git a/gpu/vulkan/BUILD.gn b/gpu/vulkan/BUILD.gn index 031c945..fd61fb4 100644 --- a/gpu/vulkan/BUILD.gn +++ b/gpu/vulkan/BUILD.gn
@@ -37,6 +37,8 @@ "vulkan_device_queue.cc", "vulkan_device_queue.h", "vulkan_export.h", + "vulkan_fence_helper.cc", + "vulkan_fence_helper.h", "vulkan_function_pointers.cc", "vulkan_function_pointers.h", "vulkan_implementation.cc", @@ -100,13 +102,17 @@ "tests/native_window.h", "tests/vulkan_test.cc", "tests/vulkan_tests_main.cc", + "vulkan_fence_helper_unittest.cc", ] deps = [ + "//base:base", "//base/test:test_support", + "//components/viz/common:vulkan_context_provider", "//gpu/vulkan/init", "//testing/gmock", "//testing/gtest", + "//ui/gfx", "//ui/gfx:native_widget_types", "//ui/gfx/geometry", ]
diff --git a/gpu/vulkan/tests/vulkan_test.cc b/gpu/vulkan/tests/vulkan_test.cc index 9f14628..bceeb2c 100644 --- a/gpu/vulkan/tests/vulkan_test.cc +++ b/gpu/vulkan/tests/vulkan_test.cc
@@ -18,6 +18,7 @@ EXPECT_TRUE(surface); EXPECT_TRUE(surface->Initialize(GetDeviceQueue(), VulkanSurface::DEFAULT_SURFACE_FORMAT)); + EXPECT_TRUE(surface->SetSize(gfx::Size(100, 100))); surface->Destroy(); } @@ -26,6 +27,7 @@ ASSERT_TRUE(surface); ASSERT_TRUE(surface->Initialize(GetDeviceQueue(), VulkanSurface::DEFAULT_SURFACE_FORMAT)); + ASSERT_TRUE(surface->SetSize(gfx::Size(100, 100))); // First swap is a special case, call it first to get better errors. EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers());
diff --git a/gpu/vulkan/vulkan_command_buffer.cc b/gpu/vulkan/vulkan_command_buffer.cc index d9c5a4d..b762400 100644 --- a/gpu/vulkan/vulkan_command_buffer.cc +++ b/gpu/vulkan/vulkan_command_buffer.cc
@@ -21,8 +21,8 @@ } VulkanCommandBuffer::~VulkanCommandBuffer() { + DCHECK(!submission_fence_.is_valid()); DCHECK_EQ(static_cast<VkCommandBuffer>(VK_NULL_HANDLE), command_buffer_); - DCHECK_EQ(static_cast<VkFence>(VK_NULL_HANDLE), submission_fence_); DCHECK(!recording_); command_pool_->DecrementCommandBufferCount(); } @@ -45,27 +45,15 @@ return false; } - VkFenceCreateInfo fence_create_info = {}; - fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - fence_create_info.flags = VK_FENCE_CREATE_SIGNALED_BIT; - - result = - vkCreateFence(device, &fence_create_info, nullptr, &submission_fence_); - if (VK_SUCCESS != result) { - DLOG(ERROR) << "vkCreateFence(submission) failed: " << result; - return false; - } - record_type_ = RECORD_TYPE_EMPTY; return true; } void VulkanCommandBuffer::Destroy() { VkDevice device = device_queue_->GetVulkanDevice(); - if (VK_NULL_HANDLE != submission_fence_) { - DCHECK(SubmissionFinished()); - vkDestroyFence(device, submission_fence_, nullptr); - submission_fence_ = VK_NULL_HANDLE; + if (submission_fence_.is_valid()) { + DCHECK(device_queue_->GetFenceHelper()->HasPassed(submission_fence_)); + submission_fence_ = VulkanFenceHelper::FenceHandle(); } if (VK_NULL_HANDLE != command_buffer_) { @@ -94,15 +82,22 @@ VkResult result = VK_SUCCESS; - result = - vkResetFences(device_queue_->GetVulkanDevice(), 1, &submission_fence_); + VkFence fence; + result = device_queue_->GetFenceHelper()->GetFence(&fence); if (VK_SUCCESS != result) { - DLOG(ERROR) << "vkResetFences() failed: " << result; + DLOG(ERROR) << "Failed to create fence: " << result; return false; } - result = vkQueueSubmit(device_queue_->GetVulkanQueue(), 1, &submit_info, - submission_fence_); + result = + vkQueueSubmit(device_queue_->GetVulkanQueue(), 1, &submit_info, fence); + + if (VK_SUCCESS != result) { + vkDestroyFence(device_queue_->GetVulkanDevice(), fence, nullptr); + submission_fence_ = VulkanFenceHelper::FenceHandle(); + } else { + submission_fence_ = device_queue_->GetFenceHelper()->EnqueueFence(fence); + } PostExecution(); if (VK_SUCCESS != result) { @@ -127,13 +122,17 @@ } void VulkanCommandBuffer::Wait(uint64_t timeout) { - VkDevice device = device_queue_->GetVulkanDevice(); - vkWaitForFences(device, 1, &submission_fence_, true, timeout); + if (!submission_fence_.is_valid()) + return; + + device_queue_->GetFenceHelper()->Wait(submission_fence_, timeout); } bool VulkanCommandBuffer::SubmissionFinished() { - VkDevice device = device_queue_->GetVulkanDevice(); - return VK_SUCCESS == vkGetFenceStatus(device, submission_fence_); + if (!submission_fence_.is_valid()) + return true; + + return device_queue_->GetFenceHelper()->HasPassed(submission_fence_); } void VulkanCommandBuffer::PostExecution() { @@ -151,8 +150,7 @@ if (record_type_ == RECORD_TYPE_DIRTY) { // Block if command buffer is still in use. This can be externally avoided // using the asynchronous SubmissionFinished() function. - VkDevice device = device_queue_->GetVulkanDevice(); - vkWaitForFences(device, 1, &submission_fence_, true, UINT64_MAX); + Wait(UINT64_MAX); VkResult result = vkResetCommandBuffer(command_buffer_, 0); if (VK_SUCCESS != result) { DLOG(ERROR) << "vkResetCommandBuffer() failed: " << result;
diff --git a/gpu/vulkan/vulkan_command_buffer.h b/gpu/vulkan/vulkan_command_buffer.h index b55b02c..0709267 100644 --- a/gpu/vulkan/vulkan_command_buffer.h +++ b/gpu/vulkan/vulkan_command_buffer.h
@@ -10,6 +10,7 @@ #include "base/logging.h" #include "base/macros.h" #include "gpu/vulkan/vulkan_export.h" +#include "gpu/vulkan/vulkan_fence_helper.h" namespace gpu { @@ -74,7 +75,7 @@ VulkanDeviceQueue* device_queue_; VulkanCommandPool* command_pool_; VkCommandBuffer command_buffer_ = VK_NULL_HANDLE; - VkFence submission_fence_ = VK_NULL_HANDLE; + VulkanFenceHelper::FenceHandle submission_fence_; DISALLOW_COPY_AND_ASSIGN(VulkanCommandBuffer); };
diff --git a/gpu/vulkan/vulkan_device_queue.cc b/gpu/vulkan/vulkan_device_queue.cc index 4fb92a3..4c327ac 100644 --- a/gpu/vulkan/vulkan_device_queue.cc +++ b/gpu/vulkan/vulkan_device_queue.cc
@@ -9,6 +9,7 @@ #include <vector> #include "gpu/vulkan/vulkan_command_pool.h" +#include "gpu/vulkan/vulkan_fence_helper.h" #include "gpu/vulkan/vulkan_function_pointers.h" namespace gpu { @@ -154,6 +155,8 @@ vkGetDeviceQueue(vk_device_, queue_index, 0, &vk_queue_); + cleanup_helper_ = std::make_unique<VulkanFenceHelper>(this); + return true; } @@ -173,10 +176,14 @@ vk_queue_ = vk_queue; vk_queue_index_ = vk_queue_index; enabled_extensions_ = std::move(enabled_extensions); + + cleanup_helper_ = std::make_unique<VulkanFenceHelper>(this); return true; } void VulkanDeviceQueue::Destroy() { + cleanup_helper_.reset(); + if (VK_NULL_HANDLE != owned_vk_device_) { vkDestroyDevice(owned_vk_device_, nullptr); owned_vk_device_ = VK_NULL_HANDLE;
diff --git a/gpu/vulkan/vulkan_device_queue.h b/gpu/vulkan/vulkan_device_queue.h index 45467fb..a5b95429 100644 --- a/gpu/vulkan/vulkan_device_queue.h +++ b/gpu/vulkan/vulkan_device_queue.h
@@ -17,6 +17,7 @@ namespace gpu { +class VulkanFenceHelper; class VulkanCommandPool; class VULKAN_EXPORT VulkanDeviceQueue { @@ -72,6 +73,8 @@ std::unique_ptr<gpu::VulkanCommandPool> CreateCommandPool(); + VulkanFenceHelper* GetFenceHelper() const { return cleanup_helper_.get(); } + private: gfx::ExtensionSet enabled_extensions_; VkPhysicalDevice vk_physical_device_ = VK_NULL_HANDLE; @@ -80,6 +83,7 @@ VkQueue vk_queue_ = VK_NULL_HANDLE; uint32_t vk_queue_index_ = 0; const VkInstance vk_instance_; + std::unique_ptr<VulkanFenceHelper> cleanup_helper_; DISALLOW_COPY_AND_ASSIGN(VulkanDeviceQueue); };
diff --git a/gpu/vulkan/vulkan_fence_helper.cc b/gpu/vulkan/vulkan_fence_helper.cc new file mode 100644 index 0000000..a423576 --- /dev/null +++ b/gpu/vulkan/vulkan_fence_helper.cc
@@ -0,0 +1,206 @@ +// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gpu/vulkan/vulkan_fence_helper.h" + +#include "base/bind.h" +#include "gpu/vulkan/vulkan_device_queue.h" +#include "gpu/vulkan/vulkan_function_pointers.h" + +namespace gpu { + +VulkanFenceHelper::FenceHandle::FenceHandle() = default; +VulkanFenceHelper::FenceHandle::FenceHandle(VkFence fence, + uint64_t generation_id) + : fence_(fence), generation_id_(generation_id) {} +VulkanFenceHelper::FenceHandle::FenceHandle(const FenceHandle& other) = default; +VulkanFenceHelper::FenceHandle& VulkanFenceHelper::FenceHandle::operator=( + const FenceHandle& other) = default; + +VulkanFenceHelper::VulkanFenceHelper(VulkanDeviceQueue* device_queue) + : device_queue_(device_queue) {} + +VulkanFenceHelper::~VulkanFenceHelper() { + PerformImmediateCleanup(); +} + +// TODO(ericrk): Handle recycling fences. +VkResult VulkanFenceHelper::GetFence(VkFence* fence) { + VkFenceCreateInfo create_info{ + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + }; + return vkCreateFence(device_queue_->GetVulkanDevice(), &create_info, + nullptr /* pAllocator */, fence); +} + +VulkanFenceHelper::FenceHandle VulkanFenceHelper::EnqueueFence(VkFence fence) { + FenceHandle handle(fence, next_generation_++); + cleanup_tasks_.emplace(handle, std::move(tasks_pending_fence_)); + tasks_pending_fence_ = std::vector<CleanupTask>(); + + return handle; +} + +bool VulkanFenceHelper::Wait(FenceHandle handle, + uint64_t timeout_in_nanoseconds) { + if (HasPassed(handle)) + return true; + + VkResult result = + vkWaitForFences(device_queue_->GetVulkanDevice(), 1, &handle.fence_, true, + timeout_in_nanoseconds); + + // After waiting, we can process cleanup tasks. + ProcessCleanupTasks(); + + return result == VK_SUCCESS; +} + +bool VulkanFenceHelper::HasPassed(FenceHandle handle) { + // Process cleanup tasks which advances our |current_generation_|. + ProcessCleanupTasks(); + + return current_generation_ >= handle.generation_id_; +} + +void VulkanFenceHelper::EnqueueCleanupTaskForSubmittedWork(CleanupTask task) { + tasks_pending_fence_.emplace_back(std::move(task)); +} + +void VulkanFenceHelper::ProcessCleanupTasks() { + VkDevice device = device_queue_->GetVulkanDevice(); + + // Iterate over our pending cleanup fences / tasks, advancing + // |current_generation_| as far as possible. This assumes that fences pass in + // order, which isn't a hard API guarantee, but should be close enough / + // efficient enough for the purpose or processing cleanup tasks. + // + // Also runs any cleanup tasks for generations that have passed. Create a + // temporary vector of tasks to run to avoid reentrancy issues. + std::vector<CleanupTask> tasks_to_run; + while (!cleanup_tasks_.empty()) { + TasksForFence& tasks_for_fence = cleanup_tasks_.front(); + VkResult result = vkGetFenceStatus(device, tasks_for_fence.handle.fence_); + if (result == VK_NOT_READY) + break; + if (result != VK_SUCCESS) { + PerformImmediateCleanup(); + return; + } + current_generation_ = tasks_for_fence.handle.generation_id_; + vkDestroyFence(device, tasks_for_fence.handle.fence_, nullptr); + + tasks_to_run.insert(tasks_to_run.end(), + std::make_move_iterator(tasks_for_fence.tasks.begin()), + std::make_move_iterator(tasks_for_fence.tasks.end())); + cleanup_tasks_.pop(); + } + + for (auto& task : tasks_to_run) + std::move(task).Run(device_queue_, false /* device_lost */); +} + +VulkanFenceHelper::FenceHandle VulkanFenceHelper::GenerateCleanupFence() { + if (tasks_pending_fence_.empty()) + return FenceHandle(); + + VkFence fence = VK_NULL_HANDLE; + VkResult result = GetFence(&fence); + if (result != VK_SUCCESS) { + PerformImmediateCleanup(); + return FenceHandle(); + } + result = vkQueueSubmit(device_queue_->GetVulkanQueue(), 0, nullptr, fence); + if (result != VK_SUCCESS) { + vkDestroyFence(device_queue_->GetVulkanDevice(), fence, nullptr); + PerformImmediateCleanup(); + return FenceHandle(); + } + + return EnqueueFence(fence); +} + +void VulkanFenceHelper::EnqueueSemaphoreCleanupForSubmittedWork( + VkSemaphore semaphore) { + if (semaphore == VK_NULL_HANDLE) + return; + + EnqueueSemaphoresCleanupForSubmittedWork({semaphore}); +} + +void VulkanFenceHelper::EnqueueSemaphoresCleanupForSubmittedWork( + std::vector<VkSemaphore> semaphores) { + if (semaphores.empty()) + return; + + EnqueueCleanupTaskForSubmittedWork(base::BindOnce( + [](std::vector<VkSemaphore> semaphores, VulkanDeviceQueue* device_queue, + bool /* is_lost */) { + for (VkSemaphore semaphore : semaphores) { + vkDestroySemaphore(device_queue->GetVulkanDevice(), semaphore, + nullptr); + } + }, + std::move(semaphores))); +} + +void VulkanFenceHelper::EnqueueImageCleanupForSubmittedWork( + VkImage image, + VkDeviceMemory memory) { + if (image == VK_NULL_HANDLE && memory == VK_NULL_HANDLE) + return; + + EnqueueCleanupTaskForSubmittedWork(base::BindOnce( + [](VkImage image, VkDeviceMemory memory, VulkanDeviceQueue* device_queue, + bool /* is_lost */) { + if (image != VK_NULL_HANDLE) + vkDestroyImage(device_queue->GetVulkanDevice(), image, nullptr); + if (memory != VK_NULL_HANDLE) + vkFreeMemory(device_queue->GetVulkanDevice(), memory, nullptr); + }, + image, memory)); +} + +void VulkanFenceHelper::PerformImmediateCleanup() { + // Rather than caring about fences, just wait for queue idle if possible. + VkResult result = vkQueueWaitIdle(device_queue_->GetVulkanQueue()); + // Wait can only fail for three reasons - device loss, host OOM, device OOM. + // If we hit an OOM, treat this as a crash. There isn't a great way to + // recover from this. + CHECK(result == VK_SUCCESS || result == VK_ERROR_DEVICE_LOST); + bool device_lost = result == VK_ERROR_DEVICE_LOST; + + // Run all cleanup tasks. Create a temporary vector of tasks to run to avoid + // reentrancy issues. + std::vector<CleanupTask> tasks_to_run; + tasks_to_run.insert(tasks_to_run.end(), + std::make_move_iterator(tasks_pending_fence_.begin()), + std::make_move_iterator(tasks_pending_fence_.end())); + tasks_pending_fence_.clear(); + while (!cleanup_tasks_.empty()) { + auto& tasks_for_fence = cleanup_tasks_.front(); + vkDestroyFence(device_queue_->GetVulkanDevice(), + tasks_for_fence.handle.fence_, nullptr); + tasks_to_run.insert(tasks_to_run.end(), + std::make_move_iterator(tasks_for_fence.tasks.begin()), + std::make_move_iterator(tasks_for_fence.tasks.end())); + cleanup_tasks_.pop(); + } + for (auto& task : tasks_to_run) + std::move(task).Run(device_queue_, device_lost); +} + +VulkanFenceHelper::TasksForFence::TasksForFence(FenceHandle handle, + std::vector<CleanupTask> tasks) + : handle(handle), tasks(std::move(tasks)) {} +VulkanFenceHelper::TasksForFence::~TasksForFence() = default; +VulkanFenceHelper::TasksForFence::TasksForFence(TasksForFence&& other) = + default; +VulkanFenceHelper::TasksForFence& +VulkanFenceHelper::TasksForFence::TasksForFence::operator=( + TasksForFence&& other) = default; + +} // namespace gpu
diff --git a/gpu/vulkan/vulkan_fence_helper.h b/gpu/vulkan/vulkan_fence_helper.h new file mode 100644 index 0000000..a4d5827 --- /dev/null +++ b/gpu/vulkan/vulkan_fence_helper.h
@@ -0,0 +1,122 @@ +// Copyright (c) 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GPU_VULKAN_VULKAN_FENCE_HELPER_H_ +#define GPU_VULKAN_VULKAN_FENCE_HELPER_H_ + +#include <vulkan/vulkan.h> + +#include "base/callback.h" +#include "base/containers/queue.h" +#include "base/macros.h" +#include "gpu/vulkan/vulkan_export.h" + +namespace gpu { + +class VulkanDeviceQueue; + +class VULKAN_EXPORT VulkanFenceHelper { + public: + explicit VulkanFenceHelper(VulkanDeviceQueue* device_queue); + ~VulkanFenceHelper(); + + // Class representing a fence registered with this system. Should be treated + // as an opaque handle. + class FenceHandle { + public: + FenceHandle(); + FenceHandle(const FenceHandle& other); + FenceHandle& operator=(const FenceHandle& other); + + bool is_valid() const { return fence_ != VK_NULL_HANDLE; } + + private: + friend class VulkanFenceHelper; + FenceHandle(VkFence fence, uint64_t generation_id); + + VkFence fence_ = VK_NULL_HANDLE; + uint64_t generation_id_ = 0; + }; + + // General fence management functions. Should be used by any Chrome code + // which creates / submits fences. By registering fences with this class and + // checking them via the returned FenceHandle, we are able to leverage these + // same fences for running cleanup tasks. + // + // In typical cases, callers will call GetFence to generate/reuse a fence, + // submit this fence, then call EnqueueFence to register it with this system. + // + // In cases where fences are not being generated by Chrome (or in cases where + // we can't use this helper, such as Skia), consumers should ensure that + // GenerateCleanupFence is called once per frame to allow cleanup tasks to be + // processed. + // + // Creates or recycles a fence. + VkResult GetFence(VkFence* fence); + // Enqueues a fence which must eventually signal (must have been submitted). + // This function takes ownership of the fence. Returns a FenceHandle which + // can be used to wait on this fence / check status. + // Note: This should be called immediately after submitting a fence, as + // calling this will attach cleanup tasks to the fence. If cleanup tasks + // are able to be inserted between fence submission and this call, we can + // end up with incorrect cleanup. + FenceHandle EnqueueFence(VkFence fence); + // Generates and submits a fence. + // TODO(ericrk): We should avoid this in all cases if possible. + FenceHandle GenerateCleanupFence(); + + // Helper functions which allow clients to wait for or check the statusof a + // fence submitted with EnqueueFence. + // + // Waits for the given fence associated with the given generation id to pass. + bool Wait(FenceHandle handle, uint64_t timeout_in_nanoseconds = UINT64_MAX); + // Checks whether the given generation id has passed. + bool HasPassed(FenceHandle handle); + + // Cleanup helpers. Allow callers to enqueue cleanup tasks which will be run + // after the next fence provided by EnqueueFence or GenerateCleanupFence + // passes. Tasks must only be enqueued if all relevant work has already been + // submitted to the queue - it must be the case that the task can immediately + // be run after a vkQueueWaitIdle. To ensure that cleanup tasks run, callers + // should ensure that ProcessCleanupTasks is called once per frame. + using CleanupTask = base::OnceCallback<void(VulkanDeviceQueue* device_queue, + bool device_lost)>; + // Submits a cleanup task for already submitted work. ProcessCleanupTasks + // must be called periodically to ensure these run. + void EnqueueCleanupTaskForSubmittedWork(CleanupTask task); + // Processes CleanupTasks for which a fence has passed. + void ProcessCleanupTasks(); + // Helpers for common types: + void EnqueueSemaphoreCleanupForSubmittedWork(VkSemaphore semaphore); + void EnqueueSemaphoresCleanupForSubmittedWork( + std::vector<VkSemaphore> semaphores); + void EnqueueImageCleanupForSubmittedWork(VkImage image, + VkDeviceMemory memory); + + private: + void PerformImmediateCleanup(); + + VulkanDeviceQueue* const device_queue_; + + std::vector<CleanupTask> tasks_pending_fence_; + uint64_t next_generation_ = 1; + uint64_t current_generation_ = 0; + + struct TasksForFence { + TasksForFence(FenceHandle handle, std::vector<CleanupTask> tasks); + ~TasksForFence(); + TasksForFence(TasksForFence&& other); + TasksForFence& operator=(TasksForFence&& other); + + FenceHandle handle; + std::vector<CleanupTask> tasks; + }; + base::queue<TasksForFence> cleanup_tasks_; + + DISALLOW_COPY_AND_ASSIGN(VulkanFenceHelper); +}; + +} // namespace gpu + +#endif // GPU_VULKAN_VULKAN_FENCE_HELPER_H_
diff --git a/gpu/vulkan/vulkan_fence_helper_unittest.cc b/gpu/vulkan/vulkan_fence_helper_unittest.cc new file mode 100644 index 0000000..2b68af3 --- /dev/null +++ b/gpu/vulkan/vulkan_fence_helper_unittest.cc
@@ -0,0 +1,96 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "testing/gtest/include/gtest/gtest.h" + +#include "base/bind.h" +#include "gpu/vulkan/tests/basic_vulkan_test.h" +#include "gpu/vulkan/vulkan_device_queue.h" +#include "gpu/vulkan/vulkan_fence_helper.h" +#include "gpu/vulkan/vulkan_function_pointers.h" +#include "gpu/vulkan/vulkan_util.h" + +namespace gpu { + +using VulkanFenceHelperTest = BasicVulkanTest; + +TEST_F(VulkanFenceHelperTest, BasicFenceUsage) { + VulkanFenceHelper* fence_helper = GetDeviceQueue()->GetFenceHelper(); + VkFence fence = VK_NULL_HANDLE; + ASSERT_TRUE(VK_SUCCESS == fence_helper->GetFence(&fence)); + ASSERT_TRUE(fence != VK_NULL_HANDLE); + ASSERT_TRUE(VK_SUCCESS == vkQueueSubmit(GetDeviceQueue()->GetVulkanQueue(), 0, + nullptr, fence)); + VulkanFenceHelper::FenceHandle fence_handle = + fence_helper->EnqueueFence(fence); + EXPECT_TRUE(fence_helper->Wait(fence_handle, UINT64_MAX)); + EXPECT_TRUE(fence_helper->HasPassed(fence_handle)); +} + +TEST_F(VulkanFenceHelperTest, TestBasicCallback) { + VulkanFenceHelper* fence_helper = GetDeviceQueue()->GetFenceHelper(); + bool cleanup_run = false; + fence_helper->EnqueueCleanupTaskForSubmittedWork( + base::BindOnce([](bool* cleanup_run, VulkanDeviceQueue* device_queue, + bool is_lost) { *cleanup_run = true; }, + &cleanup_run)); + VulkanFenceHelper::FenceHandle fence_handle = + fence_helper->GenerateCleanupFence(); + EXPECT_TRUE(fence_handle.is_valid()); + fence_helper->Wait(fence_handle, UINT64_MAX); + EXPECT_TRUE(cleanup_run); +} + +TEST_F(VulkanFenceHelperTest, TestBasicCallbackExternalSubmission) { + VulkanFenceHelper* fence_helper = GetDeviceQueue()->GetFenceHelper(); + bool cleanup_run = false; + fence_helper->EnqueueCleanupTaskForSubmittedWork( + base::BindOnce([](bool* cleanup_run, VulkanDeviceQueue* device_queue, + bool is_lost) { *cleanup_run = true; }, + &cleanup_run)); + VkFence fence = VK_NULL_HANDLE; + ASSERT_TRUE(VK_SUCCESS == fence_helper->GetFence(&fence)); + ASSERT_TRUE(fence != VK_NULL_HANDLE); + ASSERT_TRUE(VK_SUCCESS == vkQueueSubmit(GetDeviceQueue()->GetVulkanQueue(), 0, + nullptr, fence)); + VulkanFenceHelper::FenceHandle fence_handle = + fence_helper->EnqueueFence(fence); + EXPECT_TRUE(fence_handle.is_valid()); + fence_helper->Wait(fence_handle, UINT64_MAX); + EXPECT_TRUE(cleanup_run); +} + +TEST_F(VulkanFenceHelperTest, TestMultipleCallbacks) { + VulkanFenceHelper* fence_helper = GetDeviceQueue()->GetFenceHelper(); + uint32_t cleanups_run = 0; + auto increment_cleanups_callback = + [](uint32_t expected_index, uint32_t* cleanups_run, + VulkanDeviceQueue* device_queue, bool is_lost) { + EXPECT_EQ(expected_index, *cleanups_run); + *cleanups_run = *cleanups_run + 1; + }; + + // Enqueue 5 callbacks. + for (int i = 0; i < 5; i++) { + fence_helper->EnqueueCleanupTaskForSubmittedWork( + base::BindOnce(increment_cleanups_callback, i, &cleanups_run)); + } + + // Generate a cleanup fence for the first 5 callbacks. + VulkanFenceHelper::FenceHandle fence_handle = + fence_helper->GenerateCleanupFence(); + + // Enqueue 5 more callbacks. + for (int i = 5; i < 10; i++) { + fence_helper->EnqueueCleanupTaskForSubmittedWork( + base::BindOnce(increment_cleanups_callback, i, &cleanups_run)); + } + + // Generate a cleanup fence for the next 5 callbacks. + fence_handle = fence_helper->GenerateCleanupFence(); + EXPECT_TRUE(fence_handle.is_valid()); + fence_helper->Wait(fence_handle, UINT64_MAX); + EXPECT_EQ(10u, cleanups_run); +} +} // namespace gpu
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc index 5fd86f9..d39dd0e 100644 --- a/headless/test/headless_protocol_browsertest.cc +++ b/headless/test/headless_protocol_browsertest.cc
@@ -211,8 +211,8 @@ HEADLESS_PROTOCOL_TEST(VirtualTimeInterrupt, "emulation/virtual-time-interrupt.js") -// Flaky on Linux. TODO(crbug.com/930717): Re-enable. -#if defined(OS_LINUX) +// Flaky on Linux & Mac. TODO(crbug.com/930717): Re-enable. +#if defined(OS_LINUX) || defined(OS_MACOSX) #define MAYBE_VirtualTimeCrossProcessNavigation \ DISABLED_VirtualTimeCrossProcessNavigation #else
diff --git a/ios/chrome/browser/about_flags.mm b/ios/chrome/browser/about_flags.mm index c956971..491ce8d 100644 --- a/ios/chrome/browser/about_flags.mm +++ b/ios/chrome/browser/about_flags.mm
@@ -581,6 +581,11 @@ {"translate-manual-trigger", flag_descriptions::kTranslateManualTriggerName, flag_descriptions::kTranslateManualTriggerDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(translate::kTranslateMobileManualTrigger)}, + {"omnibox-use-default-search-engine-favicon", + flag_descriptions::kOmniboxUseDefaultSearchEngineFaviconName, + flag_descriptions::kOmniboxUseDefaultSearchEngineFaviconDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE(kOmniboxUseDefaultSearchEngineFavicon)}, }; // Add all switches from experimental flags to |command_line|.
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/ios_chrome_flag_descriptions.cc index 9914a4c5..c89742a 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.cc
@@ -313,6 +313,11 @@ "Switches the omnibox suggestions and omnibox itself to display the new " "design with favicons, new suggestion layout, rich entity support."; +const char kOmniboxUseDefaultSearchEngineFaviconName[] = + "Default search engine favicon in the omnibox"; +const char kOmniboxUseDefaultSearchEngineFaviconDescription[] = + "Shows default search engine favicon in the omnibox"; + const char kNonModalDialogsName[] = "Use non-modal JavaScript dialogs"; const char kNonModalDialogsDescription[] = "Presents JavaScript dialogs non-modally so that the user can change tabs "
diff --git a/ios/chrome/browser/ios_chrome_flag_descriptions.h b/ios/chrome/browser/ios_chrome_flag_descriptions.h index b023572..89b0e27f 100644 --- a/ios/chrome/browser/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/ios_chrome_flag_descriptions.h
@@ -249,6 +249,11 @@ extern const char kNewOmniboxPopupLayoutName[]; extern const char kNewOmniboxPopupLayoutDescription[]; +// Title and description for the flag to show default search engine favicon in +// the omnibox +extern const char kOmniboxUseDefaultSearchEngineFaviconName[]; +extern const char kOmniboxUseDefaultSearchEngineFaviconDescription[]; + // Title and description for the flag to enable non-modal JavaScript dialogs. extern const char kNonModalDialogsName[]; extern const char kNonModalDialogsDescription[];
diff --git a/ios/chrome/browser/signin/authentication_service.h b/ios/chrome/browser/signin/authentication_service.h index 82d0c0d..c17f7fe 100644 --- a/ios/chrome/browser/signin/authentication_service.h +++ b/ios/chrome/browser/signin/authentication_service.h
@@ -22,6 +22,7 @@ } class AuthenticationServiceDelegate; +class AuthenticationServiceFake; @class ChromeIdentity; class PrefService; class SyncSetupService; @@ -115,6 +116,7 @@ private: friend class AuthenticationServiceTest; + friend class AuthenticationServiceFake; // Method called each time the application enters foreground. void OnApplicationEnterForeground();
diff --git a/ios/chrome/browser/signin/authentication_service_fake.mm b/ios/chrome/browser/signin/authentication_service_fake.mm index 604bbc4..f3566eb 100644 --- a/ios/chrome/browser/signin/authentication_service_fake.mm +++ b/ios/chrome/browser/signin/authentication_service_fake.mm
@@ -12,6 +12,7 @@ #import "ios/chrome/browser/signin/authentication_service_factory.h" #include "ios/chrome/browser/signin/identity_manager_factory.h" #include "ios/chrome/browser/sync/profile_sync_service_factory.h" +#include "ios/chrome/browser/sync/sync_setup_service.h" #include "ios/chrome/browser/sync/sync_setup_service_factory.h" #import "ios/public/provider/chrome/browser/signin/chrome_identity.h" @@ -34,6 +35,9 @@ void AuthenticationServiceFake::SignIn(ChromeIdentity* identity, const std::string& hosted_domain) { + // Needs to call PrepareForFirstSyncSetup to behave like + // AuthenticationService. + sync_setup_service_->PrepareForFirstSyncSetup(); authenticated_identity_ = identity; }
diff --git a/ios/chrome/browser/ui/alert_view_controller/BUILD.gn b/ios/chrome/browser/ui/alert_view_controller/BUILD.gn new file mode 100644 index 0000000..772e3bc --- /dev/null +++ b/ios/chrome/browser/ui/alert_view_controller/BUILD.gn
@@ -0,0 +1,13 @@ +# Copyright 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("alert_view_controller") { + sources = [ + "alert_view_controller.h", + "alert_view_controller.mm", + ] + deps = [] + libs = [ "UIKit.framework" ] + configs += [ "//build/config/compiler:enable_arc" ] +}
diff --git a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h new file mode 100644 index 0000000..df06f68 --- /dev/null +++ b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h
@@ -0,0 +1,56 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_UI_ALERT_VIEW_CONTROLLER_ALERT_VIEW_CONTROLLER_H_ +#define IOS_CHROME_BROWSER_UI_ALERT_VIEW_CONTROLLER_ALERT_VIEW_CONTROLLER_H_ + +#import <UIKit/UIKit.h> + +// This class is a replacement for UIAlertAction. +// Current limitations: +// Actions Styles are not supported. +@interface AlertAction : NSObject + +// The title for this action. +@property(nonatomic, readonly) NSString* title; + +// Initializes an action with |title| and |handler|. ++ (instancetype)actionWithTitle:(NSString*)title + handler:(void (^)(AlertAction* action))handler; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +// This class is a replacement for UIAlertController that supports custom +// presentation styles, i.e. change modalPresentationStyle, +// modalTransitionStyle, or transitioningDelegate. The style is more similar to +// the rest of Chromium. Current limitations: +// Action Sheet Style is not supported. +// Text fields are not supported. +@interface AlertViewController : UIViewController + +// The title of the alert, will appear at the top and in bold. +@property(nonatomic, copy) NSString* title; + +// The message of the alert, will appear after the title. +@property(nonatomic, copy) NSString* message; + +// The actions that had been added to this alert. +@property(nonatomic, readonly) NSArray<AlertAction*>* actions; + +// The text fields that had been added to this alert. +@property(nonatomic, readonly) NSArray<UITextField*>* textFields; + +// Adds an action to the alert. +- (void)addAction:(AlertAction*)action; + +// Adds a text field and with an optional block to configure the properties of +// the text field. +- (void)addTextFieldWithConfigurationHandler: + (void (^)(UITextField* textField))configurationHandler; + +@end + +#endif // IOS_CHROME_BROWSER_UI_ALERT_VIEW_CONTROLLER_ALERT_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm new file mode 100644 index 0000000..7ee218c --- /dev/null +++ b/ios/chrome/browser/ui/alert_view_controller/alert_view_controller.mm
@@ -0,0 +1,186 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/ui/alert_view_controller/alert_view_controller.h" + +#import "ios/chrome/common/ui_util/constraints_ui_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace { + +// The alpha of the black chrome behind the alert view. +constexpr CGFloat kBackgroundAlpha = 0.4; + +// Properties of the alert shadow. +constexpr CGFloat kShadowOffsetX = 0; +constexpr CGFloat kShadowOffsetY = 15; +constexpr CGFloat kShadowRadius = 13; +constexpr float kShadowOpacity = 0.12; + +// Properties of the alert view. +constexpr CGFloat kCornerRadius = 12; +constexpr CGFloat kMinimumWidth = 30; +constexpr CGFloat kMinimumHeight = 30; +constexpr CGFloat kMinimumMargin = 4; + +} // namespace + +@interface AlertAction () +@property(nonatomic, readwrite) NSString* title; +@property(nonatomic, copy) void (^handler)(AlertAction* action); +@end + +@implementation AlertAction + ++ (instancetype)actionWithTitle:(NSString*)title + handler:(void (^)(AlertAction* action))handler { + AlertAction* action = [[AlertAction alloc] init]; + action.title = title; + action.handler = handler; + return action; +} + +@end + +@interface AlertViewController () +@property(nonatomic, readwrite) NSArray<AlertAction*>* actions; +@property(nonatomic, readwrite) NSArray<UITextField*>* textFields; + +// This is the view with the shadow, white background and round corners. +// Everything will be added here. +@property(nonatomic, strong) UIView* contentView; + +@end + +@implementation AlertViewController + +@dynamic title; + +- (void)addAction:(AlertAction*)action { + if (!self.actions) { + self.actions = @[ action ]; + return; + } + self.actions = [self.actions arrayByAddingObject:action]; +} + +- (void)addTextFieldWithConfigurationHandler: + (void (^)(UITextField* textField))configurationHandler { + // TODO(crbug.com/951303): Implement support. +} + +- (void)loadView { + [super loadView]; + UIView* grayBackground = [[UIView alloc] init]; + grayBackground.backgroundColor = + [[UIColor blackColor] colorWithAlphaComponent:kBackgroundAlpha]; + grayBackground.translatesAutoresizingMaskIntoConstraints = NO; + [self.view addSubview:grayBackground]; + AddSameConstraints(grayBackground, self.view.safeAreaLayoutGuide); + + self.contentView = [[UIView alloc] init]; + self.contentView.backgroundColor = [UIColor whiteColor]; + self.contentView.layer.cornerRadius = kCornerRadius; + self.contentView.layer.shadowOffset = + CGSizeMake(kShadowOffsetX, kShadowOffsetY); + self.contentView.layer.shadowRadius = kShadowRadius; + self.contentView.layer.shadowOpacity = kShadowOpacity; + self.contentView.translatesAutoresizingMaskIntoConstraints = NO; + [self.view addSubview:self.contentView]; + [NSLayoutConstraint activateConstraints:@[ + // Centering + [self.contentView.centerXAnchor + constraintEqualToAnchor:self.view.centerXAnchor], + [self.contentView.centerYAnchor + constraintEqualToAnchor:self.view.centerYAnchor], + + // Minimum Size + [self.contentView.widthAnchor + constraintGreaterThanOrEqualToConstant:kMinimumWidth], + [self.contentView.heightAnchor + constraintGreaterThanOrEqualToConstant:kMinimumHeight], + + // Maximum Size + [self.contentView.topAnchor + constraintGreaterThanOrEqualToAnchor:self.view.safeAreaLayoutGuide + .topAnchor + constant:kMinimumMargin], + [self.contentView.bottomAnchor + constraintLessThanOrEqualToAnchor:self.view.safeAreaLayoutGuide + .bottomAnchor + constant:-kMinimumMargin], + [self.contentView.trailingAnchor + constraintLessThanOrEqualToAnchor:self.view.safeAreaLayoutGuide + .trailingAnchor + constant:-kMinimumMargin], + [self.contentView.leadingAnchor + constraintGreaterThanOrEqualToAnchor:self.view.safeAreaLayoutGuide + .leadingAnchor + constant:kMinimumMargin], + + ]]; + + UIStackView* stackView = [[UIStackView alloc] init]; + stackView.axis = UILayoutConstraintAxisVertical; + stackView.translatesAutoresizingMaskIntoConstraints = NO; + [self.contentView addSubview:stackView]; + AddSameConstraints(stackView, self.contentView); + + if (self.title.length) { + UILabel* titleLabel = [[UILabel alloc] init]; + titleLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; + titleLabel.textAlignment = NSTextAlignmentCenter; + titleLabel.text = self.title; + titleLabel.translatesAutoresizingMaskIntoConstraints = NO; + [self.contentView addSubview:titleLabel]; + + [NSLayoutConstraint activateConstraints:@[ + [titleLabel.trailingAnchor + constraintEqualToAnchor:self.contentView.trailingAnchor], + [titleLabel.leadingAnchor + constraintEqualToAnchor:self.contentView.leadingAnchor], + ]]; + [stackView addArrangedSubview:titleLabel]; + } + + if (self.message.length) { + UILabel* messageLabel = [[UILabel alloc] init]; + messageLabel.numberOfLines = 0; + messageLabel.font = + [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]; + messageLabel.textAlignment = NSTextAlignmentCenter; + messageLabel.text = self.message; + messageLabel.translatesAutoresizingMaskIntoConstraints = NO; + [self.contentView addSubview:messageLabel]; + + [NSLayoutConstraint activateConstraints:@[ + [messageLabel.trailingAnchor + constraintEqualToAnchor:self.contentView.trailingAnchor], + [messageLabel.leadingAnchor + constraintEqualToAnchor:self.contentView.leadingAnchor], + ]]; + [stackView addArrangedSubview:messageLabel]; + } + + for (AlertAction* action in self.actions) { + UIButton* button = [UIButton buttonWithType:UIButtonTypeSystem]; + [button setTitle:action.title forState:UIControlStateNormal]; + button.contentHorizontalAlignment = + UIControlContentHorizontalAlignmentCenter; + button.translatesAutoresizingMaskIntoConstraints = NO; + [self.contentView addSubview:button]; + + [NSLayoutConstraint activateConstraints:@[ + [button.trailingAnchor + constraintEqualToAnchor:self.contentView.trailingAnchor], + [button.leadingAnchor + constraintEqualToAnchor:self.contentView.leadingAnchor], + ]]; + [stackView addArrangedSubview:button]; + } +}
diff --git a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm index 2fd2356..4684baa 100644 --- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -316,10 +316,11 @@ // |unifiedConsentService| may be null in unit tests. if (unifiedConsentService) unifiedConsentService->SetUrlKeyedAnonymizedDataCollectionEnabled(true); - SyncSetupService* syncSetupService = - SyncSetupServiceFactory::GetForBrowserState(_browserState); - syncSetupService->PrepareForFirstSyncSetup(); if (!_unifiedConsentCoordinator.settingsLinkWasTapped) { + // FirstSetupComplete flag should be only turned on when the user agrees + // to start Sync. + SyncSetupService* syncSetupService = + SyncSetupServiceFactory::GetForBrowserState(_browserState); syncSetupService->SetFirstSetupComplete(); syncSetupService->CommitSyncChanges(); }
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn index ccd9122bf..b4fe1e1 100644 --- a/ios/chrome/browser/ui/browser_view/BUILD.gn +++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -44,6 +44,7 @@ "//ios/chrome/browser/find_in_page", "//ios/chrome/browser/first_run", "//ios/chrome/browser/geolocation:geolocation_internal", + "//ios/chrome/browser/infobars", "//ios/chrome/browser/language", "//ios/chrome/browser/metrics:metrics_internal", "//ios/chrome/browser/net", @@ -65,6 +66,7 @@ "//ios/chrome/browser/ui/activity_services:coordinator", "//ios/chrome/browser/ui/activity_services/requirements", "//ios/chrome/browser/ui/alert_coordinator", + "//ios/chrome/browser/ui/authentication", "//ios/chrome/browser/ui/autofill:autofill", "//ios/chrome/browser/ui/autofill/manual_fill", "//ios/chrome/browser/ui/autofill/manual_fill:manual_fill_ui", @@ -113,6 +115,7 @@ "//ios/chrome/browser/ui/sad_tab:coordinator", "//ios/chrome/browser/ui/settings/sync/utils", "//ios/chrome/browser/ui/side_swipe", + "//ios/chrome/browser/ui/signin_interaction/public", "//ios/chrome/browser/ui/snackbar", "//ios/chrome/browser/ui/static_content", "//ios/chrome/browser/ui/tabs",
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index cd0ccb2a..749ae4d 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -42,6 +42,7 @@ #import "ios/chrome/browser/find_in_page/find_tab_helper.h" #include "ios/chrome/browser/first_run/first_run.h" #import "ios/chrome/browser/geolocation/omnibox_geolocation_controller.h" +#include "ios/chrome/browser/infobars/infobar_manager_impl.h" #import "ios/chrome/browser/language/url_language_histogram_factory.h" #import "ios/chrome/browser/metrics/new_tab_page_uma.h" #import "ios/chrome/browser/metrics/size_class_recorder.h" @@ -77,6 +78,7 @@ #import "ios/chrome/browser/ui/activity_services/activity_service_legacy_coordinator.h" #import "ios/chrome/browser/ui/activity_services/requirements/activity_service_presentation.h" #import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h" +#import "ios/chrome/browser/ui/authentication/re_signin_infobar_delegate.h" #import "ios/chrome/browser/ui/bookmarks/bookmark_interaction_controller.h" #import "ios/chrome/browser/ui/browser_container/browser_container_view_controller.h" #import "ios/chrome/browser/ui/browser_view/browser_view_controller_dependency_factory.h" @@ -128,8 +130,10 @@ #import "ios/chrome/browser/ui/presenters/vertical_animation_container.h" #import "ios/chrome/browser/ui/reading_list/offline_page_native_content.h" #import "ios/chrome/browser/ui/sad_tab/sad_tab_coordinator.h" +#import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h" #import "ios/chrome/browser/ui/side_swipe/side_swipe_controller.h" #import "ios/chrome/browser/ui/side_swipe/swipe_view.h" +#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h" #import "ios/chrome/browser/ui/static_content/static_html_native_content.h" #import "ios/chrome/browser/ui/tabs/background_tab_animation_view.h" #import "ios/chrome/browser/ui/tabs/foreground_tab_animation_view.h" @@ -378,6 +382,7 @@ PasswordControllerDelegate, PreloadControllerDelegate, SideSwipeControllerDelegate, + SigninPresenter, SnapshotGeneratorDelegate, TabModelObserver, TabStripPresentation, @@ -2031,7 +2036,7 @@ self.infobarContainerCoordinator = [[InfobarContainerCoordinator alloc] initWithBaseViewController:self browserState:_browserState - tabModel:self.tabModel]; + webStateList:self.tabModel.webStateList]; self.infobarContainerCoordinator.commandDispatcher = self.dispatcher; self.infobarContainerCoordinator.positioner = self; self.infobarContainerCoordinator.syncPresenter = self; @@ -4392,6 +4397,27 @@ DCHECK(tab); _temporaryNativeController = nil; + // When adding new tabs, check what kind of reminder infobar should + // be added to the new tab. Try to add only one of them. + // This check is done when a new tab is added either through the Tools Menu + // "New Tab", through a long press on the Tab Switcher button "New Tab", and + // through creating a New Tab from the Tab Switcher. This method is called + // after a new tab has added and finished initial navigation. If this is added + // earlier, the initial navigation may end up clearing the infobar(s) that are + // just added. + web::WebState* webState = tab.webState; + DCHECK(webState); + + infobars::InfoBarManager* infoBarManager = + InfoBarManagerImpl::FromWebState(webState); + NSString* tabID = TabIdTabHelper::FromWebState(webState)->tab_id(); + [[UpgradeCenter sharedInstance] addInfoBarToManager:infoBarManager + forTabId:tabID]; + if (!ReSignInInfoBarDelegate::Create(self.browserState, tab, + self /* id<SigninPresenter> */)) { + DisplaySyncErrors(self.browserState, tab, self /* id<SyncPresenter> */); + } + // The rest of this function initiates the new tab animation, which is // phone-specific. Call the foreground tab added completion block; for // iPhones, this will get executed after the animation has finished. @@ -4841,6 +4867,12 @@ } } +#pragma mark - SigninPresenter + +- (void)showSignin:(ShowSigninCommand*)command { + [self.dispatcher showSignin:command baseViewController:self]; +} + #pragma mark - SyncPresenter (Public) - (void)showReauthenticateSignin {
diff --git a/ios/chrome/browser/ui/infobars/BUILD.gn b/ios/chrome/browser/ui/infobars/BUILD.gn index 2c41579..ea440e7e 100644 --- a/ios/chrome/browser/ui/infobars/BUILD.gn +++ b/ios/chrome/browser/ui/infobars/BUILD.gn
@@ -18,15 +18,10 @@ "//ios/chrome/browser", "//ios/chrome/browser/infobars", "//ios/chrome/browser/infobars:badge", - "//ios/chrome/browser/tabs", - "//ios/chrome/browser/ui/authentication", "//ios/chrome/browser/ui/commands", "//ios/chrome/browser/ui/coordinators:chrome_coordinators", "//ios/chrome/browser/ui/fullscreen", "//ios/chrome/browser/ui/infobars/coordinators", - "//ios/chrome/browser/ui/settings/sync/utils", - "//ios/chrome/browser/ui/signin_interaction/public", - "//ios/chrome/browser/ui/translate", "//ios/chrome/browser/upgrade", "//ios/chrome/browser/web:tab_id_tab_helper", "//ios/chrome/browser/web_state_list",
diff --git a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.h b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.h index 2a06c6e..6d01424 100644 --- a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.h +++ b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.h
@@ -12,18 +12,19 @@ } @class CommandDispatcher; -@class TabModel; @protocol InfobarPositioner; @protocol SyncPresenter; +class WebStateList; // Coordinator that owns and manages an InfobarContainer. @interface InfobarContainerCoordinator : ChromeCoordinator -// TODO(crbug.com/892376): Stop passing TabModel and use WebStateList instead. +// TODO(crbug.com/892376): Pass a Browser object instead of BrowserState and +// WebStateList once BVC has a Browser pointer. - (instancetype)initWithBaseViewController:(UIViewController*)viewController browserState: (ios::ChromeBrowserState*)browserState - tabModel:(TabModel*)tabModel + webStateList:(WebStateList*)webStateList NS_DESIGNATED_INITIALIZER; ;
diff --git a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm index efdd1b3..8b88fc3 100644 --- a/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm +++ b/ios/chrome/browser/ui/infobars/infobar_container_coordinator.mm
@@ -17,7 +17,6 @@ #import "ios/chrome/browser/ui/infobars/infobar_feature.h" #import "ios/chrome/browser/ui/infobars/infobar_positioner.h" #include "ios/chrome/browser/ui/infobars/legacy_infobar_container_view_controller.h" -#import "ios/chrome/browser/ui/signin_interaction/public/signin_presenter.h" #include "ios/chrome/browser/upgrade/upgrade_center.h" #if !defined(__has_feature) || !__has_feature(objc_arc) @@ -30,11 +29,9 @@ const double kBannerPresentationDurationInSeconds = 6.0; } // namespace -@interface InfobarContainerCoordinator () < - InfobarContainerConsumer, - SigninPresenter> +@interface InfobarContainerCoordinator () <InfobarContainerConsumer> -@property(nonatomic, assign) TabModel* tabModel; +@property(nonatomic, assign) WebStateList* webStateList; // ViewController of the Infobar currently being presented, can be nil. @property(nonatomic, weak) UIViewController* infobarViewController; @@ -53,11 +50,11 @@ - (instancetype)initWithBaseViewController:(UIViewController*)viewController browserState: (ios::ChromeBrowserState*)browserState - tabModel:(TabModel*)tabModel { + webStateList:(WebStateList*)webStateList { self = [super initWithBaseViewController:viewController browserState:browserState]; if (self) { - _tabModel = tabModel; + _webStateList = webStateList; } return self; } @@ -85,11 +82,9 @@ self.mediator = [[InfobarContainerMediator alloc] initWithConsumer:self legacyConsumer:self.legacyContainerViewController - browserState:self.browserState - tabModel:self.tabModel]; + webStateList:self.webStateList]; self.mediator.syncPresenter = self.syncPresenter; - self.mediator.signinPresenter = self; [[UpgradeCenter sharedInstance] registerClient:self.mediator withDispatcher:self.dispatcher]; @@ -202,11 +197,4 @@ [infobarCoordinator presentInfobarModal]; } -#pragma mark - SigninPresenter - -- (void)showSignin:(ShowSigninCommand*)command { - [self.dispatcher showSignin:command - baseViewController:self.baseViewController]; -} - @end
diff --git a/ios/chrome/browser/ui/infobars/infobar_container_mediator.h b/ios/chrome/browser/ui/infobars/infobar_container_mediator.h index 1f37b9f..e5a1882 100644 --- a/ios/chrome/browser/ui/infobars/infobar_container_mediator.h +++ b/ios/chrome/browser/ui/infobars/infobar_container_mediator.h
@@ -10,25 +10,21 @@ #import "ios/chrome/browser/ui/infobars/infobar_badge_ui_delegate.h" #include "ios/chrome/browser/upgrade/upgrade_center.h" -namespace ios { -class ChromeBrowserState; -} - @protocol InfobarContainerConsumer; @protocol SigninPresenter; @protocol SyncPresenter; -@class TabModel; +class WebStateList; @interface InfobarContainerMediator : NSObject <InfobarBadgeUIDelegate, UpgradeCenterClient> // Designated initializer. None of the parameters are retained. -// TODO(crbug.com/927064): BrowserState shouldn't be passed to the mediator, the -// legacy consumer won't be needed once legacyInfobars are no longer supported. +// TODO(crbug.com/927064): The legacy consumer won't be needed once +// legacyInfobars are no longer supported. - (instancetype)initWithConsumer:(id<InfobarContainerConsumer>)consumer legacyConsumer:(id<InfobarContainerConsumer>)legacyConsumer - browserState:(ios::ChromeBrowserState*)browserState - tabModel:(TabModel*)tabModel NS_DESIGNATED_INITIALIZER; + webStateList:(WebStateList*)webStateList + NS_DESIGNATED_INITIALIZER; ; - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/ui/infobars/infobar_container_mediator.mm b/ios/chrome/browser/ui/infobars/infobar_container_mediator.mm index 8002bdbe..9eb45ea6 100644 --- a/ios/chrome/browser/ui/infobars/infobar_container_mediator.mm +++ b/ios/chrome/browser/ui/infobars/infobar_container_mediator.mm
@@ -7,13 +7,8 @@ #include "ios/chrome/browser/infobars/infobar_badge_tab_helper.h" #include "ios/chrome/browser/infobars/infobar_container_ios.h" #include "ios/chrome/browser/infobars/infobar_manager_impl.h" -#import "ios/chrome/browser/tabs/tab.h" -#import "ios/chrome/browser/tabs/tab_model.h" -#import "ios/chrome/browser/tabs/tab_model_observer.h" -#import "ios/chrome/browser/ui/authentication/re_signin_infobar_delegate.h" #import "ios/chrome/browser/ui/infobars/infobar_container_consumer.h" #import "ios/chrome/browser/ui/infobars/infobar_feature.h" -#import "ios/chrome/browser/ui/settings/sync/utils/sync_util.h" #include "ios/chrome/browser/upgrade/upgrade_center.h" #import "ios/chrome/browser/web/tab_id_tab_helper.h" #import "ios/chrome/browser/web_state_list/web_state_list.h" @@ -23,20 +18,14 @@ #error "This file requires ARC support." #endif -@interface InfobarContainerMediator ()<TabModelObserver, - WebStateListObserving> { +@interface InfobarContainerMediator () <WebStateListObserving> { // A single infobar container handles all infobars in all tabs. It keeps - // track of infobars for current tab (accessed via infobar helper of - // the current tab). + // track of infobars for current Webstate. std::unique_ptr<InfoBarContainerIOS> _infoBarContainer; // Bridge class to deliver webStateList notifications. std::unique_ptr<WebStateListObserverBridge> _webStateListObserver; } -// The mediator's BrowserState. -@property(nonatomic, assign, readonly) ios::ChromeBrowserState* browserState; -// The mediator's TabModel. -@property(nonatomic, weak, readonly) TabModel* tabModel; // The WebStateList that this mediator listens for any changes on its Webstates. @property(nonatomic, assign) WebStateList* webStateList; @@ -48,66 +37,30 @@ - (instancetype)initWithConsumer:(id<InfobarContainerConsumer>)consumer legacyConsumer:(id<InfobarContainerConsumer>)legacyConsumer - browserState:(ios::ChromeBrowserState*)browserState - tabModel:(TabModel*)tabModel { + webStateList:(WebStateList*)webStateList { self = [super init]; if (self) { - _browserState = browserState; - _tabModel = tabModel; - _webStateList = _tabModel.webStateList; + _webStateList = webStateList; _infoBarContainer.reset(new InfoBarContainerIOS(consumer, legacyConsumer)); infobars::InfoBarManager* infoBarManager = nullptr; - if (_tabModel.currentTab) { - DCHECK(_tabModel.currentTab.webState); + if (_webStateList->GetActiveWebState()) { infoBarManager = - InfoBarManagerImpl::FromWebState(_tabModel.currentTab.webState); + InfoBarManagerImpl::FromWebState(_webStateList->GetActiveWebState()); } _infoBarContainer->ChangeInfoBarManager(infoBarManager); _webStateListObserver = std::make_unique<WebStateListObserverBridge>(self); _webStateList->AddObserver(_webStateListObserver.get()); - [_tabModel addObserver:self]; } return self; } - (void)dealloc { - [_tabModel removeObserver:self]; _webStateList->RemoveObserver(_webStateListObserver.get()); _webStateListObserver.reset(); } -#pragma mark - TabModelObserver - -// TODO(crbug.com/892376): Stop observing TabModel and use WebStateList instead. -- (void)tabModel:(TabModel*)model - newTabWillOpen:(Tab*)tab - inBackground:(BOOL)background { - // When adding new tabs, check what kind of reminder infobar should - // be added to the new tab. Try to add only one of them. - // This check is done when a new tab is added either through the Tools Menu - // "New Tab", through a long press on the Tab Switcher button "New Tab", and - // through creating a New Tab from the Tab Switcher. This method is called - // after a new tab has added and finished initial navigation. If this is added - // earlier, the initial navigation may end up clearing the infobar(s) that are - // just added. - web::WebState* webState = tab.webState; - DCHECK(webState); - - infobars::InfoBarManager* infoBarManager = - InfoBarManagerImpl::FromWebState(webState); - NSString* tabID = TabIdTabHelper::FromWebState(webState)->tab_id(); - [[UpgradeCenter sharedInstance] addInfoBarToManager:infoBarManager - forTabId:tabID]; - if (!ReSignInInfoBarDelegate::Create( - self.browserState, tab, - self.signinPresenter /* id<SigninPresenter> */)) { - DisplaySyncErrors(self.browserState, tab, - self.syncPresenter /* id<SyncPresenter> */); - } -} - #pragma mark - WebStateListObserver - (void)webStateList:(WebStateList*)webStateList @@ -184,11 +137,10 @@ #pragma mark - UpgradeCenterClient - (void)showUpgrade:(UpgradeCenter*)center { - DCHECK(self.tabModel.webStateList); + DCHECK(self.webStateList); // Add an infobar on all the open tabs. - WebStateList* webStateList = self.tabModel.webStateList; - for (int index = 0; index < webStateList->count(); ++index) { - web::WebState* webState = webStateList->GetWebStateAt(index); + for (int index = 0; index < self.webStateList->count(); ++index) { + web::WebState* webState = self.webStateList->GetWebStateAt(index); NSString* tabID = TabIdTabHelper::FromWebState(webState)->tab_id(); infobars::InfoBarManager* infoBarManager = InfoBarManagerImpl::FromWebState(webState);
diff --git a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h index 1d3f1d8..73f2a0a 100644 --- a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h +++ b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.h
@@ -14,9 +14,11 @@ @protocol AdvancedSigninSettingsCoordinatorDelegate <NSObject> // Called when the user closes AdvancedSigninSettingsCoordinator. +// |signedin|, YES if the view is confirmed or aborted, and NO if the view is +// canceled. - (void)advancedSigninSettingsCoordinatorDidClose: (AdvancedSigninSettingsCoordinator*)coordinator - success:(BOOL)success; + signedin:(BOOL)signedin; @end @@ -30,10 +32,11 @@ // Global dispatcher. @property(nonatomic, weak) id<ApplicationCommands> dispatcher; -// Cancels the coordinator, and calls the delegate. This method does nothing if -// called twice. +// Aborts the sign-in flow, and calls the delegate. Aborting the Advanced +// sync settings doesn't sign out the user. The sync is left unsetup and doesn't +// start. This method does nothing if called twice. // |dismiss|, dismisses the view controller if YES. -- (void)cancelWithDismiss:(BOOL)dismiss; +- (void)abortWithDismiss:(BOOL)dismiss; @end
diff --git a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm index c1cdaac..7ccbf7c7 100644 --- a/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm +++ b/ios/chrome/browser/ui/settings/google_services/advanced_signin_settings_coordinator.mm
@@ -27,6 +27,16 @@ using l10n_util::GetNSString; +// Advanced sign-in settings result. +typedef NS_ENUM(NSInteger, AdvancedSigninSettingsCoordinatorResult) { + // The user confirmed the advanced sync settings. + AdvancedSyncSettingsCoordinatorResultConfirm, + // The user canceled the advanced sync settings. + AdvancedSigninSettingsCoordinatorResultCancel, + // Chrome aborted the advanced sync settings. + AdvancedSigninSettingsCoordinatorResultInterrupted, +}; + @interface AdvancedSigninSettingsCoordinator () // Google services settings coordinator. @@ -68,41 +78,61 @@ completion:nil]; } -- (void)cancelWithDismiss:(BOOL)dismiss { +- (void)abortWithDismiss:(BOOL)dismiss { if (!self.advancedSigninSettingsNavigationController) { return; } DCHECK_EQ(self.advancedSigninSettingsNavigationController, self.baseViewController.presentedViewController); - void (^completion)(void) = ^{ - [self finishedWithSuccess:NO]; - }; if (dismiss) { - [self.baseViewController dismissViewControllerAnimated:YES - completion:completion]; + [self dismissViewControllerAndFinishWithResult: + AdvancedSigninSettingsCoordinatorResultInterrupted]; } else { - completion(); + [self + finishedWithResult:AdvancedSigninSettingsCoordinatorResultInterrupted]; } } #pragma mark - Private // Called once the view controller has been removed (if needed). -// |success|, YES if the user accepts to sync. -- (void)finishedWithSuccess:(BOOL)success { +// |result|, YES if the user accepts to sync. +- (void)finishedWithResult:(AdvancedSigninSettingsCoordinatorResult)result { DCHECK(self.advancedSigninSettingsNavigationController); - if (success) { - SyncSetupServiceFactory::GetForBrowserState(self.browserState) - ->SetFirstSetupComplete(); - } else { - AuthenticationServiceFactory::GetForBrowserState(self.browserState) - ->SignOut(signin_metrics::ABORT_SIGNIN, nil); + SyncSetupService* syncSetupService = + SyncSetupServiceFactory::GetForBrowserState(self.browserState); + switch (result) { + case AdvancedSyncSettingsCoordinatorResultConfirm: + base::RecordAction( + base::UserMetricsAction("Signin_Signin_ConfirmAdvancedSyncSettings")); + if (syncSetupService->IsSyncEnabled()) { + // FirstSetupComplete flag should be only turned on when the user agrees + // to start Sync. + syncSetupService->PrepareForFirstSyncSetup(); + syncSetupService->SetFirstSetupComplete(); + } + break; + case AdvancedSigninSettingsCoordinatorResultCancel: + base::RecordAction(base::UserMetricsAction( + "Signin_Signin_ConfirmCancelAdvancedSyncSettings")); + syncSetupService->CommitSyncChanges(); + AuthenticationServiceFactory::GetForBrowserState(self.browserState) + ->SignOut(signin_metrics::ABORT_SIGNIN, nil); + break; + case AdvancedSigninSettingsCoordinatorResultInterrupted: + base::RecordAction( + base::UserMetricsAction("Signin_Signin_AbortAdvancedSyncSettings")); + break; } [self.googleServicesSettingsCoordinator stop]; self.googleServicesSettingsCoordinator.delegate = nil; self.googleServicesSettingsCoordinator = nil; + DCHECK(!syncSetupService->HasUncommittedChanges()) + << "-[GoogleServicesSettingsCoordinator stop] should commit sync " + "changes."; + BOOL signedin = result != AdvancedSigninSettingsCoordinatorResultCancel; [self.delegate advancedSigninSettingsCoordinatorDidClose:self - success:success]; + signedin:signedin]; self.advancedSigninSettingsNavigationController = nil; } @@ -163,15 +193,10 @@ // sync preferences chosen by the user, starts the sync, close the completion // callback and closes the advanced sign-in settings. - (void)navigationConfirmButtonAction { - base::RecordAction( - base::UserMetricsAction("Signin_Signin_ConfirmAdvancedSyncSettings")); DCHECK_EQ(self.advancedSigninSettingsNavigationController, self.baseViewController.presentedViewController); - void (^completion)(void) = ^{ - [self finishedWithSuccess:YES]; - }; - [self.baseViewController dismissViewControllerAnimated:YES - completion:completion]; + [self dismissViewControllerAndFinishWithResult: + AdvancedSyncSettingsCoordinatorResultConfirm]; } // Called when a button of |self.cancelConfirmationAlertCoordinator| is pressed. @@ -180,13 +205,25 @@ [self.cancelConfirmationAlertCoordinator stop]; self.cancelConfirmationAlertCoordinator = nil; if (cancelSync) { - base::RecordAction(base::UserMetricsAction( - "Signin_Signin_ConfirmCancelAdvancedSyncSettings")); - [self cancelWithDismiss:YES]; + [self dismissViewControllerAndFinishWithResult: + AdvancedSigninSettingsCoordinatorResultCancel]; } else { base::RecordAction(base::UserMetricsAction( "Signin_Signin_CancelCancelAdvancedSyncSettings")); } } +// Dismisses the current view controller with animation, and calls +// -[self finishedWithResult:] with |result|. +- (void)dismissViewControllerAndFinishWithResult: + (AdvancedSigninSettingsCoordinatorResult)result { + DCHECK_EQ(self.advancedSigninSettingsNavigationController, + self.baseViewController.presentedViewController); + [self.baseViewController + dismissViewControllerAnimated:YES + completion:^{ + [self finishedWithResult:result]; + }]; +} + @end
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm index add9152..fb53eed 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_coordinator.mm
@@ -113,11 +113,14 @@ SyncSetupService* syncSetupService = SyncSetupServiceFactory::GetForBrowserState(self.browserState); if (self.mode == GoogleServicesSettingsModeSettings && - !syncSetupService->IsFirstSetupComplete()) { - // Sign-in workflow has been interrupted. FirstSetupComplete flag needs to - // be turned on. - syncSetupService->PrepareForFirstSyncSetup(); - syncSetupService->SetFirstSetupComplete(); + !syncSetupService->IsFirstSetupComplete() && + syncSetupService->IsSyncEnabled()) { + // Google services settings has been opened in the settings mode, and + // FirstSetupComplete is off, this means the user never accepted or + // refused to turn Sync on. + // When closing, FirstSetupComplete is still off, so the user doesn't + // want to turn Sync on. To acknowledge, Sync has to be turned off. + syncSetupService->SetSyncEnabled(false); } syncSetupService->CommitSyncChanges(); }
diff --git a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm index 99d6303..f9279e3 100644 --- a/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm +++ b/ios/chrome/browser/ui/settings/google_services/google_services_settings_mediator.mm
@@ -96,6 +96,8 @@ // Returns YES if the user is authenticated. @property(nonatomic, assign, readonly) BOOL isAuthenticated; +// Returns YES if Sync setup is in progress. +@property(nonatomic, assign, readonly) BOOL isSyncSetupInProgress; // Returns YES if the user cannot turn on sync for enterprise policy reasons. @property(nonatomic, assign, readonly) BOOL isSyncDisabledByAdministrator; // Returns YES if the user is allowed to turn on sync (even if there is a sync @@ -239,10 +241,11 @@ self.accountItem.image = [self.resizedAvatarCache resizedAvatarForIdentity:identity]; self.accountItem.text = identity.userFullName; - if (self.syncSetupService->HasFinishedInitialSetup()) { - self.accountItem.detailText = identity.userEmail; - } else { + if (self.mode == GoogleServicesSettingsModeAdvancedSigninSettings || + self.isSyncSetupInProgress) { self.accountItem.detailText = GetNSString(IDS_IOS_SYNC_SETUP_IN_PROGRESS); + } else { + self.accountItem.detailText = identity.userEmail; } } @@ -408,21 +411,28 @@ - (BOOL)updateSyncChromeDataItem { TableViewModel* model = self.consumer.tableViewModel; if (self.isSyncCanBeAvailable) { - if (self.syncChromeDataSwitchItem) { - BOOL needsUpdate = self.syncChromeDataSwitchItem.on != - self.syncSetupService->IsSyncingAllDataTypes(); - self.syncChromeDataSwitchItem.on = self.syncSetupService->IsSyncEnabled(); - return needsUpdate; + BOOL needsUpdate = NO; + if (!self.syncChromeDataSwitchItem) { + self.syncChromeDataSwitchItem = + [self switchItemWithItemType:SyncChromeDataItemType + textStringID: + IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_CHROME_DATA + detailStringID:0 + dataType:0]; + [model addItem:self.syncChromeDataSwitchItem + toSectionWithIdentifier:SyncSectionIdentifier]; + needsUpdate = YES; } - self.syncChromeDataSwitchItem = [self - switchItemWithItemType:SyncChromeDataItemType - textStringID:IDS_IOS_GOOGLE_SERVICES_SETTINGS_SYNC_CHROME_DATA - detailStringID:0 - dataType:0]; - self.syncChromeDataSwitchItem.on = self.syncSetupService->IsSyncEnabled(); - [model addItem:self.syncChromeDataSwitchItem - toSectionWithIdentifier:SyncSectionIdentifier]; - return YES; + // Sync is not active when |syncSetupService->IsFirstSetupComplete()| is + // false. Show sync being turned off in the UI in this cases. + BOOL isSyncEnabled = + self.syncSetupService->IsSyncEnabled() && + (self.syncSetupService->IsFirstSetupComplete() || + self.mode == GoogleServicesSettingsModeAdvancedSigninSettings); + needsUpdate = + needsUpdate || isSyncEnabled != self.syncChromeDataSwitchItem.on; + self.syncChromeDataSwitchItem.on = isSyncEnabled; + return needsUpdate; } if (!self.syncChromeDataSwitchItem) return NO; @@ -481,6 +491,13 @@ return self.authService->IsAuthenticated(); } +- (BOOL)isSyncSetupInProgress { + return self.isAuthenticated && + (self.mode == GoogleServicesSettingsModeAdvancedSigninSettings || + (self.syncSetupService->IsSyncEnabled() && + !self.syncSetupService->IsFirstSetupComplete())); +} + - (BOOL)isSyncDisabledByAdministrator { return (self.syncService->GetDisableReasons() & syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY) != 0; @@ -615,6 +632,17 @@ break; case SyncChromeDataItemType: self.syncSetupService->SetSyncEnabled(value); + if (self.mode == GoogleServicesSettingsModeSettings && + !self.syncSetupService->IsFirstSetupComplete()) { + // FirstSetupComplete flag needs to be turned on when the user enables + // sync for the first time. This flag should not be turned on in + // GoogleServicesSettingsModeAdvancedSigninSettings. In that mode, + // this flag should be turned on only when the user clicks the confirm + // button. + CHECK(value); + self.syncSetupService->PrepareForFirstSyncSetup(); + self.syncSetupService->SetFirstSetupComplete(); + } break; case IdentityItemType: case SignInItemType:
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.mm index 995f8e34..4bf6dc6 100644 --- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.mm +++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_coordinator.mm
@@ -118,26 +118,26 @@ - (void)cancel { [self.controller cancel]; - [self.advancedSigninSettingsCoordinator cancelWithDismiss:NO]; + [self.advancedSigninSettingsCoordinator abortWithDismiss:NO]; } - (void)cancelAndDismiss { [self.controller cancelAndDismiss]; - [self.advancedSigninSettingsCoordinator cancelWithDismiss:YES]; + [self.advancedSigninSettingsCoordinator abortWithDismiss:YES]; } - (BOOL)isActive { return self.controller != nil; } -#pragma mark - AdvancedSigninSettingsCoordinatorDelegates +#pragma mark - AdvancedSigninSettingsCoordinatorDelegate - (void)advancedSigninSettingsCoordinatorDidClose: (AdvancedSigninSettingsCoordinator*)coordinator - success:(BOOL)success { + signedin:(BOOL)signedin { DCHECK_EQ(self.advancedSigninSettingsCoordinator, coordinator); self.advancedSigninSettingsCoordinator = nil; - [self signinDoneWithSuccess:success]; + [self signinDoneWithSuccess:signedin]; } #pragma mark - SigninInteractionPresenting
diff --git a/ios/chrome/browser/ui/ui_feature_flags.cc b/ios/chrome/browser/ui/ui_feature_flags.cc index 5cda4d9..66eff5f 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.cc +++ b/ios/chrome/browser/ui/ui_feature_flags.cc
@@ -34,3 +34,6 @@ const base::Feature kNewOmniboxPopupLayout{"NewOmniboxPopupLayout", base::FEATURE_DISABLED_BY_DEFAULT}; + +const base::Feature kOmniboxUseDefaultSearchEngineFavicon{ + "OmniboxUseDefaultSearchEngineFavicon", base::FEATURE_ENABLED_BY_DEFAULT};
diff --git a/ios/chrome/browser/ui/ui_feature_flags.h b/ios/chrome/browser/ui/ui_feature_flags.h index 883336831..f4a0128 100644 --- a/ios/chrome/browser/ui/ui_feature_flags.h +++ b/ios/chrome/browser/ui/ui_feature_flags.h
@@ -39,4 +39,8 @@ // favicon in the omnibox, rich entities support, new layout. extern const base::Feature kNewOmniboxPopupLayout; +// Feature to display the omnibox with default search engine favicon +// in the omnibox. +extern const base::Feature kOmniboxUseDefaultSearchEngineFavicon; + #endif // IOS_CHROME_BROWSER_UI_UI_FEATURE_FLAGS_H_
diff --git a/media/DEPS b/media/DEPS index 671a0df..e5e9d61 100644 --- a/media/DEPS +++ b/media/DEPS
@@ -19,6 +19,7 @@ "+third_party/libyuv", "+third_party/opus", "+third_party/skia", + "+ui/base/mpris/buildflags", "+ui/display", "+ui/events", "+ui/gfx",
diff --git a/media/base/BUILD.gn b/media/base/BUILD.gn index f873b15..fcc6ab6c 100644 --- a/media/base/BUILD.gn +++ b/media/base/BUILD.gn
@@ -314,6 +314,7 @@ "//skia", "//third_party/libyuv", "//third_party/widevine/cdm:headers", + "//ui/base/mpris/buildflags", "//ui/display:display", "//ui/events:events_base", "//url:url",
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 31c4054..28f4f38 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -6,6 +6,7 @@ #include "base/command_line.h" #include "build/build_config.h" +#include "ui/base/mpris/buildflags/buildflags.h" namespace switches { @@ -335,7 +336,8 @@ // Enables handling of hardware media keys for controlling media. const base::Feature kHardwareMediaKeyHandling{ "HardwareMediaKeyHandling", -#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_MACOSX) +#if defined(OS_CHROMEOS) || defined(OS_WIN) || defined(OS_MACOSX) || \ + BUILDFLAG(USE_MPRIS) base::FEATURE_ENABLED_BY_DEFAULT #else base::FEATURE_DISABLED_BY_DEFAULT
diff --git a/mojo/core/channel_mac.cc b/mojo/core/channel_mac.cc index 450bd17e..0ea384d 100644 --- a/mojo/core/channel_mac.cc +++ b/mojo/core/channel_mac.cc
@@ -17,8 +17,6 @@ #include "base/containers/buffer_iterator.h" #include "base/containers/circular_deque.h" #include "base/containers/span.h" -#include "base/debug/crash_logging.h" -#include "base/debug/dump_without_crashing.h" #include "base/logging.h" #include "base/mac/mach_logging.h" #include "base/mac/scoped_mach_msg_destroy.h" @@ -117,11 +115,6 @@ size_t extra_header_size, std::vector<PlatformHandle>* handles, bool* deferred) override { - // TODO(https://crbug.com/946372): Remove when fixed. - static base::debug::CrashKeyString* error_crash_key = - base::debug::AllocateCrashKeyString("channel-mac-handles-error", - base::debug::CrashKeySize::Size64); - // Validate the incoming handles. If validation fails, ensure they are // destroyed. std::vector<PlatformHandle> incoming_handles; @@ -130,14 +123,12 @@ if (extra_header_size < sizeof(Message::MachPortsExtraHeader) + (incoming_handles.size() * sizeof(Message::MachPortsEntry))) { - base::debug::SetCrashKeyString(error_crash_key, "extra_header_size"); return false; } const auto* mach_ports_header = reinterpret_cast<const Message::MachPortsExtraHeader*>(extra_header); if (mach_ports_header->num_ports != incoming_handles.size()) { - base::debug::SetCrashKeyString(error_crash_key, "num_ports mismatch"); return false; } @@ -145,29 +136,19 @@ auto type = static_cast<PlatformHandle::Type>( mach_ports_header->entries[i].mach_entry.type); if (type == PlatformHandle::Type::kNone) { - base::debug::SetCrashKeyString( - error_crash_key, base::StringPrintf("kNone handle #%d", i)); return false; } else if (type == PlatformHandle::Type::kFd && incoming_handles[i].is_mach_send()) { int fd = fileport_makefd(incoming_handles[i].GetMachSendRight().get()); if (fd < 0) { - base::debug::SetCrashKeyString( - error_crash_key, - base::StringPrintf("fileport_makefd %d -%d #%d", fd, errno, i)); return false; } incoming_handles[i] = PlatformHandle(base::ScopedFD(fd)); } else if (type != incoming_handles[i].type()) { - base::debug::SetCrashKeyString( - error_crash_key, - base::StringPrintf("handle mismatch %d != -%d #%d", type, - incoming_handles[i].type(), i)); return false; } } - base::debug::ClearCrashKeyString(error_crash_key); *handles = std::move(incoming_handles); return true; } @@ -646,12 +627,6 @@ size_t ignored; DispatchResult result = TryDispatchMessage(payload, &ignored); if (result != DispatchResult::kOK) { - // TODO(https://crbug.com/946372): Remove when fixed. - static auto* error_crash_key = base::debug::AllocateCrashKeyString( - "channel-mac-try-dispatch", base::debug::CrashKeySize::Size32); - base::debug::SetCrashKeyString(error_crash_key, - base::StringPrintf("%d", result)); - base::debug::DumpWithoutCrashing(); OnError(Error::kReceivedMalformedData); return; }
diff --git a/mojo/core/spliced_message_pipe_unittest.cc b/mojo/core/spliced_message_pipe_unittest.cc index 3185d5e0..575dd03 100644 --- a/mojo/core/spliced_message_pipe_unittest.cc +++ b/mojo/core/spliced_message_pipe_unittest.cc
@@ -267,7 +267,14 @@ // No multi-process support for iOS. #if !defined(OS_IOS) -TEST_F(SplicedMessagePipeTest, Multiprocess) { +#if defined(OS_FUCHSIA) +// Flaky: https://crbug.com/950983 +#define MAYBE_Multiprocess DISABLED_Multiprocess +#else +#define MAYBE_Multiprocess Multiprocess +#endif + +TEST_F(SplicedMessagePipeTest, MAYBE_Multiprocess) { MojoHandle a, b; CreateMessagePipe(&a, &b); RunTestClient("Client1", [&](MojoHandle h) {
diff --git a/net/dns/dns_test_util.cc b/net/dns/dns_test_util.cc index eab0df05..7270bd67 100644 --- a/net/dns/dns_test_util.cc +++ b/net/dns/dns_test_util.cc
@@ -304,7 +304,6 @@ } } - void SetRequestContext(URLRequestContext*) override {} void SetRequestPriority(RequestPriority priority) override {} MockDnsClientRule::Result result_; @@ -458,7 +457,8 @@ uint16_t qtype, DnsTransactionFactory::CallbackType callback, const NetLogWithSource&, - SecureDnsMode secure_dns_mode) override { + SecureDnsMode secure_dns_mode, + URLRequestContext* url_request_context) override { std::unique_ptr<MockTransaction> transaction = std::make_unique<MockTransaction>(rules_, hostname, qtype, secure_dns_mode, std::move(callback));
diff --git a/net/dns/dns_transaction.cc b/net/dns/dns_transaction.cc index 02af9b87..198b3dd4 100644 --- a/net/dns/dns_transaction.cc +++ b/net/dns/dns_transaction.cc
@@ -797,7 +797,8 @@ DnsTransactionFactory::CallbackType callback, const NetLogWithSource& net_log, const OptRecordRdata* opt_rdata, - SecureDnsMode secure_dns_mode) + SecureDnsMode secure_dns_mode, + URLRequestContext* url_request_context) : session_(session), hostname_(hostname), qtype_(qtype), @@ -811,6 +812,7 @@ had_tcp_attempt_(false), doh_attempt_(false), first_server_index_(0), + url_request_context_(url_request_context), request_priority_(DEFAULT_PRIORITY) { DCHECK(session_.get()); DCHECK(!hostname_.empty()); @@ -858,10 +860,6 @@ } } - void SetRequestContext(URLRequestContext* context) override { - url_request_context_ = context; - } - void SetRequestPriority(RequestPriority priority) override { request_priority_ = priority; } @@ -1289,10 +1287,11 @@ uint16_t qtype, CallbackType callback, const NetLogWithSource& net_log, - SecureDnsMode secure_dns_mode) override { + SecureDnsMode secure_dns_mode, + URLRequestContext* url_request_context) override { return std::make_unique<DnsTransactionImpl>( session_.get(), hostname, qtype, std::move(callback), net_log, - opt_rdata_.get(), secure_dns_mode); + opt_rdata_.get(), secure_dns_mode, url_request_context); } void AddEDNSOption(const OptRecordRdata::Opt& opt) override {
diff --git a/net/dns/dns_transaction.h b/net/dns/dns_transaction.h index 9576551c..6e9cde2 100644 --- a/net/dns/dns_transaction.h +++ b/net/dns/dns_transaction.h
@@ -42,8 +42,6 @@ // Starts the transaction. Always completes asynchronously. virtual void Start() = 0; - virtual void SetRequestContext(URLRequestContext*) = 0; - virtual void SetRequestPriority(RequestPriority priority) = 0; }; @@ -83,7 +81,8 @@ uint16_t qtype, CallbackType callback, const NetLogWithSource& net_log, - SecureDnsMode secure_dns_mode) WARN_UNUSED_RESULT = 0; + SecureDnsMode secure_dns_mode, + URLRequestContext* url_request_context) WARN_UNUSED_RESULT = 0; // The given EDNS0 option will be included in all DNS queries performed by // transactions from this factory.
diff --git a/net/dns/dns_transaction_unittest.cc b/net/dns/dns_transaction_unittest.cc index 9fd28aa..a83ecfa 100644 --- a/net/dns/dns_transaction_unittest.cc +++ b/net/dns/dns_transaction_unittest.cc
@@ -303,8 +303,7 @@ base::Bind(&TransactionHelper::OnTransactionComplete, base::Unretained(this)), NetLogWithSource::Make(&net_log_, net::NetLogSourceType::NONE), - secure_dns_mode_); - transaction_->SetRequestContext(&request_context_); + secure_dns_mode_, &request_context_); transaction_->SetRequestPriority(DEFAULT_PRIORITY); EXPECT_EQ(hostname_, transaction_->GetHostname()); EXPECT_EQ(qtype_, transaction_->GetType());
diff --git a/net/dns/host_resolver_manager.cc b/net/dns/host_resolver_manager.cc index e740cffb..fbbaa025 100644 --- a/net/dns/host_resolver_manager.cc +++ b/net/dns/host_resolver_manager.cc
@@ -999,8 +999,7 @@ base::BindOnce(&DnsTask::OnTransactionComplete, base::Unretained(this), tick_clock_->NowTicks(), dns_query_type), - net_log_, secure_dns_mode); - trans->SetRequestContext(delegate_->url_request_context()); + net_log_, secure_dns_mode, delegate_->url_request_context()); trans->SetRequestPriority(delegate_->priority()); return trans; }
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 118a1ff..f425393 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc
@@ -165,6 +165,9 @@ int HttpNetworkTransaction::Start(const HttpRequestInfo* request_info, CompletionOnceCallback callback, const NetLogWithSource& net_log) { + if (request_info->load_flags & LOAD_ONLY_FROM_CACHE) + return ERR_CACHE_MISS; + DCHECK(request_info->traffic_annotation.is_valid()); net_log_ = net_log; request_ = request_info;
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 52c3c54b..16559b3 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc
@@ -19640,6 +19640,21 @@ #endif // BUILDFLAG(ENABLE_REPORTING) +TEST_F(HttpNetworkTransactionTest, AlwaysFailRequestToCache) { + HttpRequestInfo request; + request.method = "GET"; + request.url = GURL("http://example.org/"); + + request.load_flags = LOAD_ONLY_FROM_CACHE; + + std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); + HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get()); + TestCompletionCallback callback1; + int rv = trans.Start(&request, callback1.callback(), NetLogWithSource()); + + EXPECT_THAT(rv, IsError(ERR_CACHE_MISS)); +} + TEST_F(HttpNetworkTransactionTest, ZeroRTTDoesntConfirm) { HttpRequestInfo request; request.method = "GET";
diff --git a/services/service_manager/sandbox/linux/bpf_audio_policy_linux.cc b/services/service_manager/sandbox/linux/bpf_audio_policy_linux.cc index f9c155ce..ee63d9e 100644 --- a/services/service_manager/sandbox/linux/bpf_audio_policy_linux.cc +++ b/services/service_manager/sandbox/linux/bpf_audio_policy_linux.cc
@@ -7,8 +7,10 @@ #include <sys/socket.h> #include "sandbox/linux/bpf_dsl/bpf_dsl.h" +#include "sandbox/linux/seccomp-bpf-helpers/sigsys_handlers.h" #include "sandbox/linux/seccomp-bpf-helpers/syscall_parameters_restrictions.h" #include "sandbox/linux/seccomp-bpf-helpers/syscall_sets.h" +#include "sandbox/linux/services/syscall_wrappers.h" #include "sandbox/linux/syscall_broker/broker_process.h" #include "sandbox/linux/system_headers/linux_futex.h" #include "sandbox/linux/system_headers/linux_syscalls.h" @@ -88,6 +90,23 @@ #endif } #endif +#if defined(__NR_kill) + case __NR_kill: { + // man kill says: + // "If sig is 0, then no signal is sent, but existence and permission + // checks are still performed; this can be used to check for the + // existence of a process ID or process group ID that the caller is + // permitted to signal." + // + // This seems to be tripping up at least ESET's NOD32 anti-virus, causing + // an unnecessary crash in the audio process. See: http://crbug.com/904787 + const Arg<pid_t> pid(0); + const Arg<int> sig(1); + return If(pid == sandbox::sys_getpid(), Allow()) + .ElseIf(sig == 0, Error(EPERM)) + .Else(sandbox::CrashSIGSYSKill()); + } +#endif #if defined(__NR_socket) case __NR_socket: { const Arg<int> domain(0);
diff --git a/services/video_capture/broadcasting_receiver.cc b/services/video_capture/broadcasting_receiver.cc index 78fadc1..29fe674 100644 --- a/services/video_capture/broadcasting_receiver.cc +++ b/services/video_capture/broadcasting_receiver.cc
@@ -288,10 +288,11 @@ auto buffer_context_iter = FindUnretiredBufferContextFromBufferId(buffer_id); CHECK(buffer_context_iter != buffer_contexts_.end()); auto& buffer_context = *buffer_context_iter; - buffer_context.set_access_permission(std::move(access_permission)); for (auto& client : clients_) { if (client.second.is_suspended()) continue; + if (access_permission) + buffer_context.set_access_permission(std::move(access_permission)); mojom::ScopedAccessPermissionPtr consumer_access_permission; mojo::MakeStrongBinding( std::make_unique<ConsumerAccessPermission>(base::BindOnce(
diff --git a/services/video_capture/broadcasting_receiver_unittest.cc b/services/video_capture/broadcasting_receiver_unittest.cc index 452f805..e5685f4 100644 --- a/services/video_capture/broadcasting_receiver_unittest.cc +++ b/services/video_capture/broadcasting_receiver_unittest.cc
@@ -17,6 +17,10 @@ namespace video_capture { +static const size_t kArbitraryDummyBufferSize = 8u; +static const int kArbiraryBufferId = 123; +static const int kArbiraryFrameFeedbackId = 456; + class FakeAccessPermission : public mojom::ScopedAccessPermission { public: FakeAccessPermission(base::OnceClosure destruction_cb) @@ -36,33 +40,32 @@ std::make_unique<MockReceiver>(mojo::MakeRequest(&receiver_1)); mock_receiver_2_ = std::make_unique<MockReceiver>(mojo::MakeRequest(&receiver_2)); - broadcaster_.AddClient(std::move(receiver_1), - media::VideoCaptureBufferType::kSharedMemory); - broadcaster_.AddClient(std::move(receiver_2), - media::VideoCaptureBufferType::kSharedMemory); + client_id_1_ = broadcaster_.AddClient( + std::move(receiver_1), media::VideoCaptureBufferType::kSharedMemory); + client_id_2_ = broadcaster_.AddClient( + std::move(receiver_2), media::VideoCaptureBufferType::kSharedMemory); + + ASSERT_TRUE(shm_provider.InitForSize(kArbitraryDummyBufferSize)); + media::mojom::VideoBufferHandlePtr buffer_handle = + media::mojom::VideoBufferHandle::New(); + buffer_handle->set_shared_buffer_handle( + shm_provider.GetHandleForInterProcessTransit(true /*read_only*/)); + broadcaster_.OnNewBuffer(kArbiraryBufferId, std::move(buffer_handle)); } protected: BroadcastingReceiver broadcaster_; std::unique_ptr<MockReceiver> mock_receiver_1_; std::unique_ptr<MockReceiver> mock_receiver_2_; + int32_t client_id_1_; + int32_t client_id_2_; + media::SharedMemoryHandleProvider shm_provider; base::test::ScopedTaskEnvironment task_environment_; }; TEST_F( BroadcastingReceiverTest, HoldsOnToAccessPermissionForRetiredBufferUntilLastClientFinishedConsuming) { - media::SharedMemoryHandleProvider shm_provider; - const size_t kArbitraryDummyBufferSize = 8u; - ASSERT_TRUE(shm_provider.InitForSize(kArbitraryDummyBufferSize)); - media::mojom::VideoBufferHandlePtr buffer_handle = - media::mojom::VideoBufferHandle::New(); - buffer_handle->set_shared_buffer_handle( - shm_provider.GetHandleForInterProcessTransit(true /*read_only*/)); - static const int kArbiraryBufferId = 123; - static const int kArbiraryFrameFeedbackId = 456; - broadcaster_.OnNewBuffer(kArbiraryBufferId, std::move(buffer_handle)); - base::RunLoop frame_arrived_at_receiver_1; base::RunLoop frame_arrived_at_receiver_2; EXPECT_CALL(*mock_receiver_1_, DoOnFrameReadyInBuffer(_, _, _, _)) @@ -126,4 +129,33 @@ EXPECT_TRUE(access_permission_has_been_released); } +TEST_F(BroadcastingReceiverTest, + DoesNotHoldOnToAccessPermissionWhenAllClientsAreSuspended) { + EXPECT_CALL(*mock_receiver_1_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0); + EXPECT_CALL(*mock_receiver_2_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0); + + broadcaster_.SuspendClient(client_id_1_); + broadcaster_.SuspendClient(client_id_2_); + + mojom::ScopedAccessPermissionPtr access_permission; + bool access_permission_has_been_released = false; + mojo::MakeStrongBinding(std::make_unique<FakeAccessPermission>(base::BindOnce( + [](bool* access_permission_has_been_released) { + *access_permission_has_been_released = true; + }, + &access_permission_has_been_released)), + mojo::MakeRequest(&access_permission)); + media::mojom::VideoFrameInfoPtr frame_info = + media::mojom::VideoFrameInfo::New(); + media::VideoFrameMetadata frame_metadata; + frame_info->metadata = frame_metadata.GetInternalValues().Clone(); + broadcaster_.OnFrameReadyInBuffer(kArbiraryBufferId, kArbiraryFrameFeedbackId, + std::move(access_permission), + std::move(frame_info)); + + // expect that |access_permission| is released + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(access_permission_has_been_released); +} + } // namespace video_capture
diff --git a/services/video_capture/test/mock_device_shared_access_unittest.cc b/services/video_capture/test/mock_device_shared_access_unittest.cc index 1fd271aa..d99ca7c 100644 --- a/services/video_capture/test/mock_device_shared_access_unittest.cc +++ b/services/video_capture/test/mock_device_shared_access_unittest.cc
@@ -14,6 +14,7 @@ #include "media/capture/video/video_capture_system_impl.h" #include "services/service_manager/public/cpp/service_keepalive.h" #include "services/video_capture/device_factory_media_to_mojo_adapter.h" +#include "services/video_capture/device_media_to_mojo_adapter.h" #include "services/video_capture/public/cpp/mock_receiver.h" #include "services/video_capture/public/mojom/device_factory_provider.mojom.h" #include "services/video_capture/public/mojom/video_source.mojom.h" @@ -33,8 +34,8 @@ MockDeviceSharedAccessTest() : mock_receiver_1_(mojo::MakeRequest(&receiver_1_)), mock_receiver_2_(mojo::MakeRequest(&receiver_2_)), - service_keepalive_(nullptr, base::nullopt), - next_arbitrary_frame_feedback_id_(123) {} + next_arbitrary_frame_feedback_id_(123), + service_keepalive_(nullptr, base::nullopt) {} ~MockDeviceSharedAccessTest() override {} void SetUp() override { @@ -259,9 +260,10 @@ mojom::ReceiverPtr receiver_2_; MockReceiver mock_receiver_2_; + int32_t next_arbitrary_frame_feedback_id_; + private: service_manager::ServiceKeepalive service_keepalive_; - int32_t next_arbitrary_frame_feedback_id_; }; // This alias ensures test output is easily attributed to this service's tests. @@ -429,6 +431,38 @@ SendFrameAndExpectToArriveAtBothSubscribers(); } +TEST_F(MockVideoCaptureDeviceSharedAccessTest, SuspendAndResumeSingleClient) { + LetClient1ConnectWithRequestableSettingsAndExpectToGetThem(); + subscription_1_->Activate(); + { + base::RunLoop wait_loop; + subscription_1_->Suspend(base::BindOnce( + [](base::RunLoop* wait_loop) { wait_loop->Quit(); }, &wait_loop)); + wait_loop.Run(); + } + EXPECT_CALL(mock_receiver_1_, DoOnFrameReadyInBuffer(_, _, _, _)).Times(0); + + // Send a couple of frames. We want to send at least as many frames as + // the maximum buffer count in the video frame pool to make sure that + // buffers are properly released and reused. + mock_device_.SendOnStarted(); + for (int i = 0; i < DeviceMediaToMojoAdapter::max_buffer_pool_buffer_count(); + i++) { + const int32_t kArbitraryRotation = 0; + const int32_t kArbitraryFrameFeedbackId = + next_arbitrary_frame_feedback_id_++; + mock_device_.SendStubFrame(requestable_settings_.requested_format, + kArbitraryRotation, kArbitraryFrameFeedbackId); + // We need to wait until the frame has arrived at BroadcastingReceiver + base::RunLoop().RunUntilIdle(); + } + Mock::VerifyAndClearExpectations(&mock_receiver_1_); + + subscription_1_->Resume(); + subscription_1_.FlushForTesting(); + SendFrameAndExpectToArriveOnlyAtSubscriber1(); +} + TEST_F(MockVideoCaptureDeviceSharedAccessTest, CreateNewSubscriptionAfterClosingExistingOneUsesNewSettings) { LetClient1ConnectWithRequestableSettingsAndExpectToGetThem();
diff --git a/storage/browser/fileapi/sandbox_file_system_backend.cc b/storage/browser/fileapi/sandbox_file_system_backend.cc index 5e2f0d1..b1a073e 100644 --- a/storage/browser/fileapi/sandbox_file_system_backend.cc +++ b/storage/browser/fileapi/sandbox_file_system_backend.cc
@@ -19,6 +19,7 @@ #include "storage/browser/fileapi/file_stream_reader.h" #include "storage/browser/fileapi/file_stream_writer.h" #include "storage/browser/fileapi/file_system_context.h" +#include "storage/browser/fileapi/file_system_features.h" #include "storage/browser/fileapi/file_system_operation.h" #include "storage/browser/fileapi/file_system_operation_context.h" #include "storage/browser/fileapi/file_system_options.h" @@ -38,8 +39,8 @@ SandboxFileSystemBackend::SandboxFileSystemBackend( SandboxFileSystemBackendDelegate* delegate) : delegate_(delegate), - enable_temporary_file_system_in_incognito_(false) { -} + enable_temporary_file_system_in_incognito_(base::FeatureList::IsEnabled( + features::kEnableFilesystemInIncognito)) {} SandboxFileSystemBackend::~SandboxFileSystemBackend() = default; @@ -125,7 +126,9 @@ bool SandboxFileSystemBackend::SupportsStreaming( const storage::FileSystemURL& url) const { - return false; + // Streaming is required for in-memory implementation to access memory-backed + // files. + return delegate_->file_system_options().is_incognito(); } bool SandboxFileSystemBackend::HasInplaceCopyImplementation(
diff --git a/testing/buildbot/chromium.win.json b/testing/buildbot/chromium.win.json index 8aaef0b..a0a18877 100644 --- a/testing/buildbot/chromium.win.json +++ b/testing/buildbot/chromium.win.json
@@ -3219,22 +3219,6 @@ } }, { - "args": [ - "--test-type=integration" - ], - "isolate_name": "chromedriver_py_tests", - "name": "chromedriver_py_tests", - "swarming": { - "can_use_on_swarming_builders": true, - "dimension_sets": [ - { - "cpu": "x86-64", - "os": "Windows-10-15063" - } - ] - } - }, - { "isolate_name": "chromedriver_replay_unittests", "name": "chromedriver_replay_unittests", "swarming": {
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 3dd01ab..8aa8a09c 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -353,6 +353,13 @@ } } }, + 'chromedriver_py_tests': { + 'remove_from': [ + # Timeout happens sometimes (crbug.com/951799). + 'Win10 Tests x64', + 'Win10 Tests x64 (dbg)', + ], + }, 'components_unittests': { 'modifications': { # chromium.memory
diff --git a/third_party/android_crazy_linker/BUILD.gn b/third_party/android_crazy_linker/BUILD.gn index f9e1358..a7c21e02 100644 --- a/third_party/android_crazy_linker/BUILD.gn +++ b/third_party/android_crazy_linker/BUILD.gn
@@ -144,6 +144,12 @@ public_configs = [ ":crazy_config" ] configs -= [ "//build/config/compiler:chromium_code" ] configs += [ "//build/config/compiler:no_chromium_code" ] + + # This is used to allow shared memory regions to work on Android Q+ + # See http://crbug.com/949804 + deps = [ + "//third_party/ashmem", + ] } }
diff --git a/third_party/android_crazy_linker/src/src/crazy_linker_ashmem.cpp b/third_party/android_crazy_linker/src/src/crazy_linker_ashmem.cpp index 875bf74..2dbdcca 100644 --- a/third_party/android_crazy_linker/src/src/crazy_linker_ashmem.cpp +++ b/third_party/android_crazy_linker/src/src/crazy_linker_ashmem.cpp
@@ -11,7 +11,7 @@ #include <sys/types.h> #include <unistd.h> -#include <linux/ashmem.h> +#include "third_party/ashmem/ashmem.h" #include "crazy_linker_system.h" #include "crazy_linker_memory_mapping.h" @@ -19,30 +19,16 @@ namespace crazy { bool AshmemRegion::Allocate(size_t region_size, const char* region_name) { - int fd = TEMP_FAILURE_RETRY(open("/dev/ashmem", O_RDWR)); + int fd = ashmem_create_region(region_name, region_size); if (fd < 0) return false; - if (ioctl(fd, ASHMEM_SET_SIZE, region_size) < 0) - goto ERROR; - - if (region_name) { - char buf[256]; - strlcpy(buf, region_name, sizeof(buf)); - if (ioctl(fd, ASHMEM_SET_NAME, buf) < 0) - goto ERROR; - } - Reset(fd); return true; - -ERROR: - ::close(fd); - return false; } bool AshmemRegion::SetProtectionFlags(int prot) { - return ioctl(fd_, ASHMEM_SET_PROT_MASK, prot) == 0; + return ashmem_set_prot_region(fd_, prot) == 0; } // static
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 22de4a7..1a56b5b 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -209,7 +209,7 @@ // Allows for synchronous XHR requests during page dismissal const base::Feature kForbidSyncXHRInPageDismissal{ - "ForbidSyncXHRInPageDismissal", base::FEATURE_DISABLED_BY_DEFAULT}; + "ForbidSyncXHRInPageDismissal", base::FEATURE_ENABLED_BY_DEFAULT}; // Emergency lever that can be used to restore DeviceOrientationEvent and // DeviceMotionEvent functionality in non-secure browsing contexts.
diff --git a/third_party/blink/renderer/core/dom/text.cc b/third_party/blink/renderer/core/dom/text.cc index 8f5a7531..67f8b5c 100644 --- a/third_party/blink/renderer/core/dom/text.cc +++ b/third_party/blink/renderer/core/dom/text.cc
@@ -403,11 +403,11 @@ // The computed style or the need for an anonymous inline wrapper for a // display:contents text child changed. SetNeedsReattachLayoutTree(); - return; + } else { + layout_text->SetStyle(std::move(new_style)); + if (NeedsStyleRecalc()) + layout_text->SetText(DataImpl()); } - layout_text->SetStyle(std::move(new_style)); - if (NeedsStyleRecalc()) - layout_text->SetText(DataImpl()); } else if (new_style && (NeedsStyleRecalc() || change.ReattachLayoutTree() || NeedsWhitespaceLayoutObject(*new_style))) { SetNeedsReattachLayoutTree();
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 1612018..c9dfdd6 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -4320,15 +4320,13 @@ if (RuntimeEnabledFeatures::CompositeAfterPaintEnabled() || RuntimeEnabledFeatures::BlinkGenPropertyTreesEnabled()) { DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kPrePaintClean); - if (const auto* scroll = - GetLayoutView()->FirstFragment().PaintProperties()->Scroll()) { - reasons = scroll->GetMainThreadScrollingReasons(); - } + const auto* properties = GetLayoutView()->FirstFragment().PaintProperties(); + if (properties && properties->Scroll()) + reasons = properties->Scroll()->GetMainThreadScrollingReasons(); } else { DCHECK(Lifecycle().GetState() >= DocumentLifecycle::kCompositingClean); reasons = main_thread_scrolling_reasons_; - if (GraphicsLayer* layer_for_scrolling = - LayoutViewport()->LayerForScrolling()) { + if (auto* layer_for_scrolling = LayoutViewport()->LayerForScrolling()) { if (cc::Layer* cc_layer = layer_for_scrolling->CcLayer()) reasons = cc_layer->GetMainThreadScrollingReasons(); }
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.cc b/third_party/blink/renderer/core/paint/paint_invalidator.cc index 86379cd..59cc574 100644 --- a/third_party/blink/renderer/core/paint/paint_invalidator.cc +++ b/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -93,15 +93,10 @@ if (!disable_flip) { if (object.IsBox()) { ToLayoutBox(object).FlipForWritingMode(rect); - } else if (!(context.subtree_flags & - PaintInvalidatorContext::kSubtreeSlowPathRect)) { - // For CAP and the GeometryMapper path, we also need to convert the - // rect for non-boxes into physical coordinates before applying paint - // offset. (Otherwise we'll call mapToVisualrectInAncestorSpace() which - // requires physical coordinates for boxes, but "physical coordinates - // with flipped block-flow direction" for non-boxes for which we don't - // need to flip.) - // TODO(wangxianzhu): Avoid containingBlock(). + } else { + // Also convert the rect for non-boxes into physical coordinates before + // applying paint offset. + // TODO(wangxianzhu): Avoid ContainingBlock(). object.ContainingBlock()->FlipForWritingMode(rect); } } @@ -336,17 +331,6 @@ object.GetMutableForPainting().EnsureIsReadyForPaintInvalidation(); UpdatePaintingLayer(object, context); - - // TODO(chrishtr): refactor to remove these slow paths by expanding their - // LocalVisualRect to include repeated locations. - if (object.IsTableSection()) { - const auto& section = ToLayoutTableSection(object); - if (section.IsRepeatingHeaderGroup() || section.IsRepeatingFooterGroup()) - context.subtree_flags |= PaintInvalidatorContext::kSubtreeSlowPathRect; - } - if (object.IsFixedPositionObjectInPagedMedia()) - context.subtree_flags |= PaintInvalidatorContext::kSubtreeSlowPathRect; - UpdatePaintInvalidationContainer(object, context); UpdateEmptyVisualRectFlag(object, context);
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.h b/third_party/blink/renderer/core/paint/paint_invalidator.h index c177695..cd5a9fd 100644 --- a/third_party/blink/renderer/core/paint/paint_invalidator.h +++ b/third_party/blink/renderer/core/paint/paint_invalidator.h
@@ -81,9 +81,6 @@ kSubtreeFullInvalidation = 1 << 2, kSubtreeFullInvalidationForStackedContents = 1 << 3, - // For repeated objects inside multicolumn. - kSubtreeSlowPathRect = 1 << 4, - // When this flag is set, no paint or raster invalidation will be issued // for the subtree. //
diff --git a/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js b/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js index 4ac5147..0188e67 100644 --- a/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js +++ b/third_party/blink/renderer/devtools/front_end/devtools_compatibility.js
@@ -992,6 +992,7 @@ 'textEditorAutoDetectIndent', 'textEditorBracketMatching', 'textEditorIndent', + 'textEditorTabMovesFocus', 'timelineCaptureFilmStrip', 'timelineCaptureLayersAndPictures', 'timelineCaptureMemory',
diff --git a/third_party/blink/renderer/devtools/front_end/sources/module.json b/third_party/blink/renderer/devtools/front_end/sources/module.json index 2bad0b32dc..cbe6029 100644 --- a/third_party/blink/renderer/devtools/front_end/sources/module.json +++ b/third_party/blink/renderer/devtools/front_end/sources/module.json
@@ -427,6 +427,24 @@ { "type": "setting", "category": "Sources", + "title": "Enable tab moves focus", + "settingName": "textEditorTabMovesFocus", + "settingType": "boolean", + "defaultValue": false, + "options": [ + { + "value": true, + "title": "Enable tab moves focus" + }, + { + "value": false, + "title": "Disable tab moves focus" + } + ] + }, + { + "type": "setting", + "category": "Sources", "title": "Detect indentation", "settingName": "textEditorAutoDetectIndent", "settingType": "boolean",
diff --git a/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js b/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js index 1335b70..9581a54 100644 --- a/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js +++ b/third_party/blink/renderer/devtools/front_end/text_editor/CodeMirrorTextEditor.js
@@ -561,6 +561,10 @@ * @param {!Event} e */ _handleKeyDown(e) { + if (e.key === 'Tab' && Common.moduleSetting('textEditorTabMovesFocus').get()) { + e.consume(false); + return; + } if (this._autocompleteController && this._autocompleteController.keyDown(e)) e.consume(true); }
diff --git a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc index b235b20f..f1ad817 100644 --- a/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc +++ b/third_party/blink/renderer/modules/filesystem/dom_file_system_base.cc
@@ -182,10 +182,13 @@ // types (which could be platform-specific ones), there's a chance that the // files are on remote filesystem. If the port has returned metadata just // pass it to File constructor (so we may cache the metadata). + // If |metadata.platform_path|, filesystem will decide about the actual + // storage location based on the url. // FIXME: We should use the snapshot metadata for all files. // https://www.w3.org/Bugs/Public/show_bug.cgi?id=17746 - if (type == mojom::blink::FileSystemType::kTemporary || - type == mojom::blink::FileSystemType::kPersistent) + if (!metadata.platform_path.IsEmpty() && + (type == mojom::blink::FileSystemType::kTemporary || + type == mojom::blink::FileSystemType::kPersistent)) return File::CreateForFileSystemFile(metadata.platform_path, name); const File::UserVisibility user_visibility =
diff --git a/third_party/blink/renderer/modules/modules_idl_files.gni b/third_party/blink/renderer/modules/modules_idl_files.gni index f71964b..dea3c0f 100644 --- a/third_party/blink/renderer/modules/modules_idl_files.gni +++ b/third_party/blink/renderer/modules/modules_idl_files.gni
@@ -394,6 +394,7 @@ "webgl/oes_texture_half_float.idl", "webgl/oes_texture_half_float_linear.idl", "webgl/oes_vertex_array_object.idl", + "webgl/ovr_multiview_2.idl", "webgl/webgl2_rendering_context.idl", "webgl/webgl_active_info.idl", "webgl/webgl_buffer.idl", @@ -413,7 +414,6 @@ "webgl/webgl_lose_context.idl", "webgl/webgl_multi_draw_instanced.idl", "webgl/webgl_multi_draw.idl", - "webgl/webgl_multiview.idl", "webgl/webgl_program.idl", "webgl/webgl_query.idl", "webgl/webgl_renderbuffer.idl",
diff --git a/third_party/blink/renderer/modules/webgl/BUILD.gn b/third_party/blink/renderer/modules/webgl/BUILD.gn index c6e827d..36169ad 100644 --- a/third_party/blink/renderer/modules/webgl/BUILD.gn +++ b/third_party/blink/renderer/modules/webgl/BUILD.gn
@@ -45,6 +45,8 @@ "oes_texture_half_float_linear.h", "oes_vertex_array_object.cc", "oes_vertex_array_object.h", + "ovr_multiview_2.cc", + "ovr_multiview_2.h", "webgl2_rendering_context.cc", "webgl2_rendering_context.h", "webgl2_rendering_context_base.cc", @@ -97,8 +99,6 @@ "webgl_multi_draw_common.h", "webgl_multi_draw_instanced.cc", "webgl_multi_draw_instanced.h", - "webgl_multiview.cc", - "webgl_multiview.h", "webgl_object.cc", "webgl_object.h", "webgl_program.cc",
diff --git a/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc new file mode 100644 index 0000000..8e4a3467 --- /dev/null +++ b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.cc
@@ -0,0 +1,95 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/modules/webgl/ovr_multiview_2.h" + +#include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h" +#include "third_party/blink/renderer/modules/webgl/webgl_framebuffer.h" +#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h" + +namespace blink { + +OVRMultiview2::OVRMultiview2(WebGLRenderingContextBase* context) + : WebGLExtension(context) { + context->ExtensionsUtil()->EnsureExtensionEnabled("GL_OVR_multiview2"); + context->ContextGL()->GetIntegerv(GL_MAX_VIEWS_OVR, &max_views_ovr_); +} + +WebGLExtensionName OVRMultiview2::GetName() const { + return kOVRMultiview2Name; +} + +OVRMultiview2* OVRMultiview2::Create(WebGLRenderingContextBase* context) { + return MakeGarbageCollected<OVRMultiview2>(context); +} + +void OVRMultiview2::framebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + WebGLTexture* texture, + GLint level, + GLint base_view_index, + GLsizei num_views) { + WebGLExtensionScopedContext scoped(this); + if (scoped.IsLost()) + return; + if (!scoped.Context()->ValidateNullableWebGLObject( + "framebufferTextureMultiviewOVR", texture)) + return; + GLenum textarget = texture ? texture->GetTarget() : 0; + if (texture) { + if (textarget != GL_TEXTURE_2D_ARRAY) { + scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION, + "framebufferTextureMultiviewOVR", + "invalid texture type"); + return; + } + if (num_views < 1) { + scoped.Context()->SynthesizeGLError(GL_INVALID_VALUE, + "framebufferTextureMultiviewOVR", + "numViews is less than one"); + return; + } + if (num_views > max_views_ovr_) { + scoped.Context()->SynthesizeGLError( + GL_INVALID_VALUE, "framebufferTextureMultiviewOVR", + "numViews is more than the value of MAX_VIEWS_OVR"); + return; + } + if (!static_cast<WebGL2RenderingContextBase*>(scoped.Context()) + ->ValidateTexFuncLayer("framebufferTextureMultiviewOVR", textarget, + base_view_index)) + return; + if (!static_cast<WebGL2RenderingContextBase*>(scoped.Context()) + ->ValidateTexFuncLayer("framebufferTextureMultiviewOVR", textarget, + base_view_index + num_views - 1)) + return; + if (!scoped.Context()->ValidateTexFuncLevel( + "framebufferTextureMultiviewOVR", textarget, level)) + return; + } + + WebGLFramebuffer* framebuffer_binding = + scoped.Context()->GetFramebufferBinding(target); + if (!framebuffer_binding || !framebuffer_binding->Object()) { + scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION, + "framebufferTextureMultiviewOVR", + "no framebuffer bound"); + return; + } + + framebuffer_binding->SetAttachmentForBoundFramebuffer( + target, attachment, textarget, texture, level, base_view_index, + num_views); + scoped.Context()->ApplyStencilTest(); +} + +bool OVRMultiview2::Supported(WebGLRenderingContextBase* context) { + return context->ExtensionsUtil()->SupportsExtension("GL_OVR_multiview2"); +} + +const char* OVRMultiview2::ExtensionName() { + return "OVR_multiview2"; +} + +} // namespace blink
diff --git a/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h new file mode 100644 index 0000000..f6a3ff9 --- /dev/null +++ b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.h
@@ -0,0 +1,37 @@ +// Copyright 2018 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OVR_MULTIVIEW_2_H_ +#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OVR_MULTIVIEW_2_H_ + +#include "third_party/blink/renderer/modules/webgl/webgl_extension.h" + +namespace blink { + +class OVRMultiview2 final : public WebGLExtension { + DEFINE_WRAPPERTYPEINFO(); + + public: + static OVRMultiview2* Create(WebGLRenderingContextBase*); + static bool Supported(WebGLRenderingContextBase*); + static const char* ExtensionName(); + + explicit OVRMultiview2(WebGLRenderingContextBase*); + + WebGLExtensionName GetName() const override; + + void framebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + WebGLTexture* texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews); + + private: + GLsizei max_views_ovr_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_OVR_MULTIVIEW_2_H_
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multiview.idl b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.idl similarity index 79% rename from third_party/blink/renderer/modules/webgl/webgl_multiview.idl rename to third_party/blink/renderer/modules/webgl/ovr_multiview_2.idl index 2ca349f..b004ba1a 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_multiview.idl +++ b/third_party/blink/renderer/modules/webgl/ovr_multiview_2.idl
@@ -2,19 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// https://www.khronos.org/registry/webgl/extensions/WEBGL_multiview/ +// https://www.khronos.org/registry/webgl/extensions/OVR_multiview2/ [ NoInterfaceObject, DoNotCheckConstants ] -interface WebGLMultiview { +interface OVRMultiview2 { const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR = 0x9630; const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR = 0x9632; const GLenum MAX_VIEWS_OVR = 0x9631; const GLenum FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR = 0x9633; - void framebufferTextureMultiviewWEBGL(GLenum target, GLenum attachment, + void framebufferTextureMultiviewOVR(GLenum target, GLenum attachment, WebGLTexture? texture, GLint level, GLint baseViewIndex, GLsizei numViews);
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc index 96adf00..f39b291 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.cc
@@ -20,6 +20,7 @@ #include "third_party/blink/renderer/modules/webgl/ext_texture_filter_anisotropic.h" #include "third_party/blink/renderer/modules/webgl/khr_parallel_shader_compile.h" #include "third_party/blink/renderer/modules/webgl/oes_texture_float_linear.h" +#include "third_party/blink/renderer/modules/webgl/ovr_multiview_2.h" #include "third_party/blink/renderer/modules/webgl/webgl_compressed_texture_astc.h" #include "third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc.h" #include "third_party/blink/renderer/modules/webgl/webgl_compressed_texture_etc1.h" @@ -33,7 +34,6 @@ #include "third_party/blink/renderer/modules/webgl/webgl_lose_context.h" #include "third_party/blink/renderer/modules/webgl/webgl_multi_draw.h" #include "third_party/blink/renderer/modules/webgl/webgl_multi_draw_instanced.h" -#include "third_party/blink/renderer/modules/webgl/webgl_multiview.h" #include "third_party/blink/renderer/modules/webgl/webgl_video_texture.h" #include "third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.h" @@ -146,8 +146,8 @@ RegisterExtension<WebGLMultiDraw>(webgl_multi_draw_, kDraftExtension); RegisterExtension<WebGLMultiDrawInstanced>(webgl_multi_draw_instanced_, kDraftExtension); - RegisterExtension<WebGLMultiview>(webgl_multiview_, kDraftExtension); RegisterExtension<WebGLVideoTexture>(webgl_video_texture_, kDraftExtension); + RegisterExtension<OVRMultiview2>(ovr_multiview2_, kDraftExtension); } void WebGL2RenderingContext::Trace(blink::Visitor* visitor) { @@ -157,6 +157,7 @@ visitor->Trace(ext_texture_filter_anisotropic_); visitor->Trace(khr_parallel_shader_compile_); visitor->Trace(oes_texture_float_linear_); + visitor->Trace(ovr_multiview2_); visitor->Trace(webgl_compressed_texture_astc_); visitor->Trace(webgl_compressed_texture_etc_); visitor->Trace(webgl_compressed_texture_etc1_); @@ -168,7 +169,6 @@ visitor->Trace(webgl_lose_context_); visitor->Trace(webgl_multi_draw_); visitor->Trace(webgl_multi_draw_instanced_); - visitor->Trace(webgl_multiview_); visitor->Trace(webgl_video_texture_); WebGL2RenderingContextBase::Trace(visitor); }
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h index 36c2d17c..5765703e 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context.h
@@ -18,11 +18,11 @@ class EXTFloatBlend; class EXTTextureFilterAnisotropic; class OESTextureFloatLinear; +class OVRMultiview2; class WebGLDebugRendererInfo; class WebGLLoseContext; class WebGLMultiDraw; class WebGLMultiDrawInstanced; -class WebGLMultiview; class KHRParallelShaderCompile; class WebGLVideoTexture; @@ -71,6 +71,7 @@ Member<EXTTextureFilterAnisotropic> ext_texture_filter_anisotropic_; Member<KHRParallelShaderCompile> khr_parallel_shader_compile_; Member<OESTextureFloatLinear> oes_texture_float_linear_; + Member<OVRMultiview2> ovr_multiview2_; Member<WebGLCompressedTextureASTC> webgl_compressed_texture_astc_; Member<WebGLCompressedTextureETC> webgl_compressed_texture_etc_; Member<WebGLCompressedTextureETC1> webgl_compressed_texture_etc1_; @@ -82,7 +83,6 @@ Member<WebGLLoseContext> webgl_lose_context_; Member<WebGLMultiDraw> webgl_multi_draw_; Member<WebGLMultiDrawInstanced> webgl_multi_draw_instanced_; - Member<WebGLMultiview> webgl_multiview_; Member<WebGLVideoTexture> webgl_video_texture_; };
diff --git a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc index 25ea271..2b89184 100644 --- a/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.cc
@@ -5697,18 +5697,16 @@ case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: return WebGLAny(script_state, GL_LINEAR); case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR: - if (ExtensionEnabled(kWebGLMultiviewName)) + if (ExtensionEnabled(kOVRMultiview2Name)) return WebGLAny(script_state, 0); - SynthesizeGLError( - GL_INVALID_ENUM, kFunctionName, - "invalid parameter name, WEBGL_multiview not enabled"); + SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, + "invalid parameter name, OVR_multiview2 not enabled"); return ScriptValue::CreateNull(script_state); case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: - if (ExtensionEnabled(kWebGLMultiviewName)) + if (ExtensionEnabled(kOVRMultiview2Name)) return WebGLAny(script_state, 0); - SynthesizeGLError( - GL_INVALID_ENUM, kFunctionName, - "invalid parameter name, WEBGL_multiview not enabled"); + SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, + "invalid parameter name, OVR_multiview2 not enabled"); return ScriptValue::CreateNull(script_state); default: SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, @@ -5788,10 +5786,9 @@ } case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR: case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR: { - if (!ExtensionEnabled(kWebGLMultiviewName)) { - SynthesizeGLError( - GL_INVALID_ENUM, kFunctionName, - "invalid parameter name, WEBGL_multiview not enabled"); + if (!ExtensionEnabled(kOVRMultiview2Name)) { + SynthesizeGLError(GL_INVALID_ENUM, kFunctionName, + "invalid parameter name, OVR_multiview2 not enabled"); return ScriptValue::CreateNull(script_state); } GLint value = 0;
diff --git a/third_party/blink/renderer/modules/webgl/webgl_extension_name.h b/third_party/blink/renderer/modules/webgl/webgl_extension_name.h index 03e849c..474a38a 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_extension_name.h +++ b/third_party/blink/renderer/modules/webgl/webgl_extension_name.h
@@ -28,6 +28,7 @@ kOESTextureHalfFloatLinearName, kOESTextureHalfFloatName, kOESVertexArrayObjectName, + kOVRMultiview2Name, kWebGLColorBufferFloatName, kWebGLCompressedTextureASTCName, kWebGLCompressedTextureETCName,
diff --git a/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc b/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc index fd87ef5..0746836d 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_framebuffer.cc
@@ -251,7 +251,7 @@ case GL_TEXTURE_2D_ARRAY: if (num_views > 0) { DCHECK_EQ(static_cast<GLenum>(GL_TEXTURE_2D_ARRAY), tex_target); - Context()->ContextGL()->FramebufferTextureMultiviewLayeredANGLE( + Context()->ContextGL()->FramebufferTextureMultiviewOVR( target, attachment, texture_id, level, layer, num_views); } else { Context()->ContextGL()->FramebufferTextureLayer(
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multiview.cc b/third_party/blink/renderer/modules/webgl/webgl_multiview.cc deleted file mode 100644 index 0419e82..0000000 --- a/third_party/blink/renderer/modules/webgl/webgl_multiview.cc +++ /dev/null
@@ -1,102 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "third_party/blink/renderer/modules/webgl/webgl_multiview.h" - -#include "third_party/blink/renderer/modules/webgl/webgl2_rendering_context_base.h" -#include "third_party/blink/renderer/modules/webgl/webgl_framebuffer.h" -#include "third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h" - -namespace blink { - -WebGLMultiview::WebGLMultiview(WebGLRenderingContextBase* context) - : WebGLExtension(context) { - context->ExtensionsUtil()->EnsureExtensionEnabled("GL_ANGLE_multiview"); - context->ContextGL()->GetIntegerv(GL_MAX_VIEWS_OVR, &max_views_ovr_); -} - -WebGLExtensionName WebGLMultiview::GetName() const { - return kWebGLMultiviewName; -} - -WebGLMultiview* WebGLMultiview::Create(WebGLRenderingContextBase* context) { - return MakeGarbageCollected<WebGLMultiview>(context); -} - -void WebGLMultiview::framebufferTextureMultiviewWEBGL(GLenum target, - GLenum attachment, - WebGLTexture* texture, - GLint level, - GLint base_view_index, - GLsizei num_views) { - WebGLExtensionScopedContext scoped(this); - if (scoped.IsLost()) - return; - if (!scoped.Context()->ValidateNullableWebGLObject( - "framebufferTextureMultiviewWEBGL", texture)) - return; - GLenum textarget = texture ? texture->GetTarget() : 0; - if (texture) { - if (textarget != GL_TEXTURE_2D_ARRAY) { - scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION, - "framebufferTextureMultiviewWEBGL", - "invalid texture type"); - return; - } - if (num_views < 1) { - scoped.Context()->SynthesizeGLError(GL_INVALID_VALUE, - "framebufferTextureMultiviewWEBGL", - "numViews is less than one"); - return; - } - if (num_views > max_views_ovr_) { - scoped.Context()->SynthesizeGLError( - GL_INVALID_VALUE, "framebufferTextureMultiviewWEBGL", - "numViews is more than the value of MAX_VIEWS_OVR"); - return; - } - if (!static_cast<WebGL2RenderingContextBase*>(scoped.Context()) - ->ValidateTexFuncLayer("framebufferTextureMultiviewWEBGL", - textarget, base_view_index)) - return; - if (!static_cast<WebGL2RenderingContextBase*>(scoped.Context()) - ->ValidateTexFuncLayer("framebufferTextureMultiviewWEBGL", - textarget, base_view_index + num_views - 1)) - return; - if (!scoped.Context()->ValidateTexFuncLevel( - "framebufferTextureMultiviewWEBGL", textarget, level)) - return; - } - - WebGLFramebuffer* framebuffer_binding = - scoped.Context()->GetFramebufferBinding(target); - if (!framebuffer_binding || !framebuffer_binding->Object()) { - scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION, - "framebufferTextureMultiviewWEBGL", - "no framebuffer bound"); - return; - } - // Don't allow modifications to opaque framebuffer attachements. - if (framebuffer_binding->Opaque()) { - scoped.Context()->SynthesizeGLError(GL_INVALID_OPERATION, - "framebufferTextureMultiviewWEBGL", - "opaque framebuffer bound"); - return; - } - - framebuffer_binding->SetAttachmentForBoundFramebuffer( - target, attachment, textarget, texture, level, base_view_index, - num_views); - scoped.Context()->ApplyStencilTest(); -} - -bool WebGLMultiview::Supported(WebGLRenderingContextBase* context) { - return context->ExtensionsUtil()->SupportsExtension("GL_ANGLE_multiview"); -} - -const char* WebGLMultiview::ExtensionName() { - return "WEBGL_multiview"; -} - -} // namespace blink
diff --git a/third_party/blink/renderer/modules/webgl/webgl_multiview.h b/third_party/blink/renderer/modules/webgl/webgl_multiview.h deleted file mode 100644 index 8f76d0f..0000000 --- a/third_party/blink/renderer/modules/webgl/webgl_multiview.h +++ /dev/null
@@ -1,37 +0,0 @@ -// Copyright 2018 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_MULTIVIEW_H_ -#define THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_MULTIVIEW_H_ - -#include "third_party/blink/renderer/modules/webgl/webgl_extension.h" - -namespace blink { - -class WebGLMultiview final : public WebGLExtension { - DEFINE_WRAPPERTYPEINFO(); - - public: - static WebGLMultiview* Create(WebGLRenderingContextBase*); - static bool Supported(WebGLRenderingContextBase*); - static const char* ExtensionName(); - - explicit WebGLMultiview(WebGLRenderingContextBase*); - - WebGLExtensionName GetName() const override; - - void framebufferTextureMultiviewWEBGL(GLenum target, - GLenum attachment, - WebGLTexture* texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews); - - private: - GLsizei max_views_ovr_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_WEBGL_WEBGL_MULTIVIEW_H_
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc index cf44193..84cacc3 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.cc
@@ -3405,10 +3405,10 @@ "invalid parameter name, EXT_disjoint_timer_query not enabled"); return ScriptValue::CreateNull(script_state); case GL_MAX_VIEWS_OVR: - if (ExtensionEnabled(kWebGLMultiviewName)) + if (ExtensionEnabled(kOVRMultiview2Name)) return GetIntParameter(script_state, pname); SynthesizeGLError(GL_INVALID_ENUM, "getParameter", - "invalid parameter name, WEBGL_multiview not enabled"); + "invalid parameter name, OVR_multiview2 not enabled"); return ScriptValue::CreateNull(script_state); default: if ((ExtensionEnabled(kWebGLDrawBuffersName) || IsWebGL2OrHigher()) &&
diff --git a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h index 132311a..eba175f 100644 --- a/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h +++ b/third_party/blink/renderer/modules/webgl/webgl_rendering_context_base.h
@@ -623,6 +623,7 @@ friend class WebGLObject; friend class WebGLContextObject; friend class OESVertexArrayObject; + friend class OVRMultiview2; friend class WebGLDebugShaders; friend class WebGLCompressedTextureASTC; friend class WebGLCompressedTextureETC; @@ -633,7 +634,6 @@ friend class WebGLMultiDraw; friend class WebGLMultiDrawCommon; friend class WebGLMultiDrawInstanced; - friend class WebGLMultiview; friend class WebGLRenderingContextErrorMessageCallback; friend class WebGLVertexArrayObjectBase; friend class WebGLVideoTexture;
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 3ea264aa..ee4878ff 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -6266,3 +6266,7 @@ crbug.com/951638 [ Linux ] virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Pass Failure ] crbug.com/951638 [ Mac10.13 Debug ] virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Pass Failure ] crbug.com/951638 [ Win7 ] virtual/mouseevent_fractional/fast/events/mouse-right-coords-in-zoom-and-scroll-right.html [ Pass Failure ] + +# Sheriff 2019-04-11 +crbug.com/951774 [ Linux ] virtual/video-surface-layer/media/controls/modern/overlay-play-button-tap-to-hide.html [ Pass Timeout ] +crbug.com/951811 [ Mac10.13 ] external/wpt/html/browsers/the-window-object/apis-for-creating-and-navigating-browsing-contexts-by-name/open-features-tokenization-top-left.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json index c0623e4d..168fe69 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_5.json
@@ -470247,7 +470247,7 @@ "support" ], "tools/ci/azure/install_safari.yml": [ - "88381085665fe71c40933a5ad4a59cbe15463236", + "be18f8376467b516a68e026c493b8fb679697236", "support" ], "tools/ci/azure/pip_install.yml": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/reference/green-text.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/reference/green-text.html new file mode 100644 index 0000000..95736b4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/reference/green-text.html
@@ -0,0 +1,3 @@ +<!doctype html> +<title>CSS Test: Reference</title> +<p style="color:green">This text should be green.</p>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/reslot-text-inheritance.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/reslot-text-inheritance.html new file mode 100644 index 0000000..43711c8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/reslot-text-inheritance.html
@@ -0,0 +1,17 @@ +<!doctype html> +<html class="reftest-wait"> +<title>CSS Test: Re-slotted text node inheritance</title> +<link rel="help" href="https://drafts.csswg.org/css-scoping/#slotted-pseudo"> +<link rel="match" href="reference/green-text.html"> +<script src="/common/reftest-wait.js"></script> +<p id="host">This text should be green.</p> +<script> + const root = host.attachShadow({mode:"open"}); + root.innerHTML = ` + <slot style="color:green" name="no-match"></slot> + <slot style="color:red"></slot> + `; + host.offsetTop; + root.querySelector("slot").removeAttribute("name"); + takeScreenshot(); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_safari.yml b/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_safari.yml index 8838108..be18f83 100644 --- a/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_safari.yml +++ b/third_party/blink/web_tests/external/wpt/tools/ci/azure/install_safari.yml
@@ -1,19 +1,19 @@ parameters: channel: preview +# Should match https://web-platform-tests.org/running-tests/safari.html steps: - ${{ if eq(parameters.channel, 'preview') }}: - script: | # This is equivalent to `Homebrew/homebrew-cask-versions/safari-technology-preview`, # but the raw URL is used to bypass caching. HOMEBREW_NO_AUTO_UPDATE=1 brew cask install https://raw.githubusercontent.com/Homebrew/homebrew-cask-versions/master/Casks/safari-technology-preview.rb - # https://web-platform-tests.org/running-tests/safari.html sudo "/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver" --enable - defaults write com.apple.Safari WebKitJavaScriptCanOpenWindowsAutomatically 1 + defaults write com.apple.SafariTechnologyPreview WebKitJavaScriptCanOpenWindowsAutomatically 1 + defaults write com.apple.SafariTechnologyPreview ExperimentalServerTimingEnabled 1 displayName: 'Install Safari Technology Preview' - ${{ if eq(parameters.channel, 'stable') }}: - script: | - # https://web-platform-tests.org/running-tests/safari.html sudo safaridriver --enable defaults write com.apple.Safari WebKitJavaScriptCanOpenWindowsAutomatically 1 displayName: 'Configure Safari'
diff --git a/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus-expected.txt b/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus-expected.txt new file mode 100644 index 0000000..9dfe2ab --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus-expected.txt
@@ -0,0 +1,37 @@ +This test verifies text editor's enabling and disabling tab moves focus behavior + + +Running: testDefaultTabBehavior +Focus is on: +TEXTAREA:Code editor +After pressing tab, focus is on: +TEXTAREA:Code editor +..|function.foo().{ +..var.x.=.11; +..return.x +} + +Running: testEnableTabMovesFocus +Enable tab moves focus and press Tab key +Focus is on: +TEXTAREA:Code editor +After pressing tab, focus is on: +BUTTON:Select an element in the page to inspect it +|function.foo().{ +..var.x.=.11; +..return.x +} +After pressing shift + tab, focus is on: +TEXTAREA:Code editor + +Running: testDisableTabMovesFocus +Disable tab moves focus and press Tab key +Focus is on: +TEXTAREA:Code editor +After pressing tab, focus is on: +TEXTAREA:Code editor +..|function.foo().{ +..var.x.=.11; +..return.x +} +
diff --git a/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus.js b/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus.js new file mode 100644 index 0000000..327b360 --- /dev/null +++ b/third_party/blink/web_tests/http/tests/devtools/editor/text-editor-toggle-tab-moves-focus.js
@@ -0,0 +1,83 @@ +// Copyright 2019 The Chromium 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 verifies text editor's enabling and disabling tab moves focus behavior\n`); + await TestRunner.loadModule('sources_test_runner'); + await TestRunner.showPanel('sources'); + + var textEditor = SourcesTestRunner.createTestEditor(); + textEditor.setMimeType('text/javascript'); + textEditor.setReadOnly(false); + const text = `function foo() { + var x = 11; + return x +}`; + + function dumpFocus() { + var element = document.deepActiveElement(); + if (!element) { + TestRunner.addResult('null'); + return; + } + var name = element.tagName; + if (element.id) + name += '#' + element.id; + if (element.getAttribute('aria-label')) + name += ':' + element.getAttribute('aria-label'); + else if (element.title) + name += ':' + element.title; + else if (element.textContent && element.textContent.length < 50) { + name += ':' + element.textContent.replace('\u200B', ''); + } else if (element.className) + name += '.' + element.className.split(' ').join('.'); + TestRunner.addResult(name); + } + + function setUpTextEditor(text) { + textEditor.setText(text); + textEditor.focus(); + SourcesTestRunner.setLineSelections(textEditor, [{line: 0, column: 0}]); + } + + function pressTabAndDump(next) { + TestRunner.addResult(`Focus is on:`); + dumpFocus(); + eventSender.keyDown('Tab'); + TestRunner.addResult(`After pressing tab, focus is on:`); + dumpFocus(); + SourcesTestRunner.dumpTextWithSelection(textEditor, true); + } + + var testSuite = [ + function testDefaultTabBehavior(next) { + setUpTextEditor(text); + + pressTabAndDump(); + next(); + }, + + function testEnableTabMovesFocus(next) { + setUpTextEditor(text); + + Common.moduleSetting('textEditorTabMovesFocus').set(true); + TestRunner.addResult(`Enable tab moves focus and press Tab key`); + pressTabAndDump(); + eventSender.keyDown('Tab', ['shiftKey']); + TestRunner.addResult(`After pressing shift + tab, focus is on:`); + dumpFocus(); + next(); + }, + + function testDisableTabMovesFocus(next) { + setUpTextEditor(text); + + Common.moduleSetting('textEditorTabMovesFocus').set(false); + TestRunner.addResult(`Disable tab moves focus and press Tab key`); + pressTabAndDump(); + next(); + }, + ]; + TestRunner.runTestSuite(testSuite); +})(); \ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync-expected.txt b/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync-expected.txt deleted file mode 100644 index 4b0cf22..0000000 --- a/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -CONSOLE WARNING: line 8: Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/. -Test behavior of sync XHR during unload - -PASS: sync XHR completed successfully
diff --git a/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync.html b/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync.html deleted file mode 100644 index 051f3f41..0000000 --- a/third_party/blink/web_tests/http/tests/xmlhttprequest/xmlhttprequest-unload-sync.html +++ /dev/null
@@ -1,36 +0,0 @@ -<html> -<body> -<p>Test behavior of sync XHR during unload</p> -<script> -var consoleMessages = document.createElement("ul"); -document.body.appendChild(consoleMessages); - -if (window.testRunner) { - testRunner.waitUntilDone(); - testRunner.dumpAsText(); -} - -function subframeLoaded() -{ - document.getElementById('ifr').contentWindow.location.assign("data:text/html,DONE"); -} - -function completed(msg) -{ - log(msg); - if (window.testRunner) - testRunner.notifyDone(); -} - -function log(message) -{ - var item = document.createElement("li"); - item.appendChild(document.createTextNode(message)); - consoleMessages.appendChild(item); -} -</script> -<div id="framediv"> -<iframe id="ifr" name="ifr" src="resources/xmlhttprequest-in-unload-sync.html"></iframe> -</div> -</body> -</html>
diff --git a/third_party/metrics_proto/README.chromium b/third_party/metrics_proto/README.chromium index 5ce3406..57f1d5c 100644 --- a/third_party/metrics_proto/README.chromium +++ b/third_party/metrics_proto/README.chromium
@@ -1,8 +1,8 @@ Name: Metrics Protos Short Name: metrics_proto URL: This is the canonical public repository -Version: 241818494 -Date: 2019/04/03 UTC +Version: 242980535 +Date: 2019/04/11 UTC License: BSD Security Critical: Yes
diff --git a/third_party/metrics_proto/cast_logs.proto b/third_party/metrics_proto/cast_logs.proto index 9d43c077..8dab9f5 100644 --- a/third_party/metrics_proto/cast_logs.proto +++ b/third_party/metrics_proto/cast_logs.proto
@@ -163,7 +163,7 @@ repeated CastConnectionInfo cast_connection_info = 2; // Stores Cast-enabled device specific events with a various context data. - // Next tag: 22 + // Next tag: 23 message CastEventProto { // The name of the action, hashed by same logic used to hash user action // event and histogram. @@ -229,6 +229,9 @@ // Optional value to log ui version. optional string ui_version = 20; + + // Optional field to log SELINUX audit detail. + optional string selinux_audit_detail = 22; } repeated CastEventProto cast_event = 3;
diff --git a/third_party/metrics_proto/system_profile.proto b/third_party/metrics_proto/system_profile.proto index 43f9ce58..e771ad9 100644 --- a/third_party/metrics_proto/system_profile.proto +++ b/third_party/metrics_proto/system_profile.proto
@@ -80,7 +80,7 @@ optional string application_locale = 4; // Information on the user's operating system. - // Next tag: 7 + // Next tag: 8 message OS { // The user's operating system. This should be one of: // - Android @@ -111,6 +111,21 @@ // ChromeOS and Android, have a kernel version that the OS release version // was built with that differs from the version field above. optional string kernel_version = 6; + + // Information on ChromeOS ARC runtime. This is collected to ease analysis + // on ARC-specific metrics, since this info varies by different boards / + // build configs / releases. + // Next tag: 2 + message Arc { + // Android release number from build.prop "ro.build.version.release", e.g. + // "7.1.1" for N and "9" for P. + optional string release = 1; + } + // Available since M76. This field is reported if current build supports + // ARC, regardless of whether ARC is enabled or not. Check "Arc.State" + // histogram to determine if ARC is enabled for current report. + // Logged on ChromeOS only. + optional Arc arc = 7; } optional OS os = 5;
diff --git a/third_party/webrtc_overrides/rtc_base/event.cc b/third_party/webrtc_overrides/rtc_base/event.cc index 014bc87..f81232c 100644 --- a/third_party/webrtc_overrides/rtc_base/event.cc +++ b/third_party/webrtc_overrides/rtc_base/event.cc
@@ -28,13 +28,13 @@ event_.Reset(); } -bool Event::Wait(int milliseconds) { - if (milliseconds == kForever) { +bool Event::Wait(int give_up_after_ms) { + if (give_up_after_ms == kForever) { event_.Wait(); return true; } - return event_.TimedWait(base::TimeDelta::FromMilliseconds(milliseconds)); + return event_.TimedWait(base::TimeDelta::FromMilliseconds(give_up_after_ms)); } } // namespace rtc
diff --git a/third_party/webrtc_overrides/rtc_base/event.h b/third_party/webrtc_overrides/rtc_base/event.h index 2d290e69..47a34cd 100644 --- a/third_party/webrtc_overrides/rtc_base/event.h +++ b/third_party/webrtc_overrides/rtc_base/event.h
@@ -24,8 +24,11 @@ void Reset(); // Wait for the event to become signaled, for the specified number of - // |milliseconds|. To wait indefinetly, pass kForever. - bool Wait(int milliseconds); + // milliseconds. To wait indefinetly, pass kForever. + bool Wait(int give_up_after_ms); + bool Wait(int give_up_after_ms, int /*warn_after_ms*/) { + return Wait(give_up_after_ms); + } private: base::WaitableEvent event_;
diff --git a/tools/mb/mb.py b/tools/mb/mb.py index e42688f8..e2b1cc1 100755 --- a/tools/mb/mb.py +++ b/tools/mb/mb.py
@@ -613,35 +613,18 @@ return ' '.join(gn_args) def Lookup(self): - vals = self.ReadIOSBotConfig() - if not vals: - self.ReadConfigFile() - config = self.ConfigFromArgs() - if config.startswith('//'): - if not self.Exists(self.ToAbsPath(config)): - raise MBErr('args file "%s" not found' % config) - vals = self.DefaultVals() - vals['args_file'] = config - else: - if not config in self.configs: - raise MBErr('Config "%s" not found in %s' % - (config, self.args.config_file)) - vals = self.FlattenConfig(config) - return vals - - def ReadIOSBotConfig(self): - if not self.args.master or not self.args.builder: - return {} - path = self.PathJoin(self.chromium_src_dir, 'ios', 'build', 'bots', - self.args.master, self.args.builder + '.json') - if not self.Exists(path): - return {} - - contents = json.loads(self.ReadFile(path)) - gn_args = ' '.join(contents.get('gn_args', [])) - - vals = self.DefaultVals() - vals['gn_args'] = gn_args + self.ReadConfigFile() + config = self.ConfigFromArgs() + if config.startswith('//'): + if not self.Exists(self.ToAbsPath(config)): + raise MBErr('args file "%s" not found' % config) + vals = self.DefaultVals() + vals['args_file'] = config + else: + if not config in self.configs: + raise MBErr('Config "%s" not found in %s' % + (config, self.args.config_file)) + vals = self.FlattenConfig(config) return vals def ReadConfigFile(self):
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 77b9db073..3307404 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -21783,6 +21783,7 @@ <action-suffix separator="." ordering="suffix"> <suffix name="Cancel" label="User canceled downloading an offline item."/> <suffix name="MenuDelete" label="User deleted a specific offline item."/> + <suffix name="MenuRename" label="User renamed a specific offline item."/> <suffix name="MenuShare" label="User shared a specific offline item."/> <suffix name="Open" label="User opened an offline item."/> <suffix name="Pause" label="User paused downloading an offline item."/>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index c0ab3bc..98ca28aa 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -1187,6 +1187,7 @@ <int value="4" label="MENU_SHARE"/> <int value="5" label="MENU_DELETE"/> <int value="6" label="RETRY"/> + <int value="7" label="MENU_RENAME"/> </enum> <enum name="Android.DownloadManager.Menu.Actions"> @@ -16478,6 +16479,7 @@ <int value="542" label="SignedHTTPExchangeEnabled"/> <int value="543" label="DeviceQuickFixBuildToken"/> <int value="544" label="ExtensionInstallListsMergeEnabled"/> + <int value="545" label="SamlInSessionPasswordChangeEnabled"/> </enum> <enum name="EnterprisePolicyInvalidations">
diff --git a/ui/base/mpris/mpris_service_impl.cc b/ui/base/mpris/mpris_service_impl.cc index 1ba28f8..76ca36f 100644 --- a/ui/base/mpris/mpris_service_impl.cc +++ b/ui/base/mpris/mpris_service_impl.cc
@@ -212,7 +212,9 @@ void MprisServiceImpl::OnOwnership(const std::string& service_name, bool success) { - DCHECK(success); + if (!success) + return; + service_ready_ = true; for (MprisServiceObserver& obs : observers_) @@ -387,7 +389,7 @@ void MprisServiceImpl::EmitPropertiesChangedSignal( const PropertyMap& changed_properties) { - if (!bus_ || !exported_object_) + if (!bus_ || !exported_object_ || !service_ready_) return; // |signal| follows the PropertiesChanged API:
diff --git a/ui/file_manager/file_manager/cws_widget/cws_widget_container_error_dialog.js b/ui/file_manager/file_manager/cws_widget/cws_widget_container_error_dialog.js index 800dde2d..a065ab2 100644 --- a/ui/file_manager/file_manager/cws_widget/cws_widget_container_error_dialog.js +++ b/ui/file_manager/file_manager/cws_widget/cws_widget_container_error_dialog.js
@@ -2,58 +2,54 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -/** - * @param {HTMLElement} parentNode Node to be parent for this dialog. - * @constructor - * @extends {cr.ui.dialogs.BaseDialog} - */ -function CWSWidgetContainerErrorDialog(parentNode) { - cr.ui.dialogs.BaseDialog.call(this, parentNode); -} - -CWSWidgetContainerErrorDialog.prototype = { - __proto__: cr.ui.dialogs.BaseDialog.prototype -}; - -/** - * Whether the dialog is showm. - * @return {boolean} - */ -CWSWidgetContainerErrorDialog.prototype.shown = function() { - return this.container_.classList.contains('shown'); -}; - -/** - * One-time initialization of DOM. - * @protected - */ -CWSWidgetContainerErrorDialog.prototype.initDom_ = function() { - cr.ui.dialogs.BaseDialog.prototype.initDom_.call(this); - this.frame_.classList.add('cws-widget-error-dialog-frame'); - var img = this.document_.createElement('div'); - img.className = 'cws-widget-error-dialog-img'; - this.frame_.insertBefore(img, this.text_); - - this.title_.hidden = true; - this.closeButton_.hidden = true; - this.cancelButton_.hidden = true; - this.text_.classList.add('cws-widget-error-dialog-text'); - - // Don't allow OK button to lose focus, in order to prevent webview content - // from stealing focus. - // BaseDialog keeps focus by removing all other focusable elements from tab - // order (by setting their tabIndex to -1). This doesn't work for webviews - // because the webview embedder cannot access the webview DOM tree, and thus - // fails to remove elements in the webview from tab order. - this.okButton_.addEventListener('blur', this.refocusOkButton_.bind(this)); -}; - -/** - * Focuses OK button. - * @private - */ -CWSWidgetContainerErrorDialog.prototype.refocusOkButton_ = function() { - if (this.shown()) { - this.okButton_.focus(); +class CWSWidgetContainerErrorDialog extends cr.ui.dialogs.BaseDialog { + /** + * @param {HTMLElement} parentNode Node to be parent for this dialog. + */ + constructor(parentNode) { + super(parentNode); } -}; + + /** + * Whether the dialog is showm. + * @return {boolean} + */ + shown() { + return this.container_.classList.contains('shown'); + } + + /** + * One-time initialization of DOM. + * @protected + */ + initDom_() { + super.initDom_(); + this.frame_.classList.add('cws-widget-error-dialog-frame'); + var img = this.document_.createElement('div'); + img.className = 'cws-widget-error-dialog-img'; + this.frame_.insertBefore(img, this.text_); + + this.title_.hidden = true; + this.closeButton_.hidden = true; + this.cancelButton_.hidden = true; + this.text_.classList.add('cws-widget-error-dialog-text'); + + // Don't allow OK button to lose focus, in order to prevent webview content + // from stealing focus. + // BaseDialog keeps focus by removing all other focusable elements from tab + // order (by setting their tabIndex to -1). This doesn't work for webviews + // because the webview embedder cannot access the webview DOM tree, and thus + // fails to remove elements in the webview from tab order. + this.okButton_.addEventListener('blur', this.refocusOkButton_.bind(this)); + } + + /** + * Focuses OK button. + * @private + */ + refocusOkButton_() { + if (this.shown()) { + this.okButton_.focus(); + } + } +}
diff --git a/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog.js b/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog.js index 977d363..17b7ab9 100644 --- a/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog.js +++ b/ui/file_manager/file_manager/foreground/js/ui/install_linux_package_dialog.js
@@ -29,7 +29,7 @@ // The OK button normally dismisses the dialog, so add a button we can // customize. - this.installButton_ = this.okButton_.cloneNode(); + this.installButton_ = this.okButton_.cloneNode(false /* deep */); this.installButton_.textContent = str('INSTALL_LINUX_PACKAGE_INSTALL_BUTTON'); this.installButton_.addEventListener(
diff --git a/ui/gfx/image/image.cc b/ui/gfx/image/image.cc index d7237707..eecf022 100644 --- a/ui/gfx/image/image.cc +++ b/ui/gfx/image/image.cc
@@ -109,10 +109,8 @@ ImageRepPNG() : ImageRep(Image::kImageRepPNG) { } - ImageRepPNG(const std::vector<ImagePNGRep>& image_png_reps) - : ImageRep(Image::kImageRepPNG), - image_png_reps_(image_png_reps) { - } + explicit ImageRepPNG(const std::vector<ImagePNGRep>& image_png_reps) + : ImageRep(Image::kImageRepPNG), image_png_reps_(image_png_reps) {} ~ImageRepPNG() override {} @@ -125,11 +123,11 @@ if (!size_cache_) { for (auto it = image_reps().begin(); it != image_reps().end(); ++it) { if (it->scale == 1.0f) { - size_cache_.reset(new gfx::Size(it->Size())); + size_cache_ = it->Size(); return *size_cache_; } } - size_cache_.reset(new gfx::Size); + size_cache_ = gfx::Size(); } return *size_cache_; @@ -141,29 +139,29 @@ std::vector<ImagePNGRep> image_png_reps_; // Cached to avoid having to parse the raw data multiple times. - mutable std::unique_ptr<gfx::Size> size_cache_; + mutable base::Optional<gfx::Size> size_cache_; DISALLOW_COPY_AND_ASSIGN(ImageRepPNG); }; class ImageRepSkia : public ImageRep { public: - explicit ImageRepSkia(std::unique_ptr<ImageSkia> image) - : ImageRep(Image::kImageRepSkia), image_(std::move(image)) {} + explicit ImageRepSkia(ImageSkia image) + : ImageRep(Image::kImageRepSkia), image_(image) {} ~ImageRepSkia() override {} - int Width() const override { return image_->width(); } + int Width() const override { return image_.width(); } - int Height() const override { return image_->height(); } + int Height() const override { return image_.height(); } - gfx::Size Size() const override { return image_->size(); } + gfx::Size Size() const override { return image_.size(); } - const ImageSkia* image() const { return image_.get(); } - ImageSkia* image() { return image_.get(); } + const ImageSkia* image() const { return &image_; } + ImageSkia* image() { return &image_; } private: - std::unique_ptr<ImageSkia> image_; + ImageSkia image_; DISALLOW_COPY_AND_ASSIGN(ImageRepSkia); }; @@ -235,7 +233,7 @@ // themselves not threadsafe. class ImageStorage : public base::RefCounted<ImageStorage> { public: - ImageStorage(Image::RepresentationType default_type) + explicit ImageStorage(Image::RepresentationType default_type) : default_representation_type_(default_type) #if defined(OS_MACOSX) && !defined(OS_IOS) , @@ -342,8 +340,7 @@ Image::Image(const ImageSkia& image) { if (!image.isNull()) { storage_ = new internal::ImageStorage(Image::kImageRepSkia); - AddRepresentation(std::make_unique<internal::ImageRepSkia>( - std::make_unique<ImageSkia>(image))); + AddRepresentation(std::make_unique<internal::ImageRepSkia>(image)); } } @@ -422,16 +419,16 @@ const internal::ImageRepCocoaTouch* native_rep = GetRepresentation(kImageRepCocoaTouch, true) ->AsImageRepCocoaTouch(); - scoped_rep.reset(new internal::ImageRepSkia(std::make_unique<ImageSkia>( - ImageSkiaFromUIImage(native_rep->image())))); + scoped_rep.reset(new internal::ImageRepSkia( + ImageSkia(ImageSkiaFromUIImage(native_rep->image())))); break; } #elif defined(OS_MACOSX) case kImageRepCocoa: { const internal::ImageRepCocoa* native_rep = GetRepresentation(kImageRepCocoa, true)->AsImageRepCocoa(); - scoped_rep.reset(new internal::ImageRepSkia(std::make_unique<ImageSkia>( - ImageSkiaFromNSImage(native_rep->image())))); + scoped_rep.reset(new internal::ImageRepSkia( + ImageSkia(ImageSkiaFromNSImage(native_rep->image())))); break; } #endif
diff --git a/ui/gfx/image/image_generic.cc b/ui/gfx/image/image_generic.cc index 9d90008..95432b6 100644 --- a/ui/gfx/image/image_generic.cc +++ b/ui/gfx/image/image_generic.cc
@@ -17,11 +17,11 @@ namespace { // Returns a 16x16 red image to visually show error in decoding PNG. -std::unique_ptr<ImageSkia> GetErrorImageSkia() { +ImageSkia GetErrorImageSkia() { SkBitmap bitmap; bitmap.allocN32Pixels(16, 16); bitmap.eraseARGB(0xff, 0xff, 0, 0); - return std::make_unique<ImageSkia>(ImageSkiaRep(bitmap, 1.0f)); + return ImageSkia(ImageSkiaRep(bitmap, 1.0f)); } class PNGImageSource : public ImageSkiaSource { @@ -90,8 +90,7 @@ } // namespace -std::unique_ptr<ImageSkia> ImageSkiaFromPNG( - const std::vector<ImagePNGRep>& image_png_reps) { +ImageSkia ImageSkiaFromPNG(const std::vector<ImagePNGRep>& image_png_reps) { if (image_png_reps.empty()) return GetErrorImageSkia(); std::unique_ptr<PNGImageSource> image_source(new PNGImageSource); @@ -104,7 +103,7 @@ DCHECK(!size.IsEmpty()); if (size.IsEmpty()) return GetErrorImageSkia(); - return std::make_unique<ImageSkia>(std::move(image_source), size); + return ImageSkia(std::move(image_source), size); } scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia(
diff --git a/ui/gfx/image/image_ios.mm b/ui/gfx/image/image_ios.mm index 1272728..916b218 100644 --- a/ui/gfx/image/image_ios.mm +++ b/ui/gfx/image/image_ios.mm
@@ -109,18 +109,18 @@ return Get1xPNGBytesFromUIImage(image); } -std::unique_ptr<ImageSkia> ImageSkiaFromPNG( +ImageSkia ImageSkiaFromPNG( const std::vector<gfx::ImagePNGRep>& image_png_reps) { // iOS does not expose libpng, so conversion from PNG to ImageSkia must go // through UIImage. - auto image_skia = std::make_unique<gfx::ImageSkia>(); + ImageSkia image_skia; for (size_t i = 0; i < image_png_reps.size(); ++i) { base::scoped_nsobject<UIImage> uiimage( CreateUIImageFromImagePNGRep(image_png_reps[i])); gfx::ImageSkiaRep image_skia_rep = ImageSkiaRepOfScaleFromUIImage( uiimage, image_png_reps[i].scale); if (!image_skia_rep.is_null()) - image_skia->AddRepresentation(image_skia_rep); + image_skia.AddRepresentation(image_skia_rep); } return image_skia; }
diff --git a/ui/gfx/image/image_platform.h b/ui/gfx/image/image_platform.h index 6eeebe3..e77500c 100644 --- a/ui/gfx/image/image_platform.h +++ b/ui/gfx/image/image_platform.h
@@ -46,8 +46,7 @@ gfx::Size NSImageSize(NSImage* image); #endif // defined(OS_MACOSX) -std::unique_ptr<ImageSkia> ImageSkiaFromPNG( - const std::vector<ImagePNGRep>& image_png_reps); +ImageSkia ImageSkiaFromPNG(const std::vector<ImagePNGRep>& image_png_reps); scoped_refptr<base::RefCountedMemory> Get1xPNGBytesFromImageSkia( const ImageSkia* image_skia);
diff --git a/ui/gfx/image/image_unittest.cc b/ui/gfx/image/image_unittest.cc index c25b09ac..b82a941 100644 --- a/ui/gfx/image/image_unittest.cc +++ b/ui/gfx/image/image_unittest.cc
@@ -4,6 +4,8 @@ #include <stddef.h> +#include <utility> + #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkCanvas.h" @@ -575,6 +577,72 @@ EXPECT_EQ(1U, image2.RepresentationCount()); } +TEST_F(ImageTest, Copy_PreservesRepresentation) { + const gfx::Size kSize1x(25, 25); + const gfx::Size kSize2x(50, 50); + std::vector<gfx::ImagePNGRep> image_png_reps; + image_png_reps.push_back( + gfx::ImagePNGRep(gt::CreatePNGBytes(kSize1x.width()), 1.0f)); + image_png_reps.push_back( + gfx::ImagePNGRep(gt::CreatePNGBytes(kSize2x.width()), 2.0f)); + gfx::Image image(image_png_reps); + + gfx::ImageSkia image_skia = image.AsImageSkia(); + EXPECT_EQ(kSize1x, image_skia.size()); + SkISize size = image_skia.GetRepresentation(2.0f).GetBitmap().dimensions(); + EXPECT_EQ(kSize2x, gfx::Size(size.fWidth, size.fHeight)); + + gfx::Image image2(image); + gfx::ImageSkia image_skia2 = image2.AsImageSkia(); + EXPECT_EQ(kSize1x, image_skia2.size()); + size = image_skia2.GetRepresentation(2.0f).GetBitmap().dimensions(); + EXPECT_EQ(kSize2x, gfx::Size(size.fWidth, size.fHeight)); + + EXPECT_TRUE(image_skia.BackedBySameObjectAs(image_skia2)); +} + +TEST_F(ImageTest, Copy_PreventsDuplication) { + const gfx::Size kSize1x(25, 25); + const gfx::Size kSize2x(50, 50); + std::vector<gfx::ImagePNGRep> image_png_reps; + image_png_reps.push_back( + gfx::ImagePNGRep(gt::CreatePNGBytes(kSize1x.width()), 1.0f)); + image_png_reps.push_back( + gfx::ImagePNGRep(gt::CreatePNGBytes(kSize2x.width()), 2.0f)); + gfx::Image image(image_png_reps); + + gfx::Image image2(image); + + gfx::ImageSkia image_skia = image.AsImageSkia(); + EXPECT_EQ(kSize1x, image_skia.size()); + SkISize size = image_skia.GetRepresentation(2.0f).GetBitmap().dimensions(); + EXPECT_EQ(kSize2x, gfx::Size(size.fWidth, size.fHeight)); + + gfx::ImageSkia image_skia2 = image2.AsImageSkia(); + EXPECT_EQ(kSize1x, image_skia2.size()); + size = image_skia2.GetRepresentation(2.0f).GetBitmap().dimensions(); + EXPECT_EQ(kSize2x, gfx::Size(size.fWidth, size.fHeight)); + + EXPECT_TRUE(image_skia.BackedBySameObjectAs(image_skia2)); +} + +TEST_F(ImageTest, Copy_PreservesBackingStore) { + const gfx::Size kSize1x(25, 25); + + gfx::Image image(gt::CreateImageSkia(kSize1x.width(), kSize1x.height())); + gfx::Image image2 = gfx::Image::CreateFrom1xBitmap(image.AsBitmap()); + + gfx::ImageSkia image_skia = image.AsImageSkia(); + gfx::ImageSkia image_skia2 = image2.AsImageSkia(); + + // Because we haven't copied the image representation (scale info, etc.) the + // new Skia image isn't backed by the same object, but it should still contain + // the same bitmap data. + EXPECT_FALSE(image_skia2.BackedBySameObjectAs(image_skia)); + EXPECT_EQ(image_skia.bitmap()->getPixels(), + image_skia2.bitmap()->getPixels()); +} + TEST_F(ImageTest, MultiResolutionImageSkia) { const int kWidth1x = 10; const int kHeight1x = 12;
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py index 843a5d7..1be8d8d 100755 --- a/ui/gl/generate_bindings.py +++ b/ui/gl/generate_bindings.py
@@ -619,8 +619,8 @@ 'arguments': 'GLenum target, GLenum attachment, GLuint texture, GLint level, ' 'GLint layer', }, { 'return_type': 'void', - 'versions': [{'name': 'glFramebufferTextureMultiviewLayeredANGLE', - 'extensions': ['GL_ANGLE_multiview']}], + 'versions': [{'name': 'glFramebufferTextureMultiviewOVR', + 'extensions': ['GL_OVR_multiview2']}], 'arguments': 'GLenum target, GLenum attachment, GLuint texture, GLint level, ' 'GLint baseViewIndex, GLsizei numViews', }, { 'return_type': 'void',
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h index 82213de98..209a524 100644 --- a/ui/gl/gl_bindings.h +++ b/ui/gl/gl_bindings.h
@@ -451,7 +451,7 @@ #define GL_SERVICE_LOG_CODE_BLOCK(code) code #endif -// ANGLE_multiview constants. +// OVR_multiview2 constants. #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR 0x9630 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR 0x9632 #define GL_MAX_VIEWS_OVR 0x9631
diff --git a/ui/gl/gl_bindings_api_autogen_gl.h b/ui/gl/gl_bindings_api_autogen_gl.h index fd648bd..2daabaa 100644 --- a/ui/gl/gl_bindings_api_autogen_gl.h +++ b/ui/gl/gl_bindings_api_autogen_gl.h
@@ -401,12 +401,12 @@ GLuint texture, GLint level, GLint layer) override; -void glFramebufferTextureMultiviewLayeredANGLEFn(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) override; +void glFramebufferTextureMultiviewOVRFn(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) override; void glFrontFaceFn(GLenum mode) override; void glGenBuffersARBFn(GLsizei n, GLuint* buffers) override; void glGenerateMipmapEXTFn(GLenum target) override;
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc index ce23491..beeedfd 100644 --- a/ui/gl/gl_bindings_autogen_gl.cc +++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -289,8 +289,6 @@ gfx::HasExtension(extensions, "GL_ANGLE_instanced_arrays"); ext.b_GL_ANGLE_multi_draw = gfx::HasExtension(extensions, "GL_ANGLE_multi_draw"); - ext.b_GL_ANGLE_multiview = - gfx::HasExtension(extensions, "GL_ANGLE_multiview"); ext.b_GL_ANGLE_request_extension = gfx::HasExtension(extensions, "GL_ANGLE_request_extension"); ext.b_GL_ANGLE_robust_client_memory = @@ -433,6 +431,8 @@ gfx::HasExtension(extensions, "GL_OES_texture_buffer"); ext.b_GL_OES_vertex_array_object = gfx::HasExtension(extensions, "GL_OES_vertex_array_object"); + ext.b_GL_OVR_multiview = gfx::HasExtension(extensions, "GL_OVR_multiview"); + ext.b_GL_OVR_multiview2 = gfx::HasExtension(extensions, "GL_OVR_multiview2"); if (ver->IsAtLeastGL(4u, 1u) || ver->IsAtLeastGLES(3u, 1u)) { fn.glActiveShaderProgramFn = reinterpret_cast<glActiveShaderProgramProc>( @@ -1062,10 +1062,10 @@ GetGLProcAddress("glFramebufferTextureLayer")); } - if (ext.b_GL_ANGLE_multiview) { - fn.glFramebufferTextureMultiviewLayeredANGLEFn = - reinterpret_cast<glFramebufferTextureMultiviewLayeredANGLEProc>( - GetGLProcAddress("glFramebufferTextureMultiviewLayeredANGLE")); + if (ext.b_GL_OVR_multiview2 || ext.b_GL_OVR_multiview) { + fn.glFramebufferTextureMultiviewOVRFn = + reinterpret_cast<glFramebufferTextureMultiviewOVRProc>( + GetGLProcAddress("glFramebufferTextureMultiviewOVR")); } if (ver->IsAtLeastGL(3u, 0u) || ver->is_es) { @@ -3587,13 +3587,13 @@ layer); } -void GLApiBase::glFramebufferTextureMultiviewLayeredANGLEFn(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) { - driver_->fn.glFramebufferTextureMultiviewLayeredANGLEFn( +void GLApiBase::glFramebufferTextureMultiviewOVRFn(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) { + driver_->fn.glFramebufferTextureMultiviewOVRFn( target, attachment, texture, level, baseViewIndex, numViews); } @@ -6892,17 +6892,16 @@ layer); } -void TraceGLApi::glFramebufferTextureMultiviewLayeredANGLEFn( - GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) { - TRACE_EVENT_BINARY_EFFICIENT0( - "gpu", "TraceGLAPI::glFramebufferTextureMultiviewLayeredANGLE") - gl_api_->glFramebufferTextureMultiviewLayeredANGLEFn( - target, attachment, texture, level, baseViewIndex, numViews); +void TraceGLApi::glFramebufferTextureMultiviewOVRFn(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) { + TRACE_EVENT_BINARY_EFFICIENT0("gpu", + "TraceGLAPI::glFramebufferTextureMultiviewOVR") + gl_api_->glFramebufferTextureMultiviewOVRFn(target, attachment, texture, + level, baseViewIndex, numViews); } void TraceGLApi::glFrontFaceFn(GLenum mode) { @@ -10896,20 +10895,19 @@ layer); } -void DebugGLApi::glFramebufferTextureMultiviewLayeredANGLEFn( - GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) { - GL_SERVICE_LOG("glFramebufferTextureMultiviewLayeredANGLE" +void DebugGLApi::glFramebufferTextureMultiviewOVRFn(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) { + GL_SERVICE_LOG("glFramebufferTextureMultiviewOVR" << "(" << GLEnums::GetStringEnum(target) << ", " << GLEnums::GetStringEnum(attachment) << ", " << texture << ", " << level << ", " << baseViewIndex << ", " << numViews << ")"); - gl_api_->glFramebufferTextureMultiviewLayeredANGLEFn( - target, attachment, texture, level, baseViewIndex, numViews); + gl_api_->glFramebufferTextureMultiviewOVRFn(target, attachment, texture, + level, baseViewIndex, numViews); } void DebugGLApi::glFrontFaceFn(GLenum mode) { @@ -15363,14 +15361,13 @@ NoContextHelper("glFramebufferTextureLayer"); } -void NoContextGLApi::glFramebufferTextureMultiviewLayeredANGLEFn( - GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) { - NoContextHelper("glFramebufferTextureMultiviewLayeredANGLE"); +void NoContextGLApi::glFramebufferTextureMultiviewOVRFn(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) { + NoContextHelper("glFramebufferTextureMultiviewOVR"); } void NoContextGLApi::glFrontFaceFn(GLenum mode) {
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h index 2cad1d8..a0241f5 100644 --- a/ui/gl/gl_bindings_autogen_gl.h +++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -462,7 +462,7 @@ GLuint texture, GLint level, GLint layer); -typedef void(GL_BINDING_CALL* glFramebufferTextureMultiviewLayeredANGLEProc)( +typedef void(GL_BINDING_CALL* glFramebufferTextureMultiviewOVRProc)( GLenum target, GLenum attachment, GLuint texture, @@ -1840,7 +1840,6 @@ bool b_GL_ANGLE_framebuffer_multisample; bool b_GL_ANGLE_instanced_arrays; bool b_GL_ANGLE_multi_draw; - bool b_GL_ANGLE_multiview; bool b_GL_ANGLE_request_extension; bool b_GL_ANGLE_robust_client_memory; bool b_GL_ANGLE_translated_shader_source; @@ -1917,6 +1916,8 @@ bool b_GL_OES_mapbuffer; bool b_GL_OES_texture_buffer; bool b_GL_OES_vertex_array_object; + bool b_GL_OVR_multiview; + bool b_GL_OVR_multiview2; }; struct ProcsGL { @@ -2051,8 +2052,7 @@ glFramebufferTexture2DMultisampleEXTProc glFramebufferTexture2DMultisampleEXTFn; glFramebufferTextureLayerProc glFramebufferTextureLayerFn; - glFramebufferTextureMultiviewLayeredANGLEProc - glFramebufferTextureMultiviewLayeredANGLEFn; + glFramebufferTextureMultiviewOVRProc glFramebufferTextureMultiviewOVRFn; glFrontFaceProc glFrontFaceFn; glGenBuffersARBProc glGenBuffersARBFn; glGenerateMipmapEXTProc glGenerateMipmapEXTFn; @@ -2814,13 +2814,12 @@ GLuint texture, GLint level, GLint layer) = 0; - virtual void glFramebufferTextureMultiviewLayeredANGLEFn( - GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) = 0; + virtual void glFramebufferTextureMultiviewOVRFn(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) = 0; virtual void glFrontFaceFn(GLenum mode) = 0; virtual void glGenBuffersARBFn(GLsizei n, GLuint* buffers) = 0; virtual void glGenerateMipmapEXTFn(GLenum target) = 0; @@ -4226,8 +4225,8 @@ ::gl::g_current_gl_context->glFramebufferTexture2DMultisampleEXTFn #define glFramebufferTextureLayer \ ::gl::g_current_gl_context->glFramebufferTextureLayerFn -#define glFramebufferTextureMultiviewLayeredANGLE \ - ::gl::g_current_gl_context->glFramebufferTextureMultiviewLayeredANGLEFn +#define glFramebufferTextureMultiviewOVR \ + ::gl::g_current_gl_context->glFramebufferTextureMultiviewOVRFn #define glFrontFace ::gl::g_current_gl_context->glFrontFaceFn #define glGenBuffersARB ::gl::g_current_gl_context->glGenBuffersARBFn #define glGenerateMipmapEXT ::gl::g_current_gl_context->glGenerateMipmapEXTFn
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc index 99c01875..3f16ef6 100644 --- a/ui/gl/gl_bindings_autogen_mock.cc +++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -1428,16 +1428,15 @@ } void GL_BINDING_CALL -MockGLInterface::Mock_glFramebufferTextureMultiviewLayeredANGLE( - GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) { - MakeGlMockFunctionUnique("glFramebufferTextureMultiviewLayeredANGLE"); - interface_->FramebufferTextureMultiviewLayeredANGLE( - target, attachment, texture, level, baseViewIndex, numViews); +MockGLInterface::Mock_glFramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) { + MakeGlMockFunctionUnique("glFramebufferTextureMultiviewOVR"); + interface_->FramebufferTextureMultiviewOVR(target, attachment, texture, level, + baseViewIndex, numViews); } void GL_BINDING_CALL MockGLInterface::Mock_glFrontFace(GLenum mode) { @@ -5386,9 +5385,9 @@ if (strcmp(name, "glFramebufferTextureLayer") == 0) return reinterpret_cast<GLFunctionPointerType>( Mock_glFramebufferTextureLayer); - if (strcmp(name, "glFramebufferTextureMultiviewLayeredANGLE") == 0) + if (strcmp(name, "glFramebufferTextureMultiviewOVR") == 0) return reinterpret_cast<GLFunctionPointerType>( - Mock_glFramebufferTextureMultiviewLayeredANGLE); + Mock_glFramebufferTextureMultiviewOVR); if (strcmp(name, "glFrontFace") == 0) return reinterpret_cast<GLFunctionPointerType>(Mock_glFrontFace); if (strcmp(name, "glGenBuffers") == 0)
diff --git a/ui/gl/gl_bindings_autogen_mock.h b/ui/gl/gl_bindings_autogen_mock.h index 4473299..1bbf8395 100644 --- a/ui/gl/gl_bindings_autogen_mock.h +++ b/ui/gl/gl_bindings_autogen_mock.h
@@ -608,12 +608,12 @@ GLint level, GLint layer); static void GL_BINDING_CALL -Mock_glFramebufferTextureMultiviewLayeredANGLE(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews); +Mock_glFramebufferTextureMultiviewOVR(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews); static void GL_BINDING_CALL Mock_glFrontFace(GLenum mode); static void GL_BINDING_CALL Mock_glGenBuffers(GLsizei n, GLuint* buffers); static void GL_BINDING_CALL Mock_glGenFencesAPPLE(GLsizei n, GLuint* fences);
diff --git a/ui/gl/gl_mock_autogen_gl.h b/ui/gl/gl_mock_autogen_gl.h index 28e475b..c786528 100644 --- a/ui/gl/gl_mock_autogen_gl.h +++ b/ui/gl/gl_mock_autogen_gl.h
@@ -361,7 +361,7 @@ GLuint texture, GLint level, GLint layer)); -MOCK_METHOD6(FramebufferTextureMultiviewLayeredANGLE, +MOCK_METHOD6(FramebufferTextureMultiviewOVR, void(GLenum target, GLenum attachment, GLuint texture,
diff --git a/ui/gl/gl_stub_autogen_gl.h b/ui/gl/gl_stub_autogen_gl.h index b62f4aa2..175483d 100644 --- a/ui/gl/gl_stub_autogen_gl.h +++ b/ui/gl/gl_stub_autogen_gl.h
@@ -401,12 +401,12 @@ GLuint texture, GLint level, GLint layer) override {} -void glFramebufferTextureMultiviewLayeredANGLEFn(GLenum target, - GLenum attachment, - GLuint texture, - GLint level, - GLint baseViewIndex, - GLsizei numViews) override {} +void glFramebufferTextureMultiviewOVRFn(GLenum target, + GLenum attachment, + GLuint texture, + GLint level, + GLint baseViewIndex, + GLsizei numViews) override {} void glFrontFaceFn(GLenum mode) override {} void glGenBuffersARBFn(GLsizei n, GLuint* buffers) override {} void glGenerateMipmapEXTFn(GLenum target) override {}
diff --git a/ui/ozone/platform/scenic/scenic_window.cc b/ui/ozone/platform/scenic/scenic_window.cc index e26bea4..167369bf 100644 --- a/ui/ozone/platform/scenic/scenic_window.cc +++ b/ui/ozone/platform/scenic/scenic_window.cc
@@ -176,8 +176,8 @@ // Translate the node by half of the view dimensions to put it in the center // of the view. - node_.SetTranslationRH(size_dips_.width() / 2.0, size_dips_.height() / 2.0, - 0.f); + node_.SetTranslation(size_dips_.width() / 2.0, size_dips_.height() / 2.0, + 0.f); // Scale the render node so that surface rect can always be 1x1. render_node_.SetScale(size_dips_.width(), size_dips_.height(), 1.f);
diff --git a/ui/strings/ui_strings.grd b/ui/strings/ui_strings.grd index 0fb031b..ca7f8e9 100644 --- a/ui/strings/ui_strings.grd +++ b/ui/strings/ui_strings.grd
@@ -946,6 +946,14 @@ <message name="IDS_BADGE_UNREAD_NOTIFICATIONS" desc="The accessibility text which will be read by a screen reader when there are notifcatications"> {UNREAD_NOTIFICATIONS, plural, =1 {1 Unread Notification} other {# Unread Notifications}} </message> + + <!-- Send Tab To Self --> + <message name="IDS_SEND_TAB_TO_SELF_INFOBAR_MESSAGE" desc="The message text for the infobar when a user receives a shared tab from another device."> + Received a tab + </message> + <message name="IDS_SEND_TAB_TO_SELF_INFOBAR_MESSAGE_URL" desc="Clickable text displayed as part of a URL in the inforbar displayed when a user receives a shared tab from another device."> + Open + </message> </messages> </release> </grit>
diff --git a/ui/views/controls/slider.cc b/ui/views/controls/slider.cc index 9ddc227..75432a2 100644 --- a/ui/views/controls/slider.cc +++ b/ui/views/controls/slider.cc
@@ -33,12 +33,11 @@ namespace { // Color of slider at the active and the disabled state, respectively. -constexpr SkColor kActiveColor = SkColorSetARGB(0xFF, 0x42, 0x85, 0xF4); -constexpr SkColor kDisabledColor = SkColorSetARGB(0xFF, 0xBD, 0xBD, 0xBD); -constexpr uint8_t kHighlightColorAlpha = 0x4D; +constexpr SkColor kActiveColor = SkColorSetARGB(0xFF, 0x25, 0x81, 0xDF); +constexpr SkColor kDisabledColor = SkColorSetARGB(0x6E, 0xF1, 0xF3, 0xF4); -// Color of the empty portion of the slider -const SkColor kEmptySliderColor = SkColorSetARGB(0xFF, 0xBD, 0xBD, 0xBD); +constexpr uint8_t kActiveColorAlpha = 0x40; +constexpr uint8_t kDisabledColorAlpha = 0x19; // The thickness of the slider. constexpr int kLineThickness = 2; @@ -266,9 +265,10 @@ const int x = content.x() + full + kThumbRadius; const SkColor current_thumb_color = is_active_ ? kActiveColor : kDisabledColor; + const uint8_t current_color_alpha = + is_active_ ? kActiveColorAlpha : kDisabledColorAlpha; const SkColor empty_slider_color = - is_active_ ? kEmptySliderColor - : SkColorSetA(kEmptySliderColor, kHighlightColorAlpha); + SkColorSetA(current_thumb_color, current_color_alpha); // Padding used to adjust space between slider ends and slider thumb. // Value is negative when slider is active so that there is no separation @@ -294,7 +294,7 @@ if (thumb_highlight_radius > kThumbRadius) { cc::PaintFlags highlight; SkColor highlight_color = - SkColorSetA(current_thumb_color, kHighlightColorAlpha); + SkColorSetA(current_thumb_color, current_color_alpha); highlight.setColor(highlight_color); highlight.setAntiAlias(true); canvas->DrawCircle(thumb_center, thumb_highlight_radius, highlight);
diff --git a/ui/webui/resources/js/cr/ui/dialogs.js b/ui/webui/resources/js/cr/ui/dialogs.js index 95d84fe..c404399 100644 --- a/ui/webui/resources/js/cr/ui/dialogs.js +++ b/ui/webui/resources/js/cr/ui/dialogs.js
@@ -18,10 +18,33 @@ // so we can restore it when we're hidden. this.previousActiveElement_ = null; - this.initDom_(); - + // TODO: Rename these protected fields to remove the underscore, to comply + // with the style guide. /** @private{boolean} */ this.showing_ = false; + + /** @protected {?Element} */ + this.container_ = null; + + /** @protected {?Element} */ + this.frame_ = null; + + /** @protected {?Element} */ + this.title_ = null; + + /** @protected {?Element} */ + this.text_ = null; + + /** @protected {?Element} */ + this.closeButton_ = null; + + /** @protected {?Element} */ + this.okButton_ = null; + + /** @protected {?Element} */ + this.cancelButton_ = null; + + this.initDom_(); } /**