diff --git a/DEPS b/DEPS index 49bc735..b2773db 100644 --- a/DEPS +++ b/DEPS
@@ -176,7 +176,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '2af5f573918e2f46a0df5e9ceea380a52de7e45a', + 'v8_revision': '814c68a96da7afea756c9f8aea57244f017bd715', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling swarming_client # and whatever else without interference from each other. @@ -184,7 +184,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling ANGLE # and whatever else without interference from each other. - 'angle_revision': '7f9c9a7fc00143cb5ad26a0bb5cb6950db4a1e58', + 'angle_revision': 'dc98ca69edd0a803eed76e16d650fa69ea5610f0', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -223,11 +223,11 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': 'b75031a26eed8838222ddb3a81bc1672a0e463a8', + 'freetype_revision': '3aaae716b25bd2d3232e279bc05af65cff446dd9', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling HarfBuzz # and whatever else without interference from each other. - 'harfbuzz_revision': 'e637a4b3de2fb8bdbc1b82e822f4a6cc579e794b', + 'harfbuzz_revision': '7cde68f10cdf2c3ff77c1d9077475c0fc034c75c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Emoji Segmenter # and whatever else without interference from each other. @@ -235,7 +235,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': '5758cc96a5f3f0f9f3b6f64b83c4918fd2e523dd', + 'catapult_revision': 'd9164777415c9e1611a038676c2eef56540b120a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -243,7 +243,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '5cb14a4f300bbee3447fb241b57799429492c694', + 'devtools_frontend_revision': '7eee1a626bd162ff8eaa017c6a1f94a83613b6c3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -291,7 +291,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. - 'spv_tools_revision': 'dc59b4b075e957e36cbecf4d754adc9b67ad1c9c', + 'spv_tools_revision': '041f0a02493d2c6fcc0148b0c1d397492dfe0084', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -307,7 +307,7 @@ # 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': 'ae1f25fee85ebf2773b24a0a4f39c160839b1dbb', + 'dawn_revision': '16787735601c0b5fe9b485fb79f6c647a51281fd', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -871,7 +871,7 @@ # Build tools for Chrome OS. Note: This depends on third_party/pyelftools. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '8c6f1f9af3f49004e3ba87220d69e17eabaf1b58', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'fc61fb037d2c47749e2485c383ab86b372b66055', 'condition': 'checkout_linux', }, @@ -1311,7 +1311,7 @@ }, 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'f0d1100a7149dce7efa44e42f9c1f0952e6c9ab0', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '5e3eacac1ca1dcd6f8a18da9a39aeccf48aa13c5', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1512,7 +1512,7 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'dd55f3ca8f2ea716ca917a4aaf36f0729fe902b1', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '7c1fb4156d24a217a497eed6a94ac8cb58e162db', + Var('webrtc_git') + '/src.git' + '@' + 'd6b9b0a1f4132474c737b5e673e380c3d8e12e2c', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -1579,7 +1579,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@c2eeedf4626693915c496f99d25c3fe18529cba9', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@0db29887459d7d2d5509f8f72ee0081b1138fb14', 'condition': 'checkout_src_internal', },
diff --git a/WATCHLISTS b/WATCHLISTS index 6845545e..eafaa7c4 100644 --- a/WATCHLISTS +++ b/WATCHLISTS
@@ -390,7 +390,8 @@ '|base/allocator/partition_allocator/' }, 'blink_html': { - 'filepath': 'third_party/blink/renderer/core/html/' + 'filepath': 'third_party/blink/renderer/core/html/' \ + '|third_party/blink/renderer/core/mathml/' }, 'blink_htmlparser': { 'filepath': 'third_party/blink/renderer/core/html/parser/'
diff --git a/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc b/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc index b8cd99f6..ed064b9 100644 --- a/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc +++ b/android_webview/browser/gfx/skia_output_surface_dependency_webview.cc
@@ -37,6 +37,10 @@ return shared_context_state_ && shared_context_state_->GrContextIsVulkan(); } +bool SkiaOutputSurfaceDependencyWebView::IsUsingDawn() { + return false; +} + gpu::SharedImageManager* SkiaOutputSurfaceDependencyWebView::GetSharedImageManager() { return gpu_service_->shared_image_manager(); @@ -67,6 +71,11 @@ return shared_context_state_->vk_context_provider(); } +viz::DawnContextProvider* +SkiaOutputSurfaceDependencyWebView::GetDawnContextProvider() { + return nullptr; +} + const gpu::GpuPreferences& SkiaOutputSurfaceDependencyWebView::GetGpuPreferences() { return gpu_service_->gpu_preferences();
diff --git a/android_webview/browser/gfx/skia_output_surface_dependency_webview.h b/android_webview/browser/gfx/skia_output_surface_dependency_webview.h index 393faa0..50027fc8 100644 --- a/android_webview/browser/gfx/skia_output_surface_dependency_webview.h +++ b/android_webview/browser/gfx/skia_output_surface_dependency_webview.h
@@ -27,12 +27,14 @@ std::unique_ptr<gpu::SingleTaskSequence> CreateSequence() override; bool IsUsingVulkan() override; + bool IsUsingDawn() override; gpu::SharedImageManager* GetSharedImageManager() override; gpu::SyncPointManager* GetSyncPointManager() override; const gpu::GpuDriverBugWorkarounds& GetGpuDriverBugWorkarounds() override; scoped_refptr<gpu::SharedContextState> GetSharedContextState() override; gpu::raster::GrShaderCache* GetGrShaderCache() override; viz::VulkanContextProvider* GetVulkanContextProvider() override; + viz::DawnContextProvider* GetDawnContextProvider() override; const gpu::GpuPreferences& GetGpuPreferences() override; const gpu::GpuFeatureInfo& GetGpuFeatureInfo() override; gpu::MailboxManager* GetMailboxManager() override;
diff --git a/base/debug/stack_trace_unittest.cc b/base/debug/stack_trace_unittest.cc index 07f51a0..673420f4 100644 --- a/base/debug/stack_trace_unittest.cc +++ b/base/debug/stack_trace_unittest.cc
@@ -31,25 +31,11 @@ typedef testing::Test StackTraceTest; #endif -// TODO(https://crbug.com/999737): Rewrite this test for better clarity and -// correctness. -// Note: On Linux, this test currently only fully works on Debug builds. -// See comments in the #ifdef soup if you intend to change this. -#if defined(OS_WIN) - -// Always fails on Windows: crbug.com/32070 -#define MAYBE_OutputToStream DISABLED_OutputToStream - -#elif defined(OS_FUCHSIA) && defined(OFFICIAL_BUILD) - -// Backtraces aren't supported by Fuchsia release-optimized builds. -#define MAYBE_OutputToStream DISABLED_OutputToStream - -#else -#define MAYBE_OutputToStream OutputToStream -#endif #if !defined(__UCLIBC__) && !defined(_AIX) -TEST_F(StackTraceTest, MAYBE_OutputToStream) { +// StackTrace::OutputToStream() is not implemented under uclibc, nor AIX. +// See https://crbug.com/706728 + +TEST_F(StackTraceTest, OutputToStream) { StackTrace trace; // Dump the trace into a string. @@ -60,76 +46,54 @@ // ToString() should produce the same output. EXPECT_EQ(backtrace_message, trace.ToString()); -#if defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG - // Stack traces require an extra data table that bloats our binaries, - // so they're turned off for release builds. We stop the test here, - // at least letting us verify that the calls don't crash. - return; -#endif // defined(OS_POSIX) && !defined(OS_MACOSX) && NDEBUG - size_t frames_found = 0; - trace.Addresses(&frames_found); - ASSERT_GE(frames_found, 5u) << - "No stack frames found. Skipping rest of test."; + const void* const* addresses = trace.Addresses(&frames_found); + ASSERT_TRUE(addresses); + ASSERT_GT(frames_found, 0u) << "No stack frames found."; + +#if defined(OFFICIAL_BUILD) && defined(OS_POSIX) && !defined(OS_MACOSX) + // Stack traces require an extra data table that bloats our binaries, + // so they're turned off for official builds. Stop the test here, so + // it at least verifies that StackTrace calls don't crash. + return; +#endif // defined(OFFICIAL_BUILD) && defined(OS_POSIX) && !defined(OS_MACOSX) + + ASSERT_GT(frames_found, 5u) << "Too few frames found."; + +#if defined(OS_FUCHSIA) || defined(OS_ANDROID) + // Under Fuchsia and Android, StackTrace emits executable build-Ids and + // address offsets which are symbolized on the test host system, rather than + // being symbolized in-process. + return; +#endif // defined(OS_FUCHSIA) || defined(OS_ANDROID) + +#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) + // Configurations such as ASAN and TSan emit unsymbolized stacks. + return; +#endif // defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) // Check if the output has symbol initialization warning. If it does, fail. ASSERT_EQ(backtrace_message.find("Dumping unresolved backtrace"), - std::string::npos) << - "Unable to resolve symbols. Skipping rest of test."; + std::string::npos) + << "Unable to resolve symbols."; -#if defined(OS_MACOSX) -#if 0 - // Disabled due to -fvisibility=hidden in build config. - - // Symbol resolution via the backtrace_symbol function does not work well - // in OS X. - // See this thread: - // - // http://lists.apple.com/archives/darwin-dev/2009/Mar/msg00111.html - // - // Just check instead that we find our way back to the "start" symbol - // which should be the first symbol in the trace. - // - // TODO(port): Find a more reliable way to resolve symbols. - - // Expect to at least find main. - EXPECT_TRUE(backtrace_message.find("start") != std::string::npos) - << "Expected to find start in backtrace:\n" - << backtrace_message; - -#endif -#elif defined(USE_SYMBOLIZE) - // This branch is for gcc-compiled code, but not Mac due to the - // above #if. // Expect a demangled symbol. - EXPECT_TRUE(backtrace_message.find("testing::Test::Run()") != - std::string::npos) + // Note that Windows Release builds omit the function parameters from the + // demangled stack output, otherwise this could be "testing::Test::Run()". + EXPECT_TRUE(backtrace_message.find("testing::Test::Run") != std::string::npos) << "Expected a demangled symbol in backtrace:\n" << backtrace_message; -#elif 0 - // This is the fall-through case; it used to cover Windows. - // But it's disabled because of varying buildbot configs; - // some lack symbols. - // Expect to at least find main. EXPECT_TRUE(backtrace_message.find("main") != std::string::npos) << "Expected to find main in backtrace:\n" << backtrace_message; -#if defined(OS_WIN) -// MSVC doesn't allow the use of C99's __func__ within C++, so we fake it with -// MSVC's __FUNCTION__ macro. -#define __func__ __FUNCTION__ -#endif - // Expect to find this function as well. // Note: This will fail if not linked with -rdynamic (aka -export_dynamic) EXPECT_TRUE(backtrace_message.find(__func__) != std::string::npos) << "Expected to find " << __func__ << " in backtrace:\n" << backtrace_message; - -#endif // define(OS_MACOSX) } #if !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES) @@ -146,7 +110,7 @@ truncated.Addresses(&count); EXPECT_EQ(2u, count); } -#endif // !defined(OFFICIAL_BUILD) +#endif // !defined(OFFICIAL_BUILD) && !defined(NO_UNWIND_TABLES) // The test is used for manual testing, e.g., to see the raw output. TEST_F(StackTraceTest, DebugOutputToStream) { @@ -194,7 +158,7 @@ trace.ToStringWithPrefix(nullptr); } -#endif // !defined(__UCLIBC__) +#endif // !defined(__UCLIBC__) && !defined(_AIX) #if defined(OS_POSIX) && !defined(OS_ANDROID) #if !defined(OS_IOS)
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1 index 1096166..8cc1458 100644 --- a/build/fuchsia/linux.sdk.sha1 +++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@ -8897393320560678400 \ No newline at end of file +8897362889837801216 \ No newline at end of file
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1 index d9f85a3..640e107 100644 --- a/build/fuchsia/mac.sdk.sha1 +++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@ -8897398712024874704 \ No newline at end of file +8897363254003807056 \ No newline at end of file
diff --git a/cc/paint/paint_canvas.h b/cc/paint/paint_canvas.h index 32918efd..31a736d 100644 --- a/cc/paint/paint_canvas.h +++ b/cc/paint/paint_canvas.h
@@ -18,6 +18,10 @@ class MetafileSkia; } // namespace printing +namespace paint_preview { +class PaintPreviewTracker; +} // namespace paint_preview + namespace cc { class SkottieWrapper; class PaintFlags; @@ -191,12 +195,19 @@ void SetPrintingMetafile(printing::MetafileSkia* metafile) { metafile_ = metafile; } + paint_preview::PaintPreviewTracker* GetPaintPreviewTracker() const { + return tracker_; + } + void SetPaintPreviewTracker(paint_preview::PaintPreviewTracker* tracker) { + tracker_ = tracker; + } // Subclasses can override to handle custom data. virtual void recordCustomData(uint32_t id) {} private: printing::MetafileSkia* metafile_ = nullptr; + paint_preview::PaintPreviewTracker* tracker_ = nullptr; }; class CC_PAINT_EXPORT PaintCanvasAutoRestore {
diff --git a/chrome/android/features/autofill_assistant/BUILD.gn b/chrome/android/features/autofill_assistant/BUILD.gn index 46b44df..93f9df3c 100644 --- a/chrome/android/features/autofill_assistant/BUILD.gn +++ b/chrome/android/features/autofill_assistant/BUILD.gn
@@ -133,6 +133,7 @@ "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginSection.java", "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java", "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataNativeDelegate.java", + "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantInfoPopup.java", "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantPaymentMethodSection.java", "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java", "java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantDateChoiceOptions.java", @@ -214,6 +215,7 @@ "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java", + "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantTextUtilsTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTest.java",
diff --git a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_login.xml b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_login.xml index f3ac4d60..56478b1 100644 --- a/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_login.xml +++ b/chrome/android/features/autofill_assistant/java/res/layout/autofill_assistant_login.xml
@@ -4,14 +4,19 @@ found in the LICENSE file. --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/login_full" + android:id="@+id/login_summary" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:gravity="center_vertical"> <TextView - android:id="@+id/username" + android:id="@+id/label" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.BlackBody"/> + <TextView + android:id="@+id/sublabel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="@style/TextAppearance.BlackBody" /> </LinearLayout> \ No newline at end of file
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantChoiceList.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantChoiceList.java index 67f7cc6..74f7324 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantChoiceList.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantChoiceList.java
@@ -6,6 +6,7 @@ import android.content.Context; import android.content.res.TypedArray; +import android.support.annotation.Nullable; import android.support.v7.widget.GridLayout; import android.util.AttributeSet; import android.view.Gravity; @@ -19,7 +20,7 @@ import android.widget.Space; import android.widget.TextView; -import androidx.annotation.Nullable; +import androidx.annotation.DrawableRes; import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.Callback; @@ -167,6 +168,13 @@ addItem(view, hasEditButton, null, null); } + public void addItem(View view, boolean hasEditButton, + @Nullable Callback<Boolean> itemSelectedListener, + @Nullable Runnable itemEditedListener) { + addItem(view, hasEditButton, itemSelectedListener, itemEditedListener, + R.drawable.ic_edit_24dp, ""); + } + /** * Adds an item to the list. Additional widgets to select and edit the item are created as * necessary. @@ -176,10 +184,12 @@ * @param itemSelectedListener Optional listener which is notified when the item is selected or * deselected. * @param itemEditedListener Optional listener which is notified when the item is edited. + * @param editButtonDrawable The drawable to use for the optional edit button. + * @param editButtonContentDescription The content description for the optional edit button. */ public void addItem(View view, boolean hasEditButton, - @Nullable Callback<Boolean> itemSelectedListener, - @Nullable Runnable itemEditedListener) { + @Nullable Callback<Boolean> itemSelectedListener, @Nullable Runnable itemEditedListener, + @DrawableRes int editButtonDrawable, String editButtonContentDescription) { CompoundButton radioButton = mAllowMultipleChoices ? new CheckBox(getContext()) : new RadioButton(getContext()); radioButton.setPadding(0, 0, mColumnSpacing, 0); @@ -195,7 +205,7 @@ View editButton = null; LinearLayout spacer = null; if (hasEditButton) { - editButton = createEditButton(); + editButton = createEditButton(editButtonDrawable, editButtonContentDescription); editButton.setOnClickListener(unusedView -> { if (itemEditedListener != null) { itemEditedListener.run(); @@ -388,17 +398,19 @@ return lp; } - private View createEditButton() { + private View createEditButton( + @DrawableRes int editButtonDrawable, String editButtonContentDescription) { int editButtonSize = getContext().getResources().getDimensionPixelSize( R.dimen.autofill_assistant_choicelist_edit_button_size); ChromeImageView editButton = new ChromeImageView(getContext()); - editButton.setImageResource(R.drawable.ic_edit_24dp); + editButton.setImageResource(editButtonDrawable); editButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE); editButton.setLayoutParams(new ViewGroup.LayoutParams(editButtonSize, editButtonSize)); LinearLayout editButtonLayout = createMinimumTouchSizeContainer(); editButtonLayout.setGravity(Gravity.CENTER); editButtonLayout.addView(editButton); + editButtonLayout.setContentDescription(editButtonContentDescription); return editButtonLayout; }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java index 3c47bec..c357998 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataModel.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.autofill_assistant.user_data; +import android.support.annotation.Nullable; + import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.chrome.browser.autofill.PersonalDataManager; @@ -248,6 +250,12 @@ set(DELEGATE, delegate); } + /** Creates a simple info popup with a title and some text. */ + @CalledByNative + private static AssistantInfoPopup createInfoPopup(String title, String text) { + return new AssistantInfoPopup(title, text); + } + /** Creates an empty list of login options. */ @CalledByNative private static List<AssistantLoginChoice> createLoginChoiceList() { @@ -256,9 +264,11 @@ /** Appends a login choice to {@code loginChoices}. */ @CalledByNative - private void addLoginChoice(List<AssistantLoginChoice> loginChoices, String identifier, - String label, int priority) { - loginChoices.add(new AssistantLoginChoice(identifier, label, priority)); + private static void addLoginChoice(List<AssistantLoginChoice> loginChoices, String identifier, + String label, String sublabel, String sublabelAccessibilityHint, int priority, + @Nullable AssistantInfoPopup infoPopup) { + loginChoices.add(new AssistantLoginChoice( + identifier, label, sublabel, sublabelAccessibilityHint, priority, infoPopup)); } /** Sets the list of available login choices. */
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java index 8c5a6b8..2a816a86 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantCollectUserDataSection.java
@@ -12,6 +12,7 @@ import android.widget.LinearLayout; import android.widget.TextView; +import androidx.annotation.DrawableRes; import androidx.annotation.Nullable; import org.chromium.base.ApiCompatibilityUtils; @@ -39,7 +40,6 @@ private final int mFullViewResId; private final int mTitleToContentPadding; private final List<Item> mItems; - private final boolean mCanEditItems; protected final Context mContext; protected T mSelectedOption; @@ -69,16 +69,14 @@ * button should be created. * @param listAddButton The string to display in the add button at the bottom of the list. Can * be null if no add button should be created. - * @param canEditItems Whether items can be edited (i.e., show an edit button) or not. */ public AssistantCollectUserDataSection(Context context, ViewGroup parent, int summaryViewResId, int fullViewResId, int titleToContentPadding, @Nullable String titleAddButton, - @Nullable String listAddButton, boolean canEditItems) { + @Nullable String listAddButton) { mContext = context; mFullViewResId = fullViewResId; mItems = new ArrayList<>(); mTitleToContentPadding = titleToContentPadding; - mCanEditItems = canEditItems; LayoutInflater inflater = LayoutInflater.from(context); mSectionExpander = new AssistantVerticalExpander(context, null); @@ -291,7 +289,7 @@ } /** - * Creates a new |Item| from |option|. + * Creates a new item from {@code option}. */ private Item createItem(T option) { View fullView = LayoutInflater.from(mContext).inflate(mFullViewResId, null); @@ -301,48 +299,69 @@ } /** - * Adds |item| to the UI. + * Adds {@code item} to the UI. */ private void addItem(Item item) { mItems.add(item); - mItemsView.addItem(item.mFullView, /*hasEditButton=*/mCanEditItems, selected -> { - if (mIgnoreItemSelectedNotifications || !selected) { - return; - } - mIgnoreItemSelectedNotifications = true; - selectItem(item.mFullView, item.mOption); - mIgnoreItemSelectedNotifications = false; - if (item.mOption.isComplete()) { - // Workaround for Android bug: a layout transition may cause the newly checked - // radiobutton to not render properly. - mSectionExpander.post(() -> mSectionExpander.setExpanded(false)); - } else { - createOrEditItem(item.mOption); - } - }, () -> createOrEditItem(item.mOption)); + boolean canEditOption = canEditOption(item.mOption); + @DrawableRes + int editButtonDrawable = R.drawable.ic_edit_24dp; + String editButtonContentDescription = ""; + if (canEditOption) { + editButtonDrawable = getEditButtonDrawable(item.mOption); + editButtonContentDescription = getEditButtonContentDescription(item.mOption); + } + mItemsView.addItem(item.mFullView, /*hasEditButton=*/canEditOption, + selected + -> { + if (mIgnoreItemSelectedNotifications || !selected) { + return; + } + mIgnoreItemSelectedNotifications = true; + selectItem(item.mFullView, item.mOption); + mIgnoreItemSelectedNotifications = false; + if (item.mOption.isComplete()) { + // Workaround for Android bug: a layout transition may cause the newly + // checked radiobutton to not render properly. + mSectionExpander.post(() -> mSectionExpander.setExpanded(false)); + } else { + createOrEditItem(item.mOption); + } + }, + () + -> createOrEditItem(item.mOption), + /*editButtonDrawable=*/editButtonDrawable, + /*editButtonContentDescription=*/editButtonContentDescription); updateVisibility(); } /** - * Asks the subclass to edit an item or create a new one (if |oldItem| is null). Subclasses - * should call |addOrUpdateItem| when they are done. + * Asks the subclass to edit an item or create a new one (if {@code oldItem} is null). + * Subclasses should call {@code addOrUpdateItem} when they are done. * @param oldItem The item to be edited (null if a new item should be created). */ protected abstract void createOrEditItem(@Nullable T oldItem); /** - * Asks the subclass to update the contents of |fullView|, which was previously created by - * |createFullView|. + * Asks the subclass to update the contents of {@code fullView}, which was previously created by + * {@code createFullView}. */ protected abstract void updateFullView(View fullView, T option); - /** - * Asks the subclass to update the contents of the summary view. - */ + /** Asks the subclass to update the contents of the summary view. */ protected abstract void updateSummaryView(View summaryView, T option); + /** Asks the subclass whether {@code option} should be editable or not. */ + protected abstract boolean canEditOption(T option); + + /** Asks the subclass which drawable to use for {@code option}. */ + protected abstract @DrawableRes int getEditButtonDrawable(T option); + + /** Asks the subclass for the content description of {@code option}. */ + protected abstract String getEditButtonContentDescription(T option); + /** - * For convenience. Hides |view| if it is empty. + * For convenience. Hides {@code view} if it is empty. */ void hideIfEmpty(TextView view) { view.setVisibility(view.length() == 0 ? View.GONE : View.VISIBLE);
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java index c0d37591..c924d43 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantContactDetailsSection.java
@@ -10,6 +10,7 @@ import android.view.ViewGroup; import android.widget.TextView; +import androidx.annotation.DrawableRes; import androidx.annotation.Nullable; import org.chromium.chrome.autofill_assistant.R; @@ -35,7 +36,7 @@ context.getResources().getDimensionPixelSize( R.dimen.autofill_assistant_payment_request_title_padding), context.getString(R.string.payments_add_contact), - context.getString(R.string.payments_add_contact), /*canEditItems=*/true); + context.getString(R.string.payments_add_contact)); setTitle(context.getString(R.string.payments_contact_details_label)); } @@ -104,6 +105,21 @@ contactIncompleteView.setVisibility(contact.isComplete() ? View.GONE : View.VISIBLE); } + @Override + protected boolean canEditOption(AutofillContact contact) { + return true; + } + + @Override + protected @DrawableRes int getEditButtonDrawable(AutofillContact contact) { + return R.drawable.ic_edit_24dp; + } + + @Override + protected String getEditButtonContentDescription(AutofillContact contact) { + return mContext.getString(R.string.payments_edit_contact_details_label); + } + /** * The Chrome profiles have changed externally. This will rebuild the UI with the new/changed * set of profiles, while keeping the selected item if possible.
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantInfoPopup.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantInfoPopup.java new file mode 100644 index 0000000..961fe6f --- /dev/null +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantInfoPopup.java
@@ -0,0 +1,26 @@ +// 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.autofill_assistant.user_data; + +/** + * Represents a simple info popup. + */ +public class AssistantInfoPopup { + private final String mTitle; + private final String mText; + + public AssistantInfoPopup(String title, String text) { + mTitle = title; + mText = text; + } + + public String getTitle() { + return mTitle; + } + + public String getText() { + return mText; + } +}
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginChoice.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginChoice.java index b6ea521..ebc3af0 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginChoice.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginChoice.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.autofill_assistant.user_data; +import android.support.annotation.Nullable; + import org.chromium.chrome.browser.widget.prefeditor.EditableOption; /** @@ -13,18 +15,36 @@ */ public class AssistantLoginChoice extends EditableOption { private final int mPriority; + private final String mSublabelAccessibilityHint; + private final @Nullable AssistantInfoPopup mInfoPopup; + /** * @param identifier The unique identifier of this login choice. * @param label The label to display to the user. + * @param sublabel Optional sublabel to display below the label. + * @param sublabelAccessibilityHint The a11y hint for {@code sublabel}. * @param priority The priority of this login choice (lower value == higher priority). Can be -1 * to indicate default/auto. + * @param infoPopup Optional popup that provides further information for this login choice. */ - public AssistantLoginChoice(String identifier, String label, int priority) { - super(identifier, label, null, null); + public AssistantLoginChoice(String identifier, String label, String sublabel, + String sublabelAccessibilityHint, int priority, + @Nullable AssistantInfoPopup infoPopup) { + super(identifier, label, sublabel, null); mPriority = priority; + mSublabelAccessibilityHint = sublabelAccessibilityHint; + mInfoPopup = infoPopup; } public int getPriority() { return mPriority; } + + public @Nullable AssistantInfoPopup getInfoPopup() { + return mInfoPopup; + } + + public String getSublabelAccessibilityHint() { + return mSublabelAccessibilityHint; + } }
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginSection.java index efb5d61..c1ff99e 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginSection.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantLoginSection.java
@@ -4,13 +4,20 @@ package org.chromium.chrome.browser.autofill_assistant.user_data; +import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO; +import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_NO; + import android.content.Context; +import android.support.annotation.Nullable; import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; -import androidx.annotation.Nullable; +import androidx.annotation.DrawableRes; + +import org.chromium.chrome.autofill_assistant.R; +import org.chromium.ui.UiUtils; import java.util.List; @@ -19,18 +26,23 @@ */ public class AssistantLoginSection extends AssistantCollectUserDataSection<AssistantLoginChoice> { AssistantLoginSection(Context context, ViewGroup parent) { - super(context, parent, - org.chromium.chrome.autofill_assistant.R.layout.autofill_assistant_login, - org.chromium.chrome.autofill_assistant.R.layout.autofill_assistant_login, + super(context, parent, R.layout.autofill_assistant_login, R.layout.autofill_assistant_login, context.getResources().getDimensionPixelSize( org.chromium.chrome.autofill_assistant.R.dimen .autofill_assistant_payment_request_title_padding), - /*titleAddButton=*/null, /*listAddButton=*/null, /*canEditItems=*/false); + /*titleAddButton=*/null, /*listAddButton=*/null); } @Override protected void createOrEditItem(@Nullable AssistantLoginChoice oldItem) { - // Nothing to do, this section currently does not support adding or creating items. + assert oldItem != null; + assert oldItem.getInfoPopup() != null; + + new UiUtils.CompatibleAlertDialogBuilder(mContext, R.style.Theme_Chromium_AlertDialog) + .setTitle(oldItem.getInfoPopup().getTitle()) + .setMessage(oldItem.getInfoPopup().getText()) + .setPositiveButton(R.string.close, (dialog, which) -> {}) + .show(); } @Override @@ -40,9 +52,35 @@ @Override protected void updateSummaryView(View summaryView, AssistantLoginChoice option) { - TextView usernameView = - summaryView.findViewById(org.chromium.chrome.autofill_assistant.R.id.username); - usernameView.setText(option.getLabel()); + TextView labelView = summaryView.findViewById(R.id.label); + labelView.setText(option.getLabel()); + TextView sublabelView = summaryView.findViewById(R.id.sublabel); + if (TextUtils.isEmpty(option.getSublabel())) { + sublabelView.setVisibility(View.GONE); + } else { + sublabelView.setText(option.getSublabel()); + sublabelView.setContentDescription(option.getSublabelAccessibilityHint()); + sublabelView.setImportantForAccessibility( + TextUtils.isEmpty(option.getSublabelAccessibilityHint()) + ? IMPORTANT_FOR_ACCESSIBILITY_NO + : IMPORTANT_FOR_ACCESSIBILITY_AUTO); + } + } + + @Override + protected boolean canEditOption(AssistantLoginChoice choice) { + return choice.getInfoPopup() != null; + } + + @Override + protected @DrawableRes int getEditButtonDrawable(AssistantLoginChoice choice) { + return R.drawable.btn_info; + } + + @Override + protected String getEditButtonContentDescription(AssistantLoginChoice choice) { + // TODO(b/143862732): Send this a11y string from the backend. + return mContext.getString(R.string.learn_more); } /**
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantPaymentMethodSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantPaymentMethodSection.java index caeac64..dc880a5c 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantPaymentMethodSection.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantPaymentMethodSection.java
@@ -12,6 +12,7 @@ import android.widget.ImageView; import android.widget.TextView; +import androidx.annotation.DrawableRes; import androidx.annotation.Nullable; import org.chromium.chrome.autofill_assistant.R; @@ -38,7 +39,7 @@ context.getResources().getDimensionPixelSize( R.dimen.autofill_assistant_payment_request_payment_method_title_padding), context.getString(R.string.payments_add_card), - context.getString(R.string.payments_add_card), /*canEditItems=*/true); + context.getString(R.string.payments_add_card)); setTitle(context.getString(R.string.payments_method_of_payment_label)); } @@ -120,6 +121,21 @@ hideIfEmpty(methodIncompleteView); } + @Override + protected boolean canEditOption(AutofillPaymentInstrument method) { + return true; + } + + @Override + protected @DrawableRes int getEditButtonDrawable(AutofillPaymentInstrument method) { + return R.drawable.ic_edit_24dp; + } + + @Override + protected String getEditButtonContentDescription(AutofillPaymentInstrument method) { + return mContext.getString(R.string.autofill_edit_credit_card); + } + void onProfilesChanged(List<PersonalDataManager.AutofillProfile> profiles) { // TODO(crbug.com/806868): replace suggested billing addresses (remove if necessary). for (PersonalDataManager.AutofillProfile profile : profiles) {
diff --git a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java index 500fff8..196cb5a 100644 --- a/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java +++ b/chrome/android/features/autofill_assistant/java/src/org/chromium/chrome/browser/autofill_assistant/user_data/AssistantShippingAddressSection.java
@@ -10,6 +10,7 @@ import android.view.ViewGroup; import android.widget.TextView; +import androidx.annotation.DrawableRes; import androidx.annotation.Nullable; import org.chromium.chrome.autofill_assistant.R; @@ -34,7 +35,7 @@ context.getResources().getDimensionPixelSize( R.dimen.autofill_assistant_payment_request_title_padding), context.getString(R.string.payments_add_address), - context.getString(R.string.payments_add_address), /*canEditItems=*/true); + context.getString(R.string.payments_add_address)); setTitle(context.getString(R.string.payments_shipping_address_label)); } @@ -93,6 +94,21 @@ methodIncompleteView.setVisibility(address.isComplete() ? View.GONE : View.VISIBLE); } + @Override + protected boolean canEditOption(AutofillAddress address) { + return true; + } + + @Override + protected @DrawableRes int getEditButtonDrawable(AutofillAddress address) { + return R.drawable.ic_edit_24dp; + } + + @Override + protected String getEditButtonContentDescription(AutofillAddress address) { + return mContext.getString(R.string.payments_edit_address); + } + void onProfilesChanged(List<PersonalDataManager.AutofillProfile> profiles) { if (mIgnoreProfileChangeNotifications) { return;
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java index 826e78d..4637459e 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataTestHelper.java
@@ -243,7 +243,7 @@ PersonalDataManager.CreditCard creditCard = new PersonalDataManager.CreditCard("", "https://example.com", true, true, profileName, "4111111111111111", "1111", "12", - "2050", "amex", org.chromium.chrome.autofill_assistant.R.drawable.amex_card, + "2050", "visa", org.chromium.chrome.autofill_assistant.R.drawable.visa_card, CardType.UNKNOWN, billingAddressId, "" /* serverId */); return setCreditCard(creditCard); }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java index 13814c9..f1b973bf 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantCollectUserDataUiTest.java
@@ -54,6 +54,7 @@ import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantCollectUserDataModel; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantDateChoiceOptions; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantDateTime; +import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantInfoPopup; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantLoginChoice; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantTermsAndConditionsState; import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantAdditionalSectionFactory; @@ -503,7 +504,8 @@ model.set(AssistantCollectUserDataModel.VISIBLE, true); model.set(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE, true); model.set(AssistantCollectUserDataModel.AVAILABLE_LOGINS, - Collections.singletonList(new AssistantLoginChoice("id", "Guest", 0))); + Collections.singletonList(new AssistantLoginChoice( + "id", "Guest", "Description of guest checkout", "", 0, null))); }); /* Non-empty sections should not display the 'add' button in their title. */ @@ -554,8 +556,8 @@ "Acme Inc., 123 Main, 90210 Los Angeles, California, Uzbekistan", viewHolder.mShippingSection.getCollapsedView(), viewHolder.mShippingAddressList.getItem(0)); - testLoginDetails("Guest", viewHolder.mLoginsSection.getCollapsedView(), - viewHolder.mLoginList.getItem(0)); + testLoginDetails("Guest", "Description of guest checkout", + viewHolder.mLoginsSection.getCollapsedView(), viewHolder.mLoginList.getItem(0)); /* Check delegate status. */ assertThat(delegate.mPaymentMethod.getCard().getNumber(), is("4111111111111111")); @@ -1101,6 +1103,34 @@ assertThat(delegate.mAdditionalValues.get("loyalty"), is("L-394834")); } + @Test + @MediumTest + public void testLoginSectionInfoPopup() throws Exception { + AssistantCollectUserDataModel model = new AssistantCollectUserDataModel(); + createCollectUserDataCoordinator(model); + AutofillAssistantCollectUserDataTestHelper.MockDelegate delegate = + new AutofillAssistantCollectUserDataTestHelper.MockDelegate(); + + AssistantInfoPopup infoPopup = + new AssistantInfoPopup("Guest checkout", "Text explanation."); + TestThreadUtils.runOnUiThreadBlocking(() -> { + model.set(AssistantCollectUserDataModel.DELEGATE, delegate); + model.set(AssistantCollectUserDataModel.VISIBLE, true); + model.set(AssistantCollectUserDataModel.LOGIN_SECTION_TITLE, "Login options"); + model.set(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE, true); + model.set(AssistantCollectUserDataModel.AVAILABLE_LOGINS, + Collections.singletonList(new AssistantLoginChoice( + "id", "Guest checkout", "", "", 0, infoPopup))); + }); + + onView(withText("Login options")).perform(click()); + onView(withContentDescription(mTestRule.getActivity().getString(R.string.learn_more))) + .perform(click()); + onView(withText("Guest checkout")).check(matches(isDisplayed())); + onView(withText("Text explanation.")).check(matches(isDisplayed())); + onView(withText(mTestRule.getActivity().getString(R.string.close))).perform(click()); + } + private View getPaymentSummaryErrorView(ViewHolder viewHolder) { return viewHolder.mPaymentSection.findViewById(R.id.payment_method_summary) .findViewById(R.id.incomplete_error); @@ -1157,10 +1187,13 @@ .check(matches(not(isDisplayed()))); } - private void testLoginDetails(String expectedLabel, View summaryView, View fullView) { - onView(allOf(withId(R.id.username), isDescendantOfA(is(summaryView)))) + private void testLoginDetails( + String expectedLabel, String expectedSublabel, View summaryView, View fullView) { + onView(allOf(withId(R.id.label), isDescendantOfA(is(summaryView)))) .check(matches(withText(expectedLabel))); - onView(allOf(withId(R.id.username), isDescendantOfA(is(fullView)))) + onView(allOf(withId(R.id.label), isDescendantOfA(is(fullView)))) .check(matches(withText(expectedLabel))); + onView(allOf(withId(R.id.sublabel), isDescendantOfA(is(fullView)))) + .check(matches(withText(expectedSublabel))); } }
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentTest.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentTest.java new file mode 100644 index 0000000..31640c2 --- /dev/null +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantPaymentTest.java
@@ -0,0 +1,125 @@ +// 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.autofill_assistant; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.typeText; +import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.getElementValue; +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.startAutofillAssistant; +import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewMatchesCondition; + +import android.support.test.InstrumentationRegistry; +import android.support.test.filters.MediumTest; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.chrome.autofill_assistant.R; +import org.chromium.chrome.browser.ChromeSwitches; +import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto; +import org.chromium.chrome.browser.autofill_assistant.proto.ChipProto; +import org.chromium.chrome.browser.autofill_assistant.proto.CollectUserDataProto; +import org.chromium.chrome.browser.autofill_assistant.proto.ElementReferenceProto; +import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto; +import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto; +import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto.PresentationProto; +import org.chromium.chrome.browser.autofill_assistant.proto.UseCreditCardProto; +import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; +import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils; +import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.content_public.browser.WebContents; + +import java.util.ArrayList; +import java.util.Collections; + +/** + * Tests autofill assistant payment. + */ +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@RunWith(ChromeJUnit4ClassRunner.class) +public class AutofillAssistantPaymentTest { + @Rule + public CustomTabActivityTestRule mTestRule = new CustomTabActivityTestRule(); + + private static final String TEST_PAGE = "/components/test/data/autofill_assistant/html/" + + "form_target_website.html"; + + private AutofillAssistantCollectUserDataTestHelper mHelper; + + private WebContents getWebContents() { + return mTestRule.getWebContents(); + } + + @Before + public void setUp() throws Exception { + AutofillAssistantPreferencesUtil.setInitialPreferences(true); + mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent( + InstrumentationRegistry.getTargetContext(), + mTestRule.getTestServer().getURL(TEST_PAGE))); + mHelper = new AutofillAssistantCollectUserDataTestHelper(); + } + + /** + * Fill a form with a saved credit card's details and type the CVC when prompted. + */ + @Test + @MediumTest + public void testEnterPayment() throws Exception { + String profileId = mHelper.addDummyProfile("John Doe", "johndoe@gmail.com"); + mHelper.addDummyCreditCard(profileId); + + ArrayList<ActionProto> list = new ArrayList<>(); + list.add((ActionProto) ActionProto.newBuilder() + .setCollectUserData( + CollectUserDataProto.newBuilder() + .setRequestPaymentMethod(true) + .addSupportedBasicCardNetworks("visa") + .setThirdpartyPrivacyNoticeText("3rd party privacy text") + .setRequestTermsAndConditions(false)) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setUseCard(UseCreditCardProto.newBuilder().setFormFieldElement( + ElementReferenceProto.newBuilder().addSelectors("#card_number"))) + .build()); + list.add((ActionProto) ActionProto.newBuilder() + .setPrompt(PromptProto.newBuilder().setMessage("Prompt").addChoices( + PromptProto.Choice.newBuilder())) + .build()); + AutofillAssistantTestScript script = new AutofillAssistantTestScript( + (SupportedScriptProto) SupportedScriptProto.newBuilder() + .setPath("form_target_website.html") + .setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip( + ChipProto.newBuilder().setText("Payment"))) + .build(), + list); + + AutofillAssistantTestService testService = + new AutofillAssistantTestService(Collections.singletonList(script)); + startAutofillAssistant(mTestRule.getActivity(), testService); + + waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed()); + onView(withText("Continue")).perform(click()); + waitUntilViewMatchesCondition(withId(R.id.card_unmask_input), isCompletelyDisplayed()); + onView(withId(R.id.card_unmask_input)).perform(typeText("123")); + onView(withId(R.id.positive_button)).perform(click()); + waitUntilViewMatchesCondition(withText("Prompt"), isCompletelyDisplayed()); + assertThat(getElementValue("name", getWebContents()), is("John Doe")); + assertThat(getElementValue("card_number", getWebContents()), is("4111111111111111")); + assertThat(getElementValue("cv2_number", getWebContents()), is("123")); + assertThat(getElementValue("exp_month", getWebContents()), is("12")); + assertThat(getElementValue("exp_year", getWebContents()), is("2050")); + } +}
diff --git a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java index f3eb13b..4a22608 100644 --- a/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java +++ b/chrome/android/features/autofill_assistant/javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantUiTestUtil.java
@@ -339,4 +339,23 @@ JSONArray values = new JSONArray(javascriptHelper.getJsonResultAndClear()); return new Rect(values.getInt(0), values.getInt(1), values.getInt(2), values.getInt(3)); } + + /** + * Retrieves the value of the specified element. + */ + public static String getElementValue(String elementId, WebContents webContents) + throws Exception { + if (!checkElementExists(elementId, webContents)) { + throw new IllegalArgumentException(elementId + " does not exist"); + } + TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper javascriptHelper = + new TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper(); + javascriptHelper.evaluateJavaScriptForTests(webContents, + "(function() {" + + " return [document.getElementById('" + elementId + "').value]" + + "})()"); + javascriptHelper.waitUntilHasValue(); + JSONArray result = new JSONArray(javascriptHelper.getJsonResultAndClear()); + return result.getString(0); + } }
diff --git a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMetricsRecorder.java b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMetricsRecorder.java index 575f4eb..ad958a0 100644 --- a/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMetricsRecorder.java +++ b/chrome/android/features/keyboard_accessory/internal/java/src/org/chromium/chrome/browser/keyboard_accessory/ManualFillingMetricsRecorder.java
@@ -62,9 +62,6 @@ */ public static void recordSheetTrigger( @AccessoryTabType int tabType, @AccessorySheetTrigger int bucket) { - // TODO(crbug.com/926372): Add metrics capabilities for credit cards. - if (tabType == AccessoryTabType.CREDIT_CARDS) return; - RecordHistogram.recordEnumeratedHistogram( getHistogramForType(UMA_KEYBOARD_ACCESSORY_SHEET_TRIGGERED, tabType), bucket, AccessorySheetTrigger.COUNT);
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java index 9a379a0..84d6396 100644 --- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java +++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShellDelegate.java
@@ -55,7 +55,7 @@ import org.chromium.chrome.browser.help.HelpAndFeedback; import org.chromium.chrome.browser.infobar.InfoBarIdentifier; import org.chromium.chrome.browser.infobar.SimpleConfirmInfoBarBuilder; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModelSelector; @@ -713,7 +713,7 @@ sRegisteredVrAssetsComponent = true; } SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceManager.SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP, + ChromePreferenceKeys.SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP, isDaydreamCurrentViewer); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 712c92e9e..426c617 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -110,7 +110,7 @@ import org.chromium.chrome.browser.omnibox.LocationBar; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.profiles.Profile; @@ -817,7 +817,7 @@ boolean isLegacyMultiWindow = MultiWindowUtils.getInstance().isLegacyMultiWindow(this); if (!isShowingPromo && !mIntentWithEffect && FirstRunStatus.getFirstRunFlowComplete() && preferenceManager.readBoolean( - ChromePreferenceManager.PROMOS_SKIPPED_ON_FIRST_START, false) + ChromePreferenceKeys.PROMOS_SKIPPED_ON_FIRST_START, false) && !VrModuleProvider.getDelegate().isInVr() // VrModuleProvider.getDelegate().isInVr may not return true at this point // even though Chrome is about to enter VR, so we need to also check whether @@ -827,7 +827,7 @@ isShowingPromo = maybeShowPromo(); } else { preferenceManager.writeBoolean( - ChromePreferenceManager.PROMOS_SKIPPED_ON_FIRST_START, true); + ChromePreferenceKeys.PROMOS_SKIPPED_ON_FIRST_START, true); } ToolbarButtonInProductHelpController.create(this, isShowingPromo);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java index b64a0c0..b4cdd05b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/DefaultBrowserInfo.java
@@ -22,7 +22,7 @@ import org.chromium.base.task.AsyncTask; import org.chromium.base.task.BackgroundOnlyAsyncTask; import org.chromium.chrome.R; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.content_public.browser.BrowserStartupController; @@ -105,7 +105,7 @@ && TextUtils.equals( context.getPackageName(), info.activityInfo.packageName); SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceManager.CHROME_DEFAULT_BROWSER, isDefault); + ChromePreferenceKeys.CHROME_DEFAULT_BROWSER, isDefault); // Check if there is a default handler for the Intent. If so, store its // label.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java index eea641d9..e90a53d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ClearDataDialogResultRecorder.java
@@ -4,8 +4,8 @@ package org.chromium.chrome.browser.browserservices; -import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_CLEAR_DATA; -import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_UNINSTALL; +import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_CLEAR_DATA; +import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_UNINSTALL; import org.chromium.base.StrictModeContext; import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java b/chrome/android/java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java index a261aa70..3f433ce 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/component_updater/VrAssetsComponentInstaller.java
@@ -6,7 +6,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; /** Java-side implementation of the VrAssetsComponentInstaller. */ @@ -15,6 +15,6 @@ @CalledByNative private static boolean shouldRegisterOnStartup() { return SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP, false); + ChromePreferenceKeys.SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP, false); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index e7a0718..1a993fe 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -22,7 +22,7 @@ import org.chromium.chrome.browser.contextmenu.ChromeContextMenuItem.Item; import org.chromium.chrome.browser.firstrun.FirstRunStatus; import org.chromium.chrome.browser.locale.LocaleManager; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory; import org.chromium.chrome.browser.share.LensUtils; @@ -430,7 +430,7 @@ } catch (URISyntaxException ignore) { } if (SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.CHROME_DEFAULT_BROWSER, false) + ChromePreferenceKeys.CHROME_DEFAULT_BROWSER, false) && addNewEntries) { if (mDelegate.isIncognitoSupported()) { tab.add(0, new ChromeContextMenuItem(Item.OPEN_IN_CHROME_INCOGNITO_TAB));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/device/DeviceClassManager.java b/chrome/android/java/src/org/chromium/chrome/browser/device/DeviceClassManager.java index 38e38da..6d212f08 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/device/DeviceClassManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/device/DeviceClassManager.java
@@ -7,7 +7,7 @@ import org.chromium.base.CommandLine; import org.chromium.base.SysUtils; import org.chromium.chrome.browser.ChromeSwitches; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.ui.base.DeviceFormFactor; @@ -97,7 +97,7 @@ if (getInstance().mEnableAccessibilityLayout) return true; if (!AccessibilityUtil.isAccessibilityEnabled()) return false; return SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.ACCESSIBILITY_TAB_SWITCHER, true); + ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER, true); } /** @@ -114,7 +114,7 @@ if (!getInstance().mEnableAnimations) return false; if (!AccessibilityUtil.isAccessibilityEnabled()) return true; return !SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.ACCESSIBILITY_TAB_SWITCHER, true); + ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER, true); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java b/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java index f8d6af2..556572f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/flags/FeatureUtilities.java
@@ -26,7 +26,7 @@ import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.device.DeviceClassManager; import org.chromium.chrome.browser.firstrun.FirstRunUtils; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.ui.base.DeviceFormFactor; @@ -698,7 +698,7 @@ } SharedPreferencesManager.getInstance().writeString( - ChromePreferenceManager.REACHED_CODE_PROFILER_GROUP_KEY, + ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP_KEY, FieldTrialList.findFullName(ChromeFeatureList.REACHED_CODE_PROFILER)); } @@ -709,7 +709,7 @@ public static String getReachedCodeProfilerTrialGroup() { if (sReachedCodeProfilerTrialGroup == null) { sReachedCodeProfilerTrialGroup = SharedPreferencesManager.getInstance().readString( - ChromePreferenceManager.REACHED_CODE_PROFILER_GROUP_KEY, ""); + ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP_KEY, ""); } return sReachedCodeProfilerTrialGroup;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java index 55c03df..438316d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/instantapps/InstantAppsHandler.java
@@ -21,7 +21,7 @@ import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.ShortcutHelper; import org.chromium.chrome.browser.externalnav.ExternalNavigationDelegateImpl; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.util.IntentUtils; @@ -332,7 +332,7 @@ /** @return Whether Chrome is the default browser on the device. */ private boolean isChromeDefaultHandler(Context context) { return SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.CHROME_DEFAULT_BROWSER, false); + ChromePreferenceKeys.CHROME_DEFAULT_BROWSER, false); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java index 7e976ef1..8347a78 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/metrics/WebApkUma.java
@@ -18,7 +18,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.task.AsyncTask; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.util.ConversionUtils; import org.chromium.chrome.browser.webapps.WebApkDistributor; @@ -128,8 +128,8 @@ /** Makes recordings that were deferred in order to not load native. */ public static void recordDeferredUma() { SharedPreferencesManager preferencesManager = SharedPreferencesManager.getInstance(); - Set<String> uninstalledPackages = preferencesManager.readStringSet( - ChromePreferenceManager.WEBAPK_UNINSTALLED_PACKAGES); + Set<String> uninstalledPackages = + preferencesManager.readStringSet(ChromePreferenceKeys.WEBAPK_UNINSTALLED_PACKAGES); if (uninstalledPackages.isEmpty()) return; long fallbackUninstallTimestamp = System.currentTimeMillis(); @@ -152,7 +152,7 @@ } } preferencesManager.writeStringSet( - ChromePreferenceManager.WEBAPK_UNINSTALLED_PACKAGES, new HashSet<String>()); + ChromePreferenceKeys.WEBAPK_UNINSTALLED_PACKAGES, new HashSet<String>()); // TODO(http://crbug.com/1000312): Clear WebappDataStorage for uninstalled WebAPK. } @@ -160,7 +160,7 @@ /** Sets WebAPK uninstall to be recorded next time that native is loaded. */ public static void deferRecordWebApkUninstalled(String packageName) { SharedPreferencesManager.getInstance().addToStringSet( - ChromePreferenceManager.WEBAPK_UNINSTALLED_PACKAGES, packageName); + ChromePreferenceKeys.WEBAPK_UNINSTALLED_PACKAGES, packageName); String webApkId = WebappRegistry.webApkIdForPackage(packageName); WebappRegistry.warmUpSharedPrefsForId(webApkId); WebappDataStorage webappDataStorage =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java index 0a234ba3..d95a22ee 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateController.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.night_mode; -import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY; +import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY; import android.support.v7.app.AppCompatDelegate; import android.text.TextUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java index efb7a631..6c31e8d 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/NightModeUtils.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.night_mode; -import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY; +import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY; import android.app.Activity; import android.content.Context;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java index 694a7d9..856edab 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/night_mode/WebContentsDarkModeController.java
@@ -4,7 +4,7 @@ package org.chromium.chrome.browser.night_mode; -import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.DARKEN_WEBSITES_ENABLED_KEY; +import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.DARKEN_WEBSITES_ENABLED_KEY; import android.text.TextUtils;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java index b5f10c81..ceea573 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/SignInPromo.java
@@ -13,6 +13,7 @@ import org.chromium.base.ContextUtils; import org.chromium.base.VisibleForTesting; import org.chromium.chrome.R; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.ChromePreferenceManager; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.signin.ProfileDataCache; @@ -109,7 +110,7 @@ public static boolean shouldCreatePromo() { return !sDisablePromoForTests && !SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false) + ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false) && !getSuppressionStatus(); } @@ -165,7 +166,7 @@ updateVisibility(); SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, true); + ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, true); final @StringRes int promoHeader = mSigninPromoController.getDescriptionStringId();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java index a7f739c..715152c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/omaha/UpdateStatusProvider.java
@@ -40,7 +40,7 @@ import org.chromium.chrome.browser.omaha.inline.InlineUpdateControllerFactory; import org.chromium.chrome.browser.omaha.metrics.UpdateSuccessMetrics; import org.chromium.chrome.browser.omaha.metrics.UpdateSuccessMetrics.UpdateType; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.util.ConversionUtils; import org.chromium.content_public.browser.UiThreadTaskTraits; @@ -205,7 +205,7 @@ } SharedPreferencesManager.getInstance().writeString( - ChromePreferenceManager.LATEST_UNSUPPORTED_VERSION, currentlyUsedVersion); + ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION, currentlyUsedVersion); mStatus.latestUnsupportedVersion = currentlyUsedVersion; pingObservers(); } @@ -409,7 +409,7 @@ case UpdateState.UNSUPPORTED_OS_VERSION: status.latestUnsupportedVersion = SharedPreferencesManager.getInstance().readString( - ChromePreferenceManager.LATEST_UNSUPPORTED_VERSION, null); + ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION, null); break; } @@ -430,11 +430,11 @@ allowedToUpdate ? UpdateState.UPDATE_AVAILABLE : UpdateState.NONE; SharedPreferencesManager.getInstance().removeKey( - ChromePreferenceManager.LATEST_UNSUPPORTED_VERSION); + ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION); } else if (!VersionNumberGetter.isCurrentOsVersionSupported()) { status.updateState = UpdateState.UNSUPPORTED_OS_VERSION; status.latestUnsupportedVersion = SharedPreferencesManager.getInstance().readString( - ChromePreferenceManager.LATEST_UNSUPPORTED_VERSION, null); + ChromePreferenceKeys.LATEST_UNSUPPORTED_VERSION, null); } else { status.updateState = UpdateState.NONE; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/AccessibilityPreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/AccessibilityPreferences.java index ef467b0c..91faeafd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/AccessibilityPreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/AccessibilityPreferences.java
@@ -69,11 +69,11 @@ ChromeBaseCheckBoxPreference mAccessibilityTabSwitcherPref = (ChromeBaseCheckBoxPreference) findPreference( - ChromePreferenceManager.ACCESSIBILITY_TAB_SWITCHER); + ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER); if (AccessibilityUtil.isAccessibilityEnabled()) { mAccessibilityTabSwitcherPref.setChecked( SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.ACCESSIBILITY_TAB_SWITCHER, true)); + ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER, true)); } else { getPreferenceScreen().removePreference(mAccessibilityTabSwitcherPref); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java index ca5cd42..b47348f49 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceManager.java
@@ -11,9 +11,10 @@ import java.util.Set; /** - * ChromePreferenceManager stores and retrieves various values in Android shared preferences. + * ChromePreferenceManager stores and retrieves values in Android shared preferences for specific + * features. * - * TODO(crbug.com/1022107): Finish moving constants to ChromePreferenceKeys. + * TODO(crbug.com/1022102): Finish moving feature-specific methods out of this class and delete it. */ public class ChromePreferenceManager { // For new int values with a default of 0, just document the key and its usage, and call @@ -21,208 +22,6 @@ // For new boolean values, document the key and its usage, call #readBoolean and #writeBoolean // directly. While calling #readBoolean, default value is required. - /** - * Whether the promotion for data reduction has been skipped on first invocation. - * Default value is false. - */ - public static final String PROMOS_SKIPPED_ON_FIRST_START = "promos_skipped_on_first_start"; - private static final String SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION = - "signin_promo_last_shown_chrome_version"; - private static final String SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES = - "signin_promo_last_shown_account_names"; - - /** - * This value was used prior to KitKat to keep existing low-end devices on the normal UI rather - * than the simplified UI. - * - * This value may still exist in shared preferences file. Do not reuse. - */ - @Deprecated - public static final String ALLOW_LOW_END_DEVICE_UI = "allow_low_end_device_ui"; - - @Deprecated - private static final String PREF_WEBSITE_SETTINGS_FILTER = "website_settings_filter"; - - /** - * Whether Chrome is set as the default browser. - * Default value is false. - */ - public static final String CHROME_DEFAULT_BROWSER = "applink.chrome_default_browser"; - - /** - * Deprecated in M70. This value may still exist in the shared preferences file. Do not reuse. - * TODO(twellington): Remove preference from the file in a future pref cleanup effort. - */ - @Deprecated - private static final String CHROME_MODERN_DESIGN_ENABLED_KEY = "chrome_modern_design_enabled"; - - /** - * Whether or not the home page button is force enabled. - * Default value is false. - */ - @Deprecated - public static final String HOME_PAGE_BUTTON_FORCE_ENABLED_KEY = - "home_page_button_force_enabled"; - - /** - * Whether or not the homepage tile will be shown. - * Default value is false. - */ - @Deprecated - public static final String HOMEPAGE_TILE_ENABLED_KEY = "homepage_tile_enabled"; - - /** - * Whether or not the new tab page button is enabled. - * Default value is false. - */ - @Deprecated - public static final String NTP_BUTTON_ENABLED_KEY = "ntp_button_enabled"; - - /** - * Deprecated in M71. This value may still exist in the shared preferences file. Do not reuse. - * TODO(twellington): Remove preference from the file in a future pref cleanup effort. - */ - @Deprecated - private static final String NTP_BUTTON_VARIANT_KEY = "ntp_button_variant"; - - /** - * Deprecated in M77. This value may still exist in shared preferences file. Do not reuse. - */ - @Deprecated - public static final String TAB_PERSISTENT_STORE_TASK_RUNNER_ENABLED_KEY = - "tab_persistent_store_task_runner_enabled"; - - /** - * Deprecated in M75. This value may still exist in shared preferences file. Do not reuse. - */ - @Deprecated - private static final String INFLATE_TOOLBAR_ON_BACKGROUND_THREAD_KEY = - "inflate_toolbar_on_background_thread"; - - /** - * The current theme setting in the user settings. - * Default value is -1. Use NightModeUtils#getThemeSetting() to retrieve current setting or - * default theme. - */ - public static final String UI_THEME_SETTING_KEY = "ui_theme_setting"; - - /** - * Whether or not darken websites is enabled. - * Default value is false. - */ - public static final String DARKEN_WEBSITES_ENABLED_KEY = "darken_websites_enabled"; - - /** - * Marks that the content suggestions surface has been shown. - * Default value is false. - */ - public static final String CONTENT_SUGGESTIONS_SHOWN_KEY = "content_suggestions_shown"; - - /** - * Whether the user dismissed the personalized sign in promo from the Settings. - * Default value is false. - */ - public static final String SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED = - "settings_personalized_signin_promo_dismissed"; - /** - * Whether the user dismissed the personalized sign in promo from the new tab page. - * Default value is false. - */ - public static final String NTP_SIGNIN_PROMO_DISMISSED = - "ntp.personalized_signin_promo_dismissed"; - - private static final String NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START = - "ntp.signin_promo_suppression_period_start"; - - private static final String SUCCESS_UPLOAD_SUFFIX = "_crash_success_upload"; - private static final String FAILURE_UPLOAD_SUFFIX = "_crash_failure_upload"; - - /** - * Deprecated in M76. This value may still exist in the shared preferences file. Do not reuse. - */ - @Deprecated - public static final String SOLE_INTEGRATION_ENABLED_KEY = "sole_integration_enabled"; - - private static final String VERIFIED_DIGITAL_ASSET_LINKS = - "verified_digital_asset_links"; - private static final String TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES = - "trusted_web_activity_disclosure_accepted_packages"; - - /** - * Whether VR assets component should be registered on startup. - * Default value is false. - */ - public static final String SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP = - "should_register_vr_assets_component_on_startup"; - - /* - * Whether the simplified tab switcher is enabled when accessibility mode is enabled. Keep in - * sync with accessibility_preferences.xml. - * Default value is true. - */ - public static final String ACCESSIBILITY_TAB_SWITCHER = "accessibility_tab_switcher"; - - /** - * When the user is shown a badge that the current Android OS version is unsupported, and they - * tap it to display the menu (which has additional information), we store the current version - * of Chrome to this preference to ensure we only show the badge once. The value is cleared - * if the Chrome version later changes. - */ - public static final String LATEST_UNSUPPORTED_VERSION = "android_os_unsupported_chrome_version"; - - /** - * Keys for deferred recording of the outcomes of showing the clear data dialog after - * Trusted Web Activity client apps are uninstalled or have their data cleared. - */ - public static final String TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_UNINSTALL = - "twa_dialog_number_of_dismissals_on_uninstall"; - public static final String TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_CLEAR_DATA = - "twa_dialog_number_of_dismissals_on_clear_data"; - - /** Key for deferred recording of WebAPK uninstalls. */ - @Deprecated - public static final String WEBAPK_NUMBER_OF_UNINSTALLS = "webapk_number_of_uninstalls"; - - /** Key for deferred recording of list of uninstalled WebAPK packages. */ - public static final String WEBAPK_UNINSTALLED_PACKAGES = "webapk_uninstalled_packages"; - - /** - * Key for whether it allows to start in service manager only mode. - * Default value is false. - */ - public static final String ALLOW_STARTING_SERVICE_MANAGER_ONLY_KEY = - "allow_starting_service_manager_only"; - - /** - * Deprecated keys for Chrome Home. - */ - @Deprecated - private static final String CHROME_HOME_USER_ENABLED_KEY = "chrome_home_user_enabled"; - @Deprecated - private static final String CHROME_HOME_OPT_OUT_SNACKBAR_SHOWN = - "chrome_home_opt_out_snackbar_shown"; - @Deprecated - public static final String CHROME_HOME_INFO_PROMO_SHOWN_KEY = "chrome_home_info_promo_shown"; - @Deprecated - public static final String CHROME_HOME_SHARED_PREFERENCES_KEY = "chrome_home_enabled_date"; - - /** - * Contains a trial group that was used to determine whether the reached code profiler should be - * enabled. - */ - public static final String REACHED_CODE_PROFILER_GROUP_KEY = "reached_code_profiler_group"; - - /** - * Key to cache whether offline indicator v2 (persistent offline indicator) is enabled. - */ - public static final String OFFLINE_INDICATOR_V2_ENABLED_KEY = "offline_indicator_v2_enabled"; - - /** - * Previously used to migrate {@link PrefServiceBridge} preferences to current version. - */ - @Deprecated - private static final String MIGRATION_PREF_KEY = "PrefMigrationVersion"; - private static class LazyHolder { static final ChromePreferenceManager INSTANCE = new ChromePreferenceManager(); } @@ -259,7 +58,7 @@ } private String successUploadKey(@ProcessType String process) { - return process.toLowerCase(Locale.US) + SUCCESS_UPLOAD_SUFFIX; + return process.toLowerCase(Locale.US) + ChromePreferenceKeys.SUCCESS_UPLOAD_SUFFIX; } /** @@ -278,7 +77,7 @@ } private String failureUploadKey(@ProcessType String process) { - return process.toLowerCase(Locale.US) + FAILURE_UPLOAD_SUFFIX; + return process.toLowerCase(Locale.US) + ChromePreferenceKeys.FAILURE_UPLOAD_SUFFIX; } /** @@ -286,14 +85,14 @@ * isn't known. */ public int getSigninPromoLastShownVersion() { - return mManager.readInt(SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION); + return mManager.readInt(ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION); } /** * Sets Chrome major version number when signin promo was last shown. */ public void setSigninPromoLastShownVersion(int majorVersion) { - mManager.writeInt(SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION, majorVersion); + mManager.writeInt(ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION, majorVersion); } /** @@ -301,14 +100,16 @@ * or null if promo hasn't been shown yet. */ public Set<String> getSigninPromoLastAccountNames() { - return mManager.readStringSet(SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES, null); + return mManager.readStringSet( + ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES, null); } /** * Stores a set of account names on the device when signin promo is shown. */ public void setSigninPromoLastAccountNames(Set<String> accountNames) { - mManager.writeStringSet(SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES, accountNames); + mManager.writeStringSet( + ChromePreferenceKeys.SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES, accountNames); } /** @@ -317,7 +118,7 @@ * @return the epoch time in milliseconds (see {@link System#currentTimeMillis()}). */ public long getNewTabPageSigninPromoSuppressionPeriodStart() { - return mManager.readLong(NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START); + return mManager.readLong(ChromePreferenceKeys.NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START); } /** @@ -326,7 +127,8 @@ * @param timeMillis the epoch time in milliseconds (see {@link System#currentTimeMillis()}). */ public void setNewTabPageSigninPromoSuppressionPeriodStart(long timeMillis) { - mManager.writeLong(NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START, timeMillis); + mManager.writeLong( + ChromePreferenceKeys.NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START, timeMillis); } /** @@ -334,7 +136,7 @@ * Tab Page are no longer suppressed. */ public void clearNewTabPageSigninPromoSuppressionPeriodStart() { - mManager.removeKey(NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START); + mManager.removeKey(ChromePreferenceKeys.NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START); } /** @@ -344,7 +146,8 @@ public Set<String> getVerifiedDigitalAssetLinks() { // From the official docs, modifying the result of a SharedPreferences.getStringSet can // cause bad things to happen including exceptions or ruining the data. - return new HashSet<>(mManager.readStringSet(VERIFIED_DIGITAL_ASSET_LINKS)); + return new HashSet<>( + mManager.readStringSet(ChromePreferenceKeys.VERIFIED_DIGITAL_ASSET_LINKS)); } /** @@ -352,12 +155,13 @@ * Can be retrieved by {@link #getVerifiedDigitalAssetLinks()}. */ public void setVerifiedDigitalAssetLinks(Set<String> links) { - mManager.writeStringSet(VERIFIED_DIGITAL_ASSET_LINKS, links); + mManager.writeStringSet(ChromePreferenceKeys.VERIFIED_DIGITAL_ASSET_LINKS, links); } /** Do not modify the set returned by this method. */ private Set<String> getTrustedWebActivityDisclosureAcceptedPackages() { - return mManager.readStringSet(TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES); + return mManager.readStringSet( + ChromePreferenceKeys.TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES); } /** @@ -365,7 +169,9 @@ * TWAs launched by the given package. */ public void setUserAcceptedTwaDisclosureForPackage(String packageName) { - mManager.addToStringSet(TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES, packageName); + mManager.addToStringSet( + ChromePreferenceKeys.TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES, + packageName); } /** @@ -374,7 +180,8 @@ */ public void removeTwaDisclosureAcceptanceForPackage(String packageName) { mManager.removeFromStringSet( - TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES, packageName); + ChromePreferenceKeys.TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES, + packageName); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java index e237af0..d38b57f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/sync/SignInPreference.java
@@ -16,7 +16,7 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.chrome.R; import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.ManagedPreferencesUtils; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.signin.DisplayableProfileData; @@ -168,7 +168,7 @@ } boolean personalizedPromoDismissed = SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED, false); + ChromePreferenceKeys.SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED, false); if (!mPersonalizedPromoEnabled || personalizedPromoDismissed) { setupGenericPromo(); return; @@ -280,7 +280,7 @@ SigninPromoUtil.setupPromoViewFromCache( mSigninPromoController, mProfileDataCache, signinPromoView, () -> { SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceManager.SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED, + ChromePreferenceKeys.SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED, true); update(); });
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java index 21c1c60f..abad6cd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/themes/ThemePreferences.java
@@ -4,8 +4,8 @@ package org.chromium.chrome.browser.preferences.themes; -import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.DARKEN_WEBSITES_ENABLED_KEY; -import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY; +import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.DARKEN_WEBSITES_ENABLED_KEY; +import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY; import android.os.Build; import android.os.Bundle;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsMetrics.java index f4e1fbf..5dfbe3cf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsMetrics.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsMetrics.java
@@ -13,7 +13,7 @@ import org.chromium.chrome.browser.ntp.snippets.CategoryInt; import org.chromium.chrome.browser.ntp.snippets.FaviconFetchResult; import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; @@ -30,10 +30,10 @@ public static void recordSurfaceVisible() { if (!SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.CONTENT_SUGGESTIONS_SHOWN_KEY, false)) { + ChromePreferenceKeys.CONTENT_SUGGESTIONS_SHOWN_KEY, false)) { RecordUserAction.record("Suggestions.FirstTimeSurfaceVisible"); SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceManager.CONTENT_SUGGESTIONS_SHOWN_KEY, true); + ChromePreferenceKeys.CONTENT_SUGGESTIONS_SHOWN_KEY, true); } RecordUserAction.record("Suggestions.SurfaceVisible");
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java index d837a44..d3e59bd 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarTablet.java
@@ -33,7 +33,7 @@ import org.chromium.chrome.browser.omnibox.LocationBar; import org.chromium.chrome.browser.omnibox.LocationBarTablet; import org.chromium.chrome.browser.partnercustomizations.HomepageManager; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.toolbar.HomeButton; @@ -715,6 +715,6 @@ private boolean isAccessibilityTabSwitcherPreferenceEnabled() { return SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.ACCESSIBILITY_TAB_SWITCHER, true); + ChromePreferenceKeys.ACCESSIBILITY_TAB_SWITCHER, true); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java index ec760b52..a992618 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java
@@ -22,7 +22,7 @@ import org.chromium.chrome.browser.browserservices.permissiondelegation.TrustedWebActivityPermissionStore; import org.chromium.chrome.browser.browsing_data.UrlFilter; import org.chromium.chrome.browser.browsing_data.UrlFilterBridge; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.content_public.browser.UiThreadTaskTraits; import org.chromium.webapk.lib.common.WebApkConstants; @@ -300,7 +300,7 @@ // Do not delete WebappDataStorage if we still need it for UKM logging. Set<String> webApkPackagesWithPendingUkm = SharedPreferencesManager.getInstance().readStringSet( - ChromePreferenceManager.WEBAPK_UNINSTALLED_PACKAGES); + ChromePreferenceKeys.WEBAPK_UNINSTALLED_PACKAGES); if (webApkPackagesWithPendingUkm.contains(webApkPackageName)) return false; return !PackageUtils.isPackageInstalled(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java index 1c799db..bd960f1 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ReachedCodeProfilerTest.java
@@ -14,7 +14,7 @@ import org.chromium.base.BaseSwitches; import org.chromium.base.test.ReachedCodeProfiler; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.test.ChromeActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; @@ -105,7 +105,7 @@ mActivityTestRule.startMainActivityFromLauncher(); Assert.assertEquals(FAKE_GROUP_NAME, SharedPreferencesManager.getInstance().readString( - ChromePreferenceManager.REACHED_CODE_PROFILER_GROUP_KEY, null)); + ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP_KEY, null)); } /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/BackgroundSyncTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/BackgroundSyncTest.java index 346c448..094cb976 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/BackgroundSyncTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/background_sync/BackgroundSyncTest.java
@@ -28,7 +28,6 @@ import org.chromium.base.ContextUtils; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.Feature; import org.chromium.chrome.browser.ChromeActivity; import org.chromium.chrome.browser.ChromeSwitches; @@ -93,7 +92,7 @@ // Note that this should be done before the startMainActivityOnBlankPage(), because Chrome // will otherwise run this check on startup and disable BackgroundSync code. if (!ExternalAuthUtils.canUseGooglePlayServices()) { - mNativeLibraryTestRule.loadNativeLibraryAndInitBrowserProcess(); + mNativeLibraryTestRule.loadNativeLibraryNoBrowserProcess(); disableGooglePlayServicesVersionCheck(); } @@ -114,7 +113,6 @@ @Test @MediumTest @Feature({"BackgroundSync"}) - @DisabledTest(message = "crbug.com/1015055") public void onSyncCalledWithNetworkConnectivity() throws Exception { forceConnectionType(ConnectionType.CONNECTION_NONE); @@ -148,7 +146,6 @@ @Test @MediumTest @Feature({"BackgroundSync"}) - @DisabledTest(message = "crbug.com/1015055") public void browserWakeUpScheduledWhenSyncEventFails() throws Exception { forceConnectionType(ConnectionType.CONNECTION_NONE);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java index e2cfe5c..609847a 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/MockContextForLayout.java
@@ -5,11 +5,8 @@ package org.chromium.chrome.browser.compositor.layouts; import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; +import android.content.ContextWrapper; import android.content.res.Resources; -import android.os.Looper; -import android.test.mock.MockContext; import android.test.mock.MockResources; /** @@ -17,13 +14,12 @@ * It points to a {@link MockResources} for anything that is based on xml configurations. For * everything else the standard provided Context should be sufficient. */ -public class MockContextForLayout extends MockContext { - private final Context mValidContext; +public class MockContextForLayout extends ContextWrapper { private final MockResourcesForLayout mResources; private final Resources.Theme mTheme; public MockContextForLayout(Context validContext) { - mValidContext = validContext; + super(validContext); mResources = new MockResourcesForLayout(validContext.getResources()); mTheme = mResources.newTheme(); } @@ -34,37 +30,12 @@ } @Override - public ApplicationInfo getApplicationInfo() { - return mValidContext.getApplicationInfo(); - } - - @Override - public Object getSystemService(String name) { - return mValidContext.getSystemService(name); - } - - @Override - public PackageManager getPackageManager() { - return mValidContext.getPackageManager(); - } - - @Override public Context getApplicationContext() { return this; } @Override - public int checkCallingOrSelfPermission(String permission) { - return mValidContext.checkCallingOrSelfPermission(permission); - } - - @Override - public Looper getMainLooper() { - return mValidContext.getMainLooper(); - } - - @Override public Resources.Theme getTheme() { return mTheme; } -} \ No newline at end of file +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java index 98e8d2cb1..9f24203 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/feed/FeedNewTabPageTest.java
@@ -45,7 +45,7 @@ import org.chromium.chrome.browser.ChromeSwitches; import org.chromium.chrome.browser.ntp.cards.SignInPromo; import org.chromium.chrome.browser.ntp.snippets.SectionHeader; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; @@ -178,10 +178,10 @@ @Feature({"FeedNewTabPage"}) public void testSignInPromo_DismissBySwipe() { boolean dismissed = SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false); + ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false); if (dismissed) { SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false); + ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false); } // Verify that sign-in promo is displayed initially. @@ -205,7 +205,7 @@ // Reset state. SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, dismissed); + ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, dismissed); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java index 50e441ab..4b72fa05 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/night_mode/NightModeTestUtils.java
@@ -9,7 +9,7 @@ import org.chromium.base.test.params.ParameterProvider; import org.chromium.base.test.params.ParameterSet; import org.chromium.chrome.browser.flags.FeatureUtilities; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.preferences.themes.ThemePreferences; import org.chromium.chrome.test.ui.DummyUiActivity; @@ -65,8 +65,7 @@ * @param nightModeEnabled Whether night mode should be enabled. */ public static void setUpNightModeForChromeActivity(boolean nightModeEnabled) { - SharedPreferencesManager.getInstance().writeInt( - ChromePreferenceManager.UI_THEME_SETTING_KEY, + SharedPreferencesManager.getInstance().writeInt(ChromePreferenceKeys.UI_THEME_SETTING_KEY, nightModeEnabled ? ThemePreferences.ThemeSetting.DARK : ThemePreferences.ThemeSetting.LIGHT); } @@ -79,7 +78,6 @@ FeatureUtilities.setNightModeAvailableForTesting(null); NightModeUtils.setNightModeSupportedForTesting(null); GlobalNightModeStateProviderHolder.resetInstanceForTesting(); - SharedPreferencesManager.getInstance().removeKey( - ChromePreferenceManager.UI_THEME_SETTING_KEY); + SharedPreferencesManager.getInstance().removeKey(ChromePreferenceKeys.UI_THEME_SETTING_KEY); } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/themes/ThemePreferencesTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/themes/ThemePreferencesTest.java index e12851a..ac99e361b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/themes/ThemePreferencesTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/themes/ThemePreferencesTest.java
@@ -5,7 +5,7 @@ package org.chromium.chrome.browser.preferences.themes; import static org.chromium.chrome.browser.ChromeFeatureList.ANDROID_NIGHT_MODE; -import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY; +import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java index 3719d30..e118921 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateControllerTest.java
@@ -15,7 +15,7 @@ import static org.chromium.base.ApplicationState.HAS_RUNNING_ACTIVITIES; import static org.chromium.base.ApplicationState.HAS_STOPPED_ACTIVITIES; -import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY; +import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY; import android.os.Build;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java index ef67633..20e3137 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/night_mode/GlobalNightModeStateProviderHolderTest.java
@@ -7,7 +7,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.chromium.chrome.browser.preferences.ChromePreferenceManager.UI_THEME_SETTING_KEY; +import static org.chromium.chrome.browser.preferences.ChromePreferenceKeys.UI_THEME_SETTING_KEY; import org.junit.After; import org.junit.Test;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java index 82b3336..5f04c20 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -68,6 +68,7 @@ import org.chromium.chrome.browser.ntp.snippets.KnownCategories; import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.ChromePreferenceManager; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.preferences.PrefServiceBridge; @@ -339,7 +340,7 @@ public void tearDown() { CardsVariationParameters.setTestVariationParams(null); SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false); + ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false); ChromePreferenceManager.getInstance().clearNewTabPageSigninPromoSuppressionPeriodStart(); PrefServiceBridge.setInstanceForTesting(null); ShadowPostTask.reset(); @@ -1042,7 +1043,7 @@ when(mMockSigninManager.isSignInAllowed()).thenReturn(true); when(mMockIdentityManager.hasPrimaryAccount()).thenReturn(false); SharedPreferencesManager.getInstance().writeBoolean( - ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false); + ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false); useArticleCategory(); final int signInPromoPosition = mAdapter.getFirstPositionForType(ItemViewType.PROMO); @@ -1054,7 +1055,7 @@ verify(itemDismissedCallback).onResult(anyString()); assertFalse(isSignInPromoVisible()); assertTrue(SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false)); + ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false)); reloadNtp(); assertFalse(isSignInPromoVisible()); }
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn index d11ed97..dc2162b 100644 --- a/chrome/app/BUILD.gn +++ b/chrome/app/BUILD.gn
@@ -421,7 +421,6 @@ "//components/autofill/content/common/mojom", "//components/contextual_search/content/common/mojom", "//components/data_reduction_proxy/core/common:interfaces", - "//components/dom_distiller/content/common/mojom", "//components/metrics/public/mojom:call_stack_mojo_bindings", "//components/page_load_metrics/common:page_load_metrics_mojom", "//components/rappor/public/mojom",
diff --git a/chrome/app/DEPS b/chrome/app/DEPS index 7dccaf51..c119c34 100644 --- a/chrome/app/DEPS +++ b/chrome/app/DEPS
@@ -56,7 +56,6 @@ "+components/chromeos_camera/common", "+components/contextual_search/content/common", "+components/data_reduction_proxy/core/common", - "+components/dom_distiller/content/common", "+components/metrics/public", "+components/rappor/public", "+components/translate/content/common",
diff --git a/chrome/app/chrome_content_browser_overlay_manifest.cc b/chrome/app/chrome_content_browser_overlay_manifest.cc index b19b1c70..20e3d67 100644 --- a/chrome/app/chrome_content_browser_overlay_manifest.cc +++ b/chrome/app/chrome_content_browser_overlay_manifest.cc
@@ -26,7 +26,6 @@ #include "components/autofill/content/common/mojom/autofill_driver.mojom.h" #include "components/contextual_search/content/common/mojom/contextual_search_js_api_service.mojom.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy.mojom.h" -#include "components/dom_distiller/content/common/mojom/distiller_javascript_service.mojom.h" #include "components/metrics/public/mojom/call_stack_profile_collector.mojom.h" #include "components/page_load_metrics/common/page_load_metrics.mojom.h" #include "components/rappor/public/mojom/rappor_recorder.mojom.h" @@ -157,7 +156,6 @@ cros::mojom::CameraAppDeviceProvider, #endif contextual_search::mojom::ContextualSearchJsApiService, - dom_distiller::mojom::DistillerJavaScriptService, #if BUILDFLAG(ENABLE_EXTENSIONS) extensions::KeepAlive, extensions::mime_handler::BeforeUnloadControl,
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 8143e61..7273eaf5 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -1981,6 +1981,7 @@ "//components/data_use_measurement/core:ascriber", "//components/device_event_log", "//components/dom_distiller/content/browser", + "//components/dom_distiller/content/common/mojom", "//components/domain_reliability", "//components/download/content/factory", "//components/download/database",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 487508e..2e4f95eddc 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1709,6 +1709,10 @@ kOsCrOS, FEATURE_VALUE_TYPE( chromeos::features::kBluetoothAggressiveAppearanceFilter)}, + {"cryptauth-v1-devicesync-deprecate", + flag_descriptions::kCryptAuthV1DeviceSyncDeprecateName, + flag_descriptions::kCryptAuthV1DeviceSyncDeprecateDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kCryptAuthV1DeviceSyncDeprecate)}, {"cryptauth-v2-device-activity-status", flag_descriptions::kCryptAuthV2DeviceActivityStatusName, flag_descriptions::kCryptAuthV2DeviceActivityStatusDescription, kOsCrOS, @@ -3012,10 +3016,9 @@ flag_descriptions::kEnableOutOfBlinkCorsDescription, kOsAll, FEATURE_VALUE_TYPE(network::features::kOutOfBlinkCors)}, - {"cross-origin-embedder-policy", - flag_descriptions::kCrossOriginEmbedderPolicyName, - flag_descriptions::kCrossOriginEmbedderPolicyDescription, kOsAll, - FEATURE_VALUE_TYPE(network::features::kCrossOriginEmbedderPolicy)}, + {"cross-origin-isolation", flag_descriptions::kCrossOriginIsolationName, + flag_descriptions::kCrossOriginIsolationDescription, kOsAll, + FEATURE_VALUE_TYPE(network::features::kCrossOriginIsolation)}, {"disable-keepalive-fetch", flag_descriptions::kDisableKeepaliveFetchName, flag_descriptions::kDisableKeepaliveFetchDescription, kOsAll,
diff --git a/chrome/browser/android/autofill_assistant/ui_controller_android.cc b/chrome/browser/android/autofill_assistant/ui_controller_android.cc index dd3b50f..3f519bd 100644 --- a/chrome/browser/android/autofill_assistant/ui_controller_android.cc +++ b/chrome/browser/android/autofill_assistant/ui_controller_android.cc
@@ -116,6 +116,33 @@ env, base::android::ConvertUTF8ToJavaString(env, color_string)); } +// Creates the Java equivalent to |login_choices|. +base::android::ScopedJavaLocalRef<jobject> CreateJavaLoginChoiceList( + JNIEnv* env, + const std::vector<LoginChoice>& login_choices) { + auto jlist = Java_AssistantCollectUserDataModel_createLoginChoiceList(env); + for (const auto& login_choice : login_choices) { + base::android::ScopedJavaLocalRef<jobject> jinfo_popup = nullptr; + if (login_choice.info_popup.has_value()) { + jinfo_popup = Java_AssistantCollectUserDataModel_createInfoPopup( + env, + base::android::ConvertUTF8ToJavaString( + env, login_choice.info_popup->title()), + base::android::ConvertUTF8ToJavaString( + env, login_choice.info_popup->text())); + } + Java_AssistantCollectUserDataModel_addLoginChoice( + env, jlist, + base::android::ConvertUTF8ToJavaString(env, login_choice.identifier), + base::android::ConvertUTF8ToJavaString(env, login_choice.label), + base::android::ConvertUTF8ToJavaString(env, login_choice.sublabel), + base::android::ConvertUTF8ToJavaString( + env, login_choice.sublabel_accessibility_hint), + login_choice.preselect_priority, jinfo_popup); + } + return jlist; +} + // Creates the java equivalent to the text inputs specified in |section|. base::android::ScopedJavaLocalRef<jobject> CreateJavaTextInputsForSection( JNIEnv* env, @@ -888,14 +915,8 @@ base::android::ToJavaArrayOfStrings( env, collect_user_data_options->supported_basic_card_networks)); if (collect_user_data_options->request_login_choice) { - auto jlist = Java_AssistantCollectUserDataModel_createLoginChoiceList(env); - for (const auto& login_choice : collect_user_data_options->login_choices) { - Java_AssistantCollectUserDataModel_addLoginChoice( - env, jmodel, jlist, - base::android::ConvertUTF8ToJavaString(env, login_choice.identifier), - base::android::ConvertUTF8ToJavaString(env, login_choice.label), - login_choice.preselect_priority); - } + auto jlist = CreateJavaLoginChoiceList( + env, collect_user_data_options->login_choices); Java_AssistantCollectUserDataModel_setLoginChoices(env, jmodel, jlist); } Java_AssistantCollectUserDataModel_setRequestDateRange(
diff --git a/chrome/browser/android/background_sync_launcher_android.cc b/chrome/browser/android/background_sync_launcher_android.cc index 1a6626b..8189768 100644 --- a/chrome/browser/android/background_sync_launcher_android.cc +++ b/chrome/browser/android/background_sync_launcher_android.cc
@@ -82,7 +82,6 @@ // static void BackgroundSyncLauncherAndroid::SetPlayServicesVersionCheckDisabledForTests( bool disabled) { - DCHECK_CURRENTLY_ON(BrowserThread::UI); disable_play_services_version_check_for_tests = disabled; }
diff --git a/chrome/browser/android/dom_distiller/distiller_ui_handle_android.cc b/chrome/browser/android/dom_distiller/distiller_ui_handle_android.cc index fa3154e..a78d025 100644 --- a/chrome/browser/android/dom_distiller/distiller_ui_handle_android.cc +++ b/chrome/browser/android/dom_distiller/distiller_ui_handle_android.cc
@@ -8,6 +8,7 @@ #include "chrome/android/chrome_jni_headers/DomDistillerUIUtils_jni.h" #include "chrome/browser/ui/android/view_android_helper.h" #include "components/dom_distiller/core/url_utils.h" +#include "content/public/browser/render_frame_host.h" #include "content/public/browser/web_contents.h" #include "ui/android/window_android.h" #include "url/gurl.h" @@ -18,10 +19,12 @@ namespace android { -// static -void DistillerUIHandleAndroid::OpenSettings( - content::WebContents* web_contents) { +void DistillerUIHandleAndroid::OpenSettings() { JNIEnv* env = base::android::AttachCurrentThread(); + + DCHECK(render_frame_host_); + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost(render_frame_host_); Java_DomDistillerUIUtils_openSettings(env, web_contents->GetJavaWebContents()); }
diff --git a/chrome/browser/android/dom_distiller/distiller_ui_handle_android.h b/chrome/browser/android/dom_distiller/distiller_ui_handle_android.h index 0045e744..f79b3ea 100644 --- a/chrome/browser/android/dom_distiller/distiller_ui_handle_android.h +++ b/chrome/browser/android/dom_distiller/distiller_ui_handle_android.h
@@ -6,8 +6,11 @@ #define CHROME_BROWSER_ANDROID_DOM_DISTILLER_DISTILLER_UI_HANDLE_ANDROID_H_ #include "base/macros.h" -#include "components/dom_distiller/content/browser/distiller_ui_handle.h" -#include "content/public/browser/web_contents.h" +#include "components/dom_distiller/core/distiller_ui_handle.h" + +namespace content { +class RenderFrameHost; +} namespace dom_distiller { @@ -18,9 +21,13 @@ DistillerUIHandleAndroid() {} ~DistillerUIHandleAndroid() override {} - void OpenSettings(content::WebContents* web_contents) override; + void set_render_frame_host(content::RenderFrameHost* host) { + render_frame_host_ = host; + } + void OpenSettings() override; private: + content::RenderFrameHost* render_frame_host_ = nullptr; DISALLOW_COPY_AND_ASSIGN(DistillerUIHandleAndroid); };
diff --git a/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc b/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc index 16af4395..2dc59d7 100644 --- a/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc +++ b/chrome/browser/background_sync/background_sync_controller_impl_unittest.cc
@@ -6,6 +6,7 @@ #include <stdint.h> +#include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/macros.h" #include "chrome/browser/engagement/site_engagement_score.h" @@ -63,10 +64,12 @@ void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + base::FilePath sub_dir = + temp_dir_.GetPath().AppendASCII("BackgroundSyncTest"); + ASSERT_TRUE(base::CreateDirectory(sub_dir)); + HistoryServiceFactory::GetInstance()->SetTestingFactory( - &profile_, base::BindRepeating( - &BuildTestHistoryService, - temp_dir_.GetPath().AppendASCII("BackgroundSyncTest"))); + &profile_, base::BindRepeating(&BuildTestHistoryService, sub_dir)); controller_ = std::make_unique<BackgroundSyncControllerImpl>(&profile_); } @@ -94,10 +97,10 @@ } content::BrowserTaskEnvironment task_environment_; + base::ScopedTempDir temp_dir_; TestingProfile profile_; std::unique_ptr<BackgroundSyncControllerImpl> controller_; std::unique_ptr<base::FieldTrialList> field_trial_list_; - base::ScopedTempDir temp_dir_; DISALLOW_COPY_AND_ASSIGN(BackgroundSyncControllerImplTest); };
diff --git a/chrome/browser/chrome_browser_interface_binders.cc b/chrome/browser/chrome_browser_interface_binders.cc index 6b1cc8d..f1b14d8 100644 --- a/chrome/browser/chrome_browser_interface_binders.cc +++ b/chrome/browser/chrome_browser_interface_binders.cc
@@ -11,13 +11,17 @@ #include "chrome/browser/accessibility/accessibility_labels_service.h" #include "chrome/browser/accessibility/accessibility_labels_service_factory.h" #include "chrome/browser/content_settings/content_settings_manager_impl.h" +#include "chrome/browser/dom_distiller/dom_distiller_service_factory.h" #include "chrome/browser/navigation_predictor/navigation_predictor.h" #include "chrome/browser/prerender/prerender_contents.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ssl/insecure_sensitive_input_driver_factory.h" #include "chrome/common/prerender.mojom.h" #include "components/dom_distiller/content/browser/distillability_driver.h" +#include "components/dom_distiller/content/browser/distiller_javascript_service_impl.h" #include "components/dom_distiller/content/common/mojom/distillability_service.mojom.h" +#include "components/dom_distiller/content/common/mojom/distiller_javascript_service.mojom.h" +#include "components/dom_distiller/core/dom_distiller_service.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/render_frame_host.h" #include "content/public/browser/render_process_host.h" @@ -37,6 +41,7 @@ #endif // BUILDFLAG(ENABLE_UNHANDLED_TAP) #if defined(OS_ANDROID) +#include "chrome/browser/android/dom_distiller/distiller_ui_handle_android.h" #include "content/public/browser/web_contents.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "third_party/blink/public/mojom/installedapp/installed_app_provider.mojom.h" @@ -97,6 +102,23 @@ driver->CreateDistillabilityService(std::move(receiver)); } +void BindDistillerJavaScriptService( + content::RenderFrameHost* const frame_host, + mojo::PendingReceiver<dom_distiller::mojom::DistillerJavaScriptService> + receiver) { + dom_distiller::DomDistillerService* dom_distiller_service = + dom_distiller::DomDistillerServiceFactory::GetForBrowserContext( + content::WebContents::FromRenderFrameHost(frame_host) + ->GetBrowserContext()); + auto* distiller_ui_handle = dom_distiller_service->GetDistillerUIHandle(); +#if defined(OS_ANDROID) + static_cast<dom_distiller::android::DistillerUIHandleAndroid*>( + distiller_ui_handle) + ->set_render_frame_host(frame_host); +#endif + CreateDistillerJavaScriptService(distiller_ui_handle, std::move(receiver)); +} + void BindPrerenderCanceler( content::RenderFrameHost* frame_host, mojo::PendingReceiver<mojom::PrerenderCanceler> receiver) { @@ -157,6 +179,9 @@ map->Add<dom_distiller::mojom::DistillabilityService>( base::BindRepeating(&BindDistillabilityService)); + map->Add<dom_distiller::mojom::DistillerJavaScriptService>( + base::BindRepeating(&BindDistillerJavaScriptService)); + map->Add<mojom::PrerenderCanceler>( base::BindRepeating(&BindPrerenderCanceler));
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 8e200cf..43cb024 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -2013,6 +2013,8 @@ "printing/printer_metrics_provider.h", "printing/printers_map.cc", "printing/printers_map.h", + "printing/printers_model_type_controller.cc", + "printing/printers_model_type_controller.h", "printing/printers_sync_bridge.cc", "printing/printers_sync_bridge.h", "printing/server_printers_fetcher.cc", @@ -2122,6 +2124,8 @@ "smb_client/temp_file_manager.h", "startup_settings_cache.cc", "startup_settings_cache.h", + "sync/os_preferences_model_type_controller.cc", + "sync/os_preferences_model_type_controller.h", "system/automatic_reboot_manager.cc", "system/automatic_reboot_manager.h", "system/automatic_reboot_manager_observer.h", @@ -2935,21 +2939,8 @@ "../ui/webui/settings/chromeos/device_keyboard_handler_unittest.cc", "../ui/webui/settings/chromeos/internet_handler_unittest.cc", "../ui/webui/settings/chromeos/multidevice_handler_unittest.cc", - "//components/drive/change_list_processor_unittest.cc", - "//components/drive/chromeos/file_cache_unittest.cc", - "//components/drive/drive_file_util_unittest.cc", "//components/drive/drive_notification_manager_unittest.cc", - "//components/drive/drive_operation_queue_unittest.cc", - "//components/drive/file_change_unittest.cc", - "//components/drive/file_system_core_util_unittest.cc", - "//components/drive/file_write_watcher_unittest.cc", - "//components/drive/job_queue_unittest.cc", - "//components/drive/job_scheduler_unittest.cc", - "//components/drive/local_file_reader_unittest.cc", - "//components/drive/remove_stale_cache_files_unittest.cc", - "//components/drive/resource_entry_conversion_unittest.cc", "//components/drive/resource_metadata_storage_unittest.cc", - "//components/drive/resource_metadata_unittest.cc", "//components/drive/search_metadata_unittest.cc", ] @@ -3020,9 +3011,7 @@ "//components/crx_file", "//components/download/public/background_service/test:test_support", "//components/drive", - "//components/drive:drive_chromeos", "//components/drive:test_support", - "//components/drive:test_support_chromeos", "//components/exo", "//components/invalidation/impl:test_support", "//components/invalidation/public",
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc index 3e8b8ce0..d3eed6e3 100644 --- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -66,9 +66,7 @@ #include "components/arc/session/arc_bridge_service.h" #include "components/arc/test/connection_holder_util.h" #include "components/arc/test/fake_file_system_instance.h" -#include "components/drive/chromeos/file_system_interface.h" #include "components/drive/drive_pref_names.h" -#include "components/drive/service/fake_drive_service.h" #include "components/prefs/pref_service.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/notification_service.h"
diff --git a/chrome/browser/chromeos/login/app_launch_controller.cc b/chrome/browser/chromeos/login/app_launch_controller.cc index 575c255..4c04b37b 100644 --- a/chrome/browser/chromeos/login/app_launch_controller.cc +++ b/chrome/browser/chromeos/login/app_launch_controller.cc
@@ -288,15 +288,18 @@ OnLaunchFailed(KioskAppLaunchError::USER_CANCEL); } -void AppLaunchController::OnNetworkConfigRequested(bool requested) { - network_config_requested_ = requested; - if (requested) { - MaybeShowNetworkConfigureUI(); - } else { - app_launch_splash_screen_view_->UpdateAppLaunchState( - AppLaunchSplashScreenView::APP_LAUNCH_STATE_PREPARING_NETWORK); - startup_app_launcher_->RestartLauncher(); - } +void AppLaunchController::OnNetworkConfigRequested() { + DCHECK(!network_config_requested_); + network_config_requested_ = true; + MaybeShowNetworkConfigureUI(); +} + +void AppLaunchController::OnNetworkConfigFinished() { + DCHECK(network_config_requested_); + network_config_requested_ = false; + app_launch_splash_screen_view_->UpdateAppLaunchState( + AppLaunchSplashScreenView::APP_LAUNCH_STATE_PREPARING_NETWORK); + startup_app_launcher_->RestartLauncher(); } void AppLaunchController::OnNetworkStateChanged(bool online) {
diff --git a/chrome/browser/chromeos/login/app_launch_controller.h b/chrome/browser/chromeos/login/app_launch_controller.h index 6ae3fe1..b09f5e4 100644 --- a/chrome/browser/chromeos/login/app_launch_controller.h +++ b/chrome/browser/chromeos/login/app_launch_controller.h
@@ -58,7 +58,8 @@ // AppLaunchSplashScreenView::Delegate: void OnConfigureNetwork() override; void OnCancelAppLaunch() override; - void OnNetworkConfigRequested(bool requested) override; + void OnNetworkConfigRequested() override; + void OnNetworkConfigFinished() override; void OnNetworkStateChanged(bool online) override; void OnDeletingSplashScreenView() override; KioskAppManagerBase::App GetAppData() override;
diff --git a/chrome/browser/chromeos/login/ui/login_web_dialog.cc b/chrome/browser/chromeos/login/ui/login_web_dialog.cc index 7cc30bb..e81e41a 100644 --- a/chrome/browser/chromeos/login/ui/login_web_dialog.cc +++ b/chrome/browser/chromeos/login/ui/login_web_dialog.cc
@@ -56,8 +56,7 @@ delegate_(delegate), title_(title), url_(url) { - if (!parent_window_) { - DCHECK(chromeos::LoginDisplayHost::default_host()); + if (!parent_window_ && chromeos::LoginDisplayHost::default_host()) { parent_window_ = chromeos::LoginDisplayHost::default_host()->GetNativeWindow(); } @@ -93,6 +92,11 @@ std::vector<WebUIMessageHandler*>* handlers) const {} void LoginWebDialog::GetDialogSize(gfx::Size* size) const { + // TODO(https://crbug.com/1022774): Fix for the lock screen. + if (!parent_window_) { + *size = kMaxSize; + return; + } gfx::Rect bounds = parent_window_->bounds(); bounds.Inset(kMinMargins); *size = bounds.size();
diff --git a/chrome/browser/chromeos/login/ui/login_web_dialog_browsertest.cc b/chrome/browser/chromeos/login/ui/login_web_dialog_browsertest.cc index 2e1f650..0874047 100644 --- a/chrome/browser/chromeos/login/ui/login_web_dialog_browsertest.cc +++ b/chrome/browser/chromeos/login/ui/login_web_dialog_browsertest.cc
@@ -45,4 +45,13 @@ EXPECT_TRUE(closing_observer.widget_closed()); } +// Tests that LoginWebDialog does not crash with missing parent window. +IN_PROC_BROWSER_TEST_F(LoginWebDialogTest, NoParentWindow) { + LoginWebDialog* dialog = new LoginWebDialog( + browser()->profile(), nullptr, nullptr, base::string16(), GURL()); + dialog->Show(); + aura::Window* window = dialog->get_dialog_window_for_test(); + ASSERT_TRUE(window); +} + } // namespace chromeos
diff --git a/chrome/browser/chromeos/login/web_kiosk_controller.cc b/chrome/browser/chromeos/login/web_kiosk_controller.cc index ff4c940b..0e863699e 100644 --- a/chrome/browser/chromeos/login/web_kiosk_controller.cc +++ b/chrome/browser/chromeos/login/web_kiosk_controller.cc
@@ -67,17 +67,17 @@ } } -void WebKioskController::OnConfigureNetwork() { - // TODO(crbug.com/1006230): Implement when app launch logic is done. -} - void WebKioskController::OnCancelAppLaunch() { KioskAppLaunchError::Save(KioskAppLaunchError::USER_CANCEL); CleanUp(); chrome::AttemptUserExit(); } -void WebKioskController::OnNetworkConfigRequested(bool requested) { +void WebKioskController::OnNetworkConfigRequested() { + // TODO(crbug.com/1006230): Implement when app launch logic is done. +} + +void WebKioskController::OnNetworkConfigFinished() { // TODO(crbug.com/1006230): Implement when app launch logic is done. }
diff --git a/chrome/browser/chromeos/login/web_kiosk_controller.h b/chrome/browser/chromeos/login/web_kiosk_controller.h index 4cfea7f..22de152f 100644 --- a/chrome/browser/chromeos/login/web_kiosk_controller.h +++ b/chrome/browser/chromeos/login/web_kiosk_controller.h
@@ -52,9 +52,9 @@ void OnProfilePrepared(Profile* profile, bool browser_launched) override; // AppLaunchSplashScreenView::Delegate: - void OnConfigureNetwork() override; void OnCancelAppLaunch() override; - void OnNetworkConfigRequested(bool requested) override; + void OnNetworkConfigRequested() override; + void OnNetworkConfigFinished() override; void OnNetworkStateChanged(bool online) override; void OnDeletingSplashScreenView() override; KioskAppManagerBase::App GetAppData() override;
diff --git a/chrome/browser/chromeos/printing/printers_model_type_controller.cc b/chrome/browser/chromeos/printing/printers_model_type_controller.cc new file mode 100644 index 0000000..b2a9a4d --- /dev/null +++ b/chrome/browser/chromeos/printing/printers_model_type_controller.cc
@@ -0,0 +1,48 @@ +// 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/printing/printers_model_type_controller.h" + +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "chromeos/constants/chromeos_features.h" +#include "components/prefs/pref_service.h" +#include "components/sync/base/model_type.h" +#include "components/sync/base/pref_names.h" +#include "components/sync/driver/sync_service.h" +#include "components/sync/model/model_type_controller_delegate.h" + +PrintersModelTypeController::PrintersModelTypeController( + std::unique_ptr<syncer::ModelTypeControllerDelegate> delegate, + PrefService* pref_service, + syncer::SyncService* sync_service) + : syncer::ModelTypeController(syncer::PRINTERS, std::move(delegate)), + pref_service_(pref_service), + sync_service_(sync_service) { + DCHECK(chromeos::features::IsSplitSettingsSyncEnabled()); + DCHECK(pref_service_); + DCHECK(sync_service_); + pref_registrar_.Init(pref_service_); + pref_registrar_.Add( + syncer::prefs::kOsSyncFeatureEnabled, + base::BindRepeating(&PrintersModelTypeController::OnUserPrefChanged, + base::Unretained(this))); +} + +PrintersModelTypeController::~PrintersModelTypeController() = default; + +syncer::DataTypeController::PreconditionState +PrintersModelTypeController::GetPreconditionState() const { + DCHECK(CalledOnValidThread()); + return pref_service_->GetBoolean(syncer::prefs::kOsSyncFeatureEnabled) + ? PreconditionState::kPreconditionsMet + : PreconditionState::kMustStopAndClearData; +} + +void PrintersModelTypeController::OnUserPrefChanged() { + DCHECK(CalledOnValidThread()); + sync_service_->DataTypePreconditionChanged(type()); +}
diff --git a/chrome/browser/chromeos/printing/printers_model_type_controller.h b/chrome/browser/chromeos/printing/printers_model_type_controller.h new file mode 100644 index 0000000..2269876 --- /dev/null +++ b/chrome/browser/chromeos/printing/printers_model_type_controller.h
@@ -0,0 +1,44 @@ +// 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_PRINTING_PRINTERS_MODEL_TYPE_CONTROLLER_H_ +#define CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MODEL_TYPE_CONTROLLER_H_ + +#include "components/prefs/pref_change_registrar.h" +#include "components/sync/driver/model_type_controller.h" + +class PrefService; + +namespace syncer { +class ModelTypeControllerDelegate; +class SyncService; +} // namespace syncer + +// Controls syncing of ModelType PRINTERS. +class PrintersModelTypeController : public syncer::ModelTypeController { + public: + PrintersModelTypeController( + std::unique_ptr<syncer::ModelTypeControllerDelegate> delegate, + PrefService* pref_service, + syncer::SyncService* sync_service); + ~PrintersModelTypeController() override; + + PrintersModelTypeController(const PrintersModelTypeController&) = delete; + PrintersModelTypeController& operator=(const PrintersModelTypeController&) = + delete; + + // DataTypeController: + PreconditionState GetPreconditionState() const override; + + private: + // Callback for changes to the OS sync feature enabled pref. + void OnUserPrefChanged(); + + PrefService* const pref_service_; + syncer::SyncService* const sync_service_; + + PrefChangeRegistrar pref_registrar_; +}; + +#endif // CHROME_BROWSER_CHROMEOS_PRINTING_PRINTERS_MODEL_TYPE_CONTROLLER_H_
diff --git a/chrome/browser/chromeos/sync/os_preferences_model_type_controller.cc b/chrome/browser/chromeos/sync/os_preferences_model_type_controller.cc new file mode 100644 index 0000000..4490e722 --- /dev/null +++ b/chrome/browser/chromeos/sync/os_preferences_model_type_controller.cc
@@ -0,0 +1,55 @@ +// 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/sync/os_preferences_model_type_controller.h" + +#include <utility> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "chromeos/constants/chromeos_features.h" +#include "components/prefs/pref_service.h" +#include "components/sync/base/model_type.h" +#include "components/sync/base/pref_names.h" +#include "components/sync/driver/sync_service.h" + +OsPreferencesModelTypeController::OsPreferencesModelTypeController( + syncer::ModelType type, + syncer::OnceModelTypeStoreFactory store_factory, + base::WeakPtr<syncer::SyncableService> syncable_service, + const base::RepeatingClosure& dump_stack, + PrefService* pref_service, + syncer::SyncService* sync_service) + : syncer::SyncableServiceBasedModelTypeController(type, + std::move(store_factory), + syncable_service, + dump_stack), + pref_service_(pref_service), + sync_service_(sync_service) { + DCHECK(chromeos::features::IsSplitSettingsSyncEnabled()); + DCHECK(type == syncer::OS_PREFERENCES || + type == syncer::OS_PRIORITY_PREFERENCES); + DCHECK(pref_service_); + DCHECK(sync_service_); + pref_registrar_.Init(pref_service_); + pref_registrar_.Add( + syncer::prefs::kOsSyncFeatureEnabled, + base::BindRepeating(&OsPreferencesModelTypeController::OnUserPrefChanged, + base::Unretained(this))); +} + +OsPreferencesModelTypeController::~OsPreferencesModelTypeController() = default; + +syncer::DataTypeController::PreconditionState +OsPreferencesModelTypeController::GetPreconditionState() const { + DCHECK(CalledOnValidThread()); + return pref_service_->GetBoolean(syncer::prefs::kOsSyncFeatureEnabled) + ? PreconditionState::kPreconditionsMet + : PreconditionState::kMustStopAndClearData; +} + +void OsPreferencesModelTypeController::OnUserPrefChanged() { + DCHECK(CalledOnValidThread()); + sync_service_->DataTypePreconditionChanged(type()); +}
diff --git a/chrome/browser/chromeos/sync/os_preferences_model_type_controller.h b/chrome/browser/chromeos/sync/os_preferences_model_type_controller.h new file mode 100644 index 0000000..4267219 --- /dev/null +++ b/chrome/browser/chromeos/sync/os_preferences_model_type_controller.h
@@ -0,0 +1,51 @@ +// 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_SYNC_OS_PREFERENCES_MODEL_TYPE_CONTROLLER_H_ +#define CHROME_BROWSER_CHROMEOS_SYNC_OS_PREFERENCES_MODEL_TYPE_CONTROLLER_H_ + +#include "base/callback_forward.h" +#include "base/memory/weak_ptr.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/sync/driver/syncable_service_based_model_type_controller.h" +#include "components/sync/model/model_type_store.h" + +class PrefService; + +namespace syncer { +class SyncService; +} + +// Controls syncing of ModelTypes OS_PREFERENCES and OS_PRIORITY_PREFERENCES. +class OsPreferencesModelTypeController + : public syncer::SyncableServiceBasedModelTypeController { + public: + OsPreferencesModelTypeController( + syncer::ModelType type, + syncer::OnceModelTypeStoreFactory store_factory, + base::WeakPtr<syncer::SyncableService> syncable_service, + const base::RepeatingClosure& dump_stack, + PrefService* pref_service, + syncer::SyncService* sync_service); + ~OsPreferencesModelTypeController() override; + + OsPreferencesModelTypeController(const OsPreferencesModelTypeController&) = + delete; + OsPreferencesModelTypeController& operator=( + const OsPreferencesModelTypeController&) = delete; + + // DataTypeController: + PreconditionState GetPreconditionState() const override; + + private: + // Callback for changes to the OS sync feature enabled pref. + void OnUserPrefChanged(); + + PrefService* const pref_service_; + syncer::SyncService* const sync_service_; + + PrefChangeRegistrar pref_registrar_; +}; + +#endif // CHROME_BROWSER_CHROMEOS_SYNC_OS_PREFERENCES_MODEL_TYPE_CONTROLLER_H_
diff --git a/chrome/browser/component_updater/cros_component_installer_chromeos.cc b/chrome/browser/component_updater/cros_component_installer_chromeos.cc index 733d2e7..f57033e 100644 --- a/chrome/browser/component_updater/cros_component_installer_chromeos.cc +++ b/chrome/browser/component_updater/cros_component_installer_chromeos.cc
@@ -38,9 +38,9 @@ "1913a5e0a6cad30b6f03e176177e0d7ed62c5d6700a9c66da556d7c3f5d6a47e"}, {"cros-termina", "800.1", "e9d960f84f628e1f42d05de4046bb5b3154b6f1f65c08412c6af57a29aecaffb"}, - {"rtanalytics-light", "14.0", + {"rtanalytics-light", "15.0", "69f09d33c439c2ab55bbbe24b47ab55cb3f6c0bd1f1ef46eefea3216ec925038"}, - {"rtanalytics-full", "14.0", + {"rtanalytics-full", "15.0", "c93c3e1013c52100a20038b405ac854d69fa889f6dc4fa6f188267051e05e444"}, {"star-cups-driver", "1.1", "6d24de30f671da5aee6d463d9e446cafe9ddac672800a9defe86877dcde6c466"},
diff --git a/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc b/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc index b6ceed8..9a0006e 100644 --- a/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc +++ b/chrome/browser/dom_distiller/distillable_page_utils_browsertest.cc
@@ -249,4 +249,14 @@ Optional(AllOf(Not(IsDistillable()), IsLast(), Not(IsMobileFriendly())))); } +IN_PROC_BROWSER_TEST_F(DistillablePageUtilsBrowserTestAllArticles, + ObserverNotCalledAfterRemoval) { + RemoveObserver(web_contents_, &holder_); + EXPECT_CALL(holder_, OnResult(_)).Times(0); + NavigateAndWait(kSimpleArticlePath, kWaitNoExpectedCall); + EXPECT_THAT( + GetLatestResult(web_contents_), + Optional(AllOf(IsDistillable(), IsLast(), Not(IsMobileFriendly())))); +} + } // namespace dom_distiller
diff --git a/chrome/browser/dom_distiller/dom_distiller_service_factory.cc b/chrome/browser/dom_distiller/dom_distiller_service_factory.cc index 0ac7729..d56aa95 100644 --- a/chrome/browser/dom_distiller/dom_distiller_service_factory.cc +++ b/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
@@ -8,6 +8,7 @@ #include "base/sequenced_task_runner.h" #include "base/task/post_task.h" +#include "build/build_config.h" #include "chrome/browser/profiles/incognito_helpers.h" #include "chrome/browser/profiles/profile.h" #include "components/dom_distiller/content/browser/distiller_page_web_contents.h" @@ -18,15 +19,21 @@ #include "content/public/browser/storage_partition.h" #include "services/network/public/cpp/shared_url_loader_factory.h" +#if defined(OS_ANDROID) +#include "chrome/browser/android/dom_distiller/distiller_ui_handle_android.h" +#endif // defined(OS_ANDROID) + namespace dom_distiller { DomDistillerContextKeyedService::DomDistillerContextKeyedService( std::unique_ptr<DistillerFactory> distiller_factory, std::unique_ptr<DistillerPageFactory> distiller_page_factory, - std::unique_ptr<DistilledPagePrefs> distilled_page_prefs) + std::unique_ptr<DistilledPagePrefs> distilled_page_prefs, + std::unique_ptr<DistillerUIHandle> distiller_ui_handle) : DomDistillerService(std::move(distiller_factory), std::move(distiller_page_factory), - std::move(distilled_page_prefs)) {} + std::move(distilled_page_prefs), + std::move(distiller_ui_handle)) {} // static DomDistillerServiceFactory* DomDistillerServiceFactory::GetInstance() { @@ -80,11 +87,17 @@ std::move(distiller_url_fetcher_factory), options)); std::unique_ptr<DistilledPagePrefs> distilled_page_prefs( new DistilledPagePrefs(profile->GetPrefs())); + std::unique_ptr<DistillerUIHandle> distiller_ui_handle; + +#if defined(OS_ANDROID) + distiller_ui_handle = + std::make_unique<dom_distiller::android::DistillerUIHandleAndroid>(); +#endif // defined(OS_ANDROID) DomDistillerContextKeyedService* service = - new DomDistillerContextKeyedService(std::move(distiller_factory), - std::move(distiller_page_factory), - std::move(distilled_page_prefs)); + new DomDistillerContextKeyedService( + std::move(distiller_factory), std::move(distiller_page_factory), + std::move(distilled_page_prefs), std::move(distiller_ui_handle)); return service; }
diff --git a/chrome/browser/dom_distiller/dom_distiller_service_factory.h b/chrome/browser/dom_distiller/dom_distiller_service_factory.h index e28ad13f..e51ccd87 100644 --- a/chrome/browser/dom_distiller/dom_distiller_service_factory.h +++ b/chrome/browser/dom_distiller/dom_distiller_service_factory.h
@@ -8,6 +8,7 @@ #include "base/macros.h" #include "base/memory/singleton.h" #include "components/dom_distiller/core/distilled_page_prefs.h" +#include "components/dom_distiller/core/distiller_ui_handle.h" #include "components/dom_distiller/core/dom_distiller_service.h" #include "components/keyed_service/content/browser_context_keyed_service_factory.h" #include "components/keyed_service/core/keyed_service.h" @@ -26,7 +27,8 @@ DomDistillerContextKeyedService( std::unique_ptr<DistillerFactory> distiller_factory, std::unique_ptr<DistillerPageFactory> distiller_page_factory, - std::unique_ptr<DistilledPagePrefs> distilled_page_prefs); + std::unique_ptr<DistilledPagePrefs> distilled_page_prefs, + std::unique_ptr<DistillerUIHandle> distiller_ui_handle); ~DomDistillerContextKeyedService() override {} private:
diff --git a/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc b/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc index 006d5aa..217c44f2 100644 --- a/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc +++ b/chrome/browser/dom_distiller/dom_distiller_viewer_source_browsertest.cc
@@ -118,7 +118,8 @@ auto service = std::make_unique<DomDistillerContextKeyedService>( std::move(distiller_factory), std::move(distiller_page_factory), std::make_unique<DistilledPagePrefs>( - Profile::FromBrowserContext(context)->GetPrefs())); + Profile::FromBrowserContext(context)->GetPrefs()), + /* distiller_ui_handle */ nullptr); if (expect_distillation_) { // There will only be destillation of an article if the database contains // the article.
diff --git a/chrome/browser/dom_distiller/lazy_dom_distiller_service.cc b/chrome/browser/dom_distiller/lazy_dom_distiller_service.cc index 28acfac..98cf30b 100644 --- a/chrome/browser/dom_distiller/lazy_dom_distiller_service.cc +++ b/chrome/browser/dom_distiller/lazy_dom_distiller_service.cc
@@ -55,6 +55,10 @@ return GetImpl()->GetDistilledPagePrefs(); } +DistillerUIHandle* LazyDomDistillerService::GetDistillerUIHandle() { + return GetImpl()->GetDistillerUIHandle(); +} + LazyDomDistillerService::LazyDomDistillerService(Profile* profile) : profile_(profile) {}
diff --git a/chrome/browser/dom_distiller/lazy_dom_distiller_service.h b/chrome/browser/dom_distiller/lazy_dom_distiller_service.h index 23895af..d605f9b5 100644 --- a/chrome/browser/dom_distiller/lazy_dom_distiller_service.h +++ b/chrome/browser/dom_distiller/lazy_dom_distiller_service.h
@@ -37,6 +37,7 @@ std::unique_ptr<DistillerPage> CreateDefaultDistillerPageWithHandle( std::unique_ptr<SourcePageHandle> handle) override; DistilledPagePrefs* GetDistilledPagePrefs() override; + DistillerUIHandle* GetDistillerUIHandle() override; private: explicit LazyDomDistillerService(Profile* profile);
diff --git a/chrome/browser/dom_distiller/profile_utils.cc b/chrome/browser/dom_distiller/profile_utils.cc index 59230bb..09c07fd 100644 --- a/chrome/browser/dom_distiller/profile_utils.cc +++ b/chrome/browser/dom_distiller/profile_utils.cc
@@ -13,15 +13,10 @@ #include "chrome/common/chrome_isolated_world_ids.h" #include "chrome/common/chrome_switches.h" #include "components/dom_distiller/content/browser/distiller_javascript_utils.h" -#include "components/dom_distiller/content/browser/distiller_ui_handle.h" #include "components/dom_distiller/content/browser/dom_distiller_viewer_source.h" #include "components/dom_distiller/core/dom_distiller_features.h" #include "components/dom_distiller/core/url_constants.h" -#if defined(OS_ANDROID) -#include "chrome/browser/android/dom_distiller/distiller_ui_handle_android.h" -#endif // defined(OS_ANDROID) - namespace dom_distiller { void RegisterViewerSource(Profile* profile) { @@ -30,20 +25,14 @@ LazyDomDistillerService* lazy_service = LazyDomDistillerService::Create(profile); - std::unique_ptr<DistillerUIHandle> ui_handle; - -#if defined(OS_ANDROID) - ui_handle = - std::make_unique<dom_distiller::android::DistillerUIHandleAndroid>(); -#endif // defined(OS_ANDROID) // Set the JavaScript world ID. if (!DistillerJavaScriptWorldIdIsSet()) SetDistillerJavaScriptWorldId(ISOLATED_WORLD_ID_CHROME_INTERNAL); content::URLDataSource::Add( - profile, std::make_unique<DomDistillerViewerSource>( - lazy_service, kDomDistillerScheme, std::move(ui_handle))); + profile, std::make_unique<DomDistillerViewerSource>(lazy_service, + kDomDistillerScheme)); } } // namespace dom_distiller
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc index 538751dcb..8ebab3b 100644 --- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc +++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h" #include <memory> +#include <utility> +#include <vector> #include "base/bind.h" #include "base/json/json_writer.h" @@ -51,7 +53,9 @@ EnterpriseReportingPrivateUploadChromeDesktopReportFunction:: EnterpriseReportingPrivateUploadChromeDesktopReportFunction( - scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + : dm_token_( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateEmptyToken()) { policy::DeviceManagementService* device_management_service = g_browser_process->browser_policy_connector() ->device_management_service(); @@ -66,7 +70,7 @@ std::string() /* manufacture_date */, device_management_service, std::move(url_loader_factory), nullptr, policy::CloudPolicyClient::DeviceDMTokenCallback()); - dm_token_ = policy::BrowserDMTokenStorage::Get()->RetrieveDMToken(); + dm_token_ = policy::BrowserDMTokenStorage::Get()->RetrieveBrowserDMToken(); client_id_ = policy::BrowserDMTokenStorage::Get()->RetrieveClientId(); } @@ -85,7 +89,7 @@ EnterpriseReportingPrivateUploadChromeDesktopReportFunction::Run() { VLOG(1) << "Uploading enterprise report"; - if (dm_token_.empty() || client_id_.empty()) { + if (!dm_token_.is_valid() || client_id_.empty()) { LogReportError("Device is not enrolled."); return RespondNow(Error(enterprise_reporting::kDeviceNotEnrolled)); } @@ -104,7 +108,7 @@ } if (!cloud_policy_client_->is_registered()) - cloud_policy_client_->SetupRegistration(dm_token_, client_id_, + cloud_policy_client_->SetupRegistration(dm_token_.value(), client_id_, std::vector<std::string>()); cloud_policy_client_->UploadChromeDesktopReport( @@ -123,8 +127,9 @@ } void EnterpriseReportingPrivateUploadChromeDesktopReportFunction:: - SetRegistrationInfoForTesting(const std::string& dm_token, - const std::string& client_id) { + SetRegistrationInfoForTesting( + const policy::BrowserDMTokenStorage::BrowserDMToken& dm_token, + const std::string& client_id) { dm_token_ = dm_token; client_id_ = client_id; }
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h index ec772107..d125f544 100644 --- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h +++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_api.h
@@ -5,7 +5,11 @@ #ifndef CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_REPORTING_PRIVATE_ENTERPRISE_REPORTING_PRIVATE_API_H_ #define CHROME_BROWSER_EXTENSIONS_API_ENTERPRISE_REPORTING_PRIVATE_ENTERPRISE_REPORTING_PRIVATE_API_H_ +#include <memory> +#include <string> + #include "base/memory/ref_counted.h" +#include "chrome/browser/policy/browser_dm_token_storage.h" #include "extensions/browser/extension_function.h" namespace policy { @@ -39,8 +43,9 @@ void SetCloudPolicyClientForTesting( std::unique_ptr<policy::CloudPolicyClient> client); - void SetRegistrationInfoForTesting(const std::string& dm_token, - const std::string& client_id); + void SetRegistrationInfoForTesting( + const policy::BrowserDMTokenStorage::BrowserDMToken& dm_token, + const std::string& client_id); // Used by tests that want to overrode the URLLoaderFactory used to simulate // network requests. @@ -58,7 +63,7 @@ void OnReportUploaded(bool status); std::unique_ptr<policy::CloudPolicyClient> cloud_policy_client_; - std::string dm_token_; + policy::BrowserDMTokenStorage::BrowserDMToken dm_token_; std::string client_id_; DISALLOW_COPY_AND_ASSIGN(
diff --git a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc index 344b323..06829af 100644 --- a/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc +++ b/chrome/browser/extensions/api/enterprise_reporting_private/enterprise_reporting_private_unittest.cc
@@ -43,7 +43,16 @@ test_url_loader_factory_.GetSafeWeakWrapper()); client_ = client.get(); function->SetCloudPolicyClientForTesting(std::move(client)); - function->SetRegistrationInfoForTesting(dm_token, kFakeClientId); + if (dm_token.empty()) { + function->SetRegistrationInfoForTesting( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateEmptyToken(), + kFakeClientId); + } else { + function->SetRegistrationInfoForTesting( + policy::BrowserDMTokenStorage::BrowserDMToken::CreateValidToken( + dm_token), + kFakeClientId); + } return function; }
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 8fbe1df..fcff95f 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -555,7 +555,7 @@ "expiry_milestone": 80 }, { - "name": "cross-origin-embedder-policy", + "name": "cross-origin-isolation", "owners": [ "yhirano" ], "expiry_milestone": 83 }, @@ -590,6 +590,11 @@ "expiry_milestone": 82 }, { + "name": "cryptauth-v1-devicesync-deprecate", + "owners": [ "khorimoto", "nohle" ], + "expiry_milestone": 87 + }, + { "name": "cryptauth-v2-device-activity-status", "owners": [ "khorimoto", "nohle", "themaxli" ], "expiry_milestone": 85 @@ -1669,7 +1674,7 @@ { "name": "enable-reader-mode", "owners": [ "gilmanmh@google.com" ], - "expiry_milestone": 78 + "expiry_milestone": 82 }, { "name": "enable-reader-mode-in-cct",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index b36de73..2c8ff0f 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -815,9 +815,9 @@ const char kEnableOutOfBlinkCorsDescription[] = "CORS handling logic is moved out of blink."; -const char kCrossOriginEmbedderPolicyName[] = "Cross Origin Embedder Policy"; -const char kCrossOriginEmbedderPolicyDescription[] = - "Enable Cross Origin Embedder Policy (https://mikewest.github.io/corpp/)."; +const char kCrossOriginIsolationName[] = "Cross Origin Isolation"; +const char kCrossOriginIsolationDescription[] = + "Enable Cross Origin Opener Policy and Cross Origin Embedder Policy."; const char kDisableKeepaliveFetchName[] = "Disable fetch with keepalive set"; const char kDisableKeepaliveFetchDescription[] = @@ -3336,6 +3336,12 @@ const char kCrostiniWebUIInstallerDescription[] = "Enable the new WebUI Crostini Installer."; +const char kCryptAuthV1DeviceSyncDeprecateName[] = + "Deprecate CryptAuth v1 DeviceSync"; +const char kCryptAuthV1DeviceSyncDeprecateDescription[] = + "Deprecate the CryptAuth v1 DeviceSync protocol. The v2 DeviceSync flag " + "should be enabled before this flag is flipped."; + const char kCryptAuthV2DeviceActivityStatusName[] = "CryptAuth Device Activity Status"; const char kCryptAuthV2DeviceActivityStatusDescription[] = @@ -3343,7 +3349,8 @@ const char kCryptAuthV2DeviceSyncName[] = "CryptAuth v2 DeviceSync"; const char kCryptAuthV2DeviceSyncDescription[] = - "Use the CryptAuth v2 DeviceSync protocol."; + "Use the CryptAuth v2 DeviceSync protocol. Note: v1 DeviceSync will " + "continue to run until the deprecation flag is flipped."; const char kCryptAuthV2EnrollmentName[] = "CryptAuth v2 Enrollment"; const char kCryptAuthV2EnrollmentDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 411e4a1..fd171b9 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -477,8 +477,8 @@ extern const char kEnableOutOfBlinkCorsName[]; extern const char kEnableOutOfBlinkCorsDescription[]; -extern const char kCrossOriginEmbedderPolicyName[]; -extern const char kCrossOriginEmbedderPolicyDescription[]; +extern const char kCrossOriginIsolationName[]; +extern const char kCrossOriginIsolationDescription[]; extern const char kDisableKeepaliveFetchName[]; extern const char kDisableKeepaliveFetchDescription[]; @@ -1975,6 +1975,9 @@ extern const char kCrostiniWebUIInstallerName[]; extern const char kCrostiniWebUIInstallerDescription[]; +extern const char kCryptAuthV1DeviceSyncDeprecateName[]; +extern const char kCryptAuthV1DeviceSyncDeprecateDescription[]; + extern const char kCryptAuthV2DeviceActivityStatusName[]; extern const char kCryptAuthV2DeviceActivityStatusDescription[];
diff --git a/chrome/browser/password_manager/password_manager_browsertest.cc b/chrome/browser/password_manager/password_manager_browsertest.cc index 71d06fc..90a9eb0 100644 --- a/chrome/browser/password_manager/password_manager_browsertest.cc +++ b/chrome/browser/password_manager/password_manager_browsertest.cc
@@ -3315,8 +3315,7 @@ #define MAYBE_FillWhenFormWithHiddenUsername \ DISABLED_FillWhenFormWithHiddenUsername #else -#define MAYBE_FillWhenFormWithHiddenUsername \ - FillWhenFormWithHiddenUsername +#define MAYBE_FillWhenFormWithHiddenUsername FillWhenFormWithHiddenUsername #endif IN_PROC_BROWSER_TEST_F(PasswordManagerBrowserTest, MAYBE_FillWhenFormWithHiddenUsername) { @@ -3788,6 +3787,8 @@ // Check that the password for origin A was not updated automatically and the // update bubble is shown instead. WaitForPasswordStore(); // Let the navigation take its effect on storing. + ASSERT_THAT(password_store->stored_passwords(), + ElementsAre(testing::Key(url_A.GetOrigin()))); CheckThatCredentialsStored("user", "oldpassword"); std::unique_ptr<BubbleObserver> prompt_observer( new BubbleObserver(WebContents())); @@ -3799,10 +3800,9 @@ prompt_observer->AcceptUpdatePrompt(stored_form); WaitForPasswordStore(); - // There are two credentials saved with the new password. + // The stored credential has been updated with the new password. const auto& passwords_map = password_store->stored_passwords(); - ASSERT_THAT(passwords_map, ElementsAre(testing::Key(url_A.GetOrigin()), - testing::Key(url_B.GetOrigin()))); + ASSERT_THAT(passwords_map, ElementsAre(testing::Key(url_A.GetOrigin()))); for (const auto& credentials : passwords_map) { ASSERT_THAT(credentials.second, testing::SizeIs(1)); EXPECT_EQ(base::ASCIIToUTF16("user"), credentials.second[0].username_value);
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 56079c34..f974c9b 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -69,8 +69,6 @@ #include "content/public/common/context_menu_params.h" #include "content/public/common/mime_handler_view_mode.h" #include "content/public/common/url_constants.h" -#include "content/public/test/accessibility_notification_waiter.h" -#include "content/public/test/browser_accessibility.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/dump_accessibility_test_helper.h" #include "content/public/test/hit_test_region_observer.h" @@ -83,7 +81,6 @@ #include "net/test/embedded_test_server/embedded_test_server.h" #include "pdf/pdf_features.h" #include "services/network/public/cpp/features.h" -#include "ui/accessibility/ax_action_data.h" #include "ui/accessibility/ax_enum_util.h" #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_node.h" @@ -2518,13 +2515,12 @@ // Find the embedded PDF and dump the accessibility tree. content::FindAccessibilityNodeCriteria find_criteria; find_criteria.role = ax::mojom::Role::kEmbeddedObject; - content::TestBrowserAccessibility* pdf_root = + content::BrowserAccessibility* pdf_root = content::FindAccessibilityNode(guest_contents, find_criteria); CHECK(pdf_root); base::string16 actual_contents_utf16; - content::TestBrowserAccessibility::FormatAccessibilityTree( - formatter.get(), pdf_root, &actual_contents_utf16); + formatter->FormatAccessibilityTree(pdf_root, &actual_contents_utf16); std::string actual_contents = base::UTF16ToUTF8(actual_contents_utf16); std::vector<std::string> actual_lines = @@ -2630,38 +2626,3 @@ IN_PROC_BROWSER_TEST_P(PDFExtensionAccessibilityTreeDumpTest, TextStyle) { RunPDFTest(FILE_PATH_LITERAL("text-style.pdf")); } - -// This test suite validates the navigation done using the accessibility client. -using PDFExtensionAccessibilityNavigationTest = PDFExtensionTest; - -IN_PROC_BROWSER_TEST_F(PDFExtensionAccessibilityNavigationTest, - LinkNavigation) { - // Enable accessibility and load the test file. - content::BrowserAccessibilityState::GetInstance()->EnableAccessibility(); - GURL url(embedded_test_server()->GetURL("/pdf/accessibility/weblinks.pdf")); - WebContents* guest_contents = LoadPdfGetGuestContents(url); - ASSERT_TRUE(guest_contents); - WaitForAccessibilityTreeToContainNodeWithName(guest_contents, "Page 1"); - - // Find the specific link node. - content::FindAccessibilityNodeCriteria find_criteria; - find_criteria.role = ax::mojom::Role::kLink; - find_criteria.name = "http://bing.com"; - content::TestBrowserAccessibility* link_node = - content::FindAccessibilityNode(guest_contents, find_criteria); - ASSERT_TRUE(link_node); - - // Invoke action on a link and wait for navigation to complete. - content::AccessibilityNotificationWaiter event_waiter( - GetActiveWebContents(), ui::kAXModeComplete, - ax::mojom::Event::kLoadComplete); - ui::AXActionData action_data; - action_data.action = ax::mojom::Action::kDoDefault; - action_data.target_node_id = link_node->GetData().id; - link_node->AccessibilityPerformAction(action_data); - event_waiter.WaitForNotification(); - - // Test that navigation occurred correctly. - const GURL& expected_url = GetActiveWebContents()->GetURL(); - EXPECT_EQ("https://bing.com/", expected_url.spec()); -}
diff --git a/chrome/browser/policy/cloud/chrome_browser_cloud_management_browsertest.cc b/chrome/browser/policy/cloud/chrome_browser_cloud_management_browsertest.cc index f60dc29..49ca7fa 100644 --- a/chrome/browser/policy/cloud/chrome_browser_cloud_management_browsertest.cc +++ b/chrome/browser/policy/cloud/chrome_browser_cloud_management_browsertest.cc
@@ -471,9 +471,13 @@ } void VerifyEnrollmentResult() { - EXPECT_EQ(is_enrollment_token_valid() ? "fake_device_management_token" - : std::string(), - BrowserDMTokenStorage::Get()->RetrieveDMToken()); + auto dm_token = BrowserDMTokenStorage::Get()->RetrieveBrowserDMToken(); + if (is_enrollment_token_valid()) { + EXPECT_TRUE(dm_token.is_valid()); + EXPECT_EQ("fake_device_management_token", dm_token.value()); + } else { + EXPECT_TRUE(dm_token.is_empty()); + } // Verify the enrollment result. ChromeBrowserCloudManagementEnrollmentResult expected_result;
diff --git a/chrome/browser/policy/cloud/chrome_browser_cloud_management_helper.cc b/chrome/browser/policy/cloud/chrome_browser_cloud_management_helper.cc index 192ce1d..b989810 100644 --- a/chrome/browser/policy/cloud/chrome_browser_cloud_management_helper.cc +++ b/chrome/browser/policy/cloud/chrome_browser_cloud_management_helper.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/policy/cloud/chrome_browser_cloud_management_helper.h" #include <utility> +#include <vector> #include "base/bind.h" #include "base/bind_helpers.h" @@ -163,10 +164,10 @@ } void MachineLevelUserCloudPolicyFetcher::TryToFetchPolicy() { - std::string dm_token = BrowserDMTokenStorage::Get()->RetrieveDMToken(); + auto dm_token = BrowserDMTokenStorage::Get()->RetrieveBrowserDMToken(); std::string client_id = BrowserDMTokenStorage::Get()->RetrieveClientId(); - if (!dm_token.empty() && !client_id.empty()) - SetupRegistrationAndFetchPolicy(dm_token, client_id); + if (dm_token.is_valid() && !client_id.empty()) + SetupRegistrationAndFetchPolicy(dm_token.value(), client_id); } } // namespace policy
diff --git a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java index 8e7580b..e6a92498 100644 --- a/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java +++ b/chrome/browser/preferences/android/java/src/org/chromium/chrome/browser/preferences/ChromePreferenceKeys.java
@@ -12,7 +12,6 @@ * Do not remove constants from here. Keys that were used in past versions but are not used anymore * cannot be reused. Mark them as @Deprecated. * - * TODO(crbug.com/1022107): Finish moving constants from ChromePreferenceManager. * TODO(crbug.com/1013781): Implement key deprecation. For now, just mark them as @Deprecated. */ public final class ChromePreferenceKeys { @@ -98,5 +97,204 @@ public static final String CONTEXTUAL_SEARCH_CURRENT_WEEK_NUMBER = "contextual_search_current_week_number"; + /** + * Whether the promotion for data reduction has been skipped on first invocation. + * Default value is false. + */ + public static final String PROMOS_SKIPPED_ON_FIRST_START = "promos_skipped_on_first_start"; + public static final String SIGNIN_PROMO_LAST_SHOWN_MAJOR_VERSION = + "signin_promo_last_shown_chrome_version"; + public static final String SIGNIN_PROMO_LAST_SHOWN_ACCOUNT_NAMES = + "signin_promo_last_shown_account_names"; + + /** + * This value was used prior to KitKat to keep existing low-end devices on the normal UI rather + * than the simplified UI. + * + * This value may still exist in shared preferences file. Do not reuse. + */ + @Deprecated + private static final String ALLOW_LOW_END_DEVICE_UI = "allow_low_end_device_ui"; + + @Deprecated + private static final String PREF_WEBSITE_SETTINGS_FILTER = "website_settings_filter"; + + /** + * Whether Chrome is set as the default browser. + * Default value is false. + */ + public static final String CHROME_DEFAULT_BROWSER = "applink.chrome_default_browser"; + + /** + * Deprecated in M70. This value may still exist in the shared preferences file. Do not reuse. + */ + @Deprecated + private static final String CHROME_MODERN_DESIGN_ENABLED_KEY = "chrome_modern_design_enabled"; + + /** + * Whether or not the home page button is force enabled. + * Default value is false. + */ + @Deprecated + private static final String HOME_PAGE_BUTTON_FORCE_ENABLED_KEY = + "home_page_button_force_enabled"; + + /** + * Whether or not the homepage tile will be shown. + * Default value is false. + */ + @Deprecated + private static final String HOMEPAGE_TILE_ENABLED_KEY = "homepage_tile_enabled"; + + /** + * Whether or not the new tab page button is enabled. + * Default value is false. + */ + @Deprecated + private static final String NTP_BUTTON_ENABLED_KEY = "ntp_button_enabled"; + + /** + * Deprecated in M71. This value may still exist in the shared preferences file. Do not reuse. + */ + @Deprecated + private static final String NTP_BUTTON_VARIANT_KEY = "ntp_button_variant"; + + /** + * Deprecated in M77. This value may still exist in shared preferences file. Do not reuse. + */ + @Deprecated + private static final String TAB_PERSISTENT_STORE_TASK_RUNNER_ENABLED_KEY = + "tab_persistent_store_task_runner_enabled"; + + /** + * Deprecated in M75. This value may still exist in shared preferences file. Do not reuse. + */ + @Deprecated + private static final String INFLATE_TOOLBAR_ON_BACKGROUND_THREAD_KEY = + "inflate_toolbar_on_background_thread"; + + /** + * The current theme setting in the user settings. + * Default value is -1. Use NightModeUtils#getThemeSetting() to retrieve current setting or + * default theme. + */ + public static final String UI_THEME_SETTING_KEY = "ui_theme_setting"; + + /** + * Whether or not darken websites is enabled. + * Default value is false. + */ + public static final String DARKEN_WEBSITES_ENABLED_KEY = "darken_websites_enabled"; + + /** + * Marks that the content suggestions surface has been shown. + * Default value is false. + */ + public static final String CONTENT_SUGGESTIONS_SHOWN_KEY = "content_suggestions_shown"; + + /** + * Whether the user dismissed the personalized sign in promo from the Settings. + * Default value is false. + */ + public static final String SETTINGS_PERSONALIZED_SIGNIN_PROMO_DISMISSED = + "settings_personalized_signin_promo_dismissed"; + /** + * Whether the user dismissed the personalized sign in promo from the new tab page. + * Default value is false. + */ + public static final String NTP_SIGNIN_PROMO_DISMISSED = + "ntp.personalized_signin_promo_dismissed"; + + public static final String NTP_SIGNIN_PROMO_SUPPRESSION_PERIOD_START = + "ntp.signin_promo_suppression_period_start"; + + public static final String SUCCESS_UPLOAD_SUFFIX = "_crash_success_upload"; + public static final String FAILURE_UPLOAD_SUFFIX = "_crash_failure_upload"; + + /** + * Deprecated in M76. This value may still exist in the shared preferences file. Do not reuse. + */ + @Deprecated + private static final String SOLE_INTEGRATION_ENABLED_KEY = "sole_integration_enabled"; + + public static final String VERIFIED_DIGITAL_ASSET_LINKS = "verified_digital_asset_links"; + public static final String TRUSTED_WEB_ACTIVITY_DISCLOSURE_ACCEPTED_PACKAGES = + "trusted_web_activity_disclosure_accepted_packages"; + + /** + * Whether VR assets component should be registered on startup. + * Default value is false. + */ + public static final String SHOULD_REGISTER_VR_ASSETS_COMPONENT_ON_STARTUP = + "should_register_vr_assets_component_on_startup"; + + /* + * Whether the simplified tab switcher is enabled when accessibility mode is enabled. Keep in + * sync with accessibility_preferences.xml. + * Default value is true. + */ + public static final String ACCESSIBILITY_TAB_SWITCHER = "accessibility_tab_switcher"; + + /** + * When the user is shown a badge that the current Android OS version is unsupported, and they + * tap it to display the menu (which has additional information), we store the current version + * of Chrome to this preference to ensure we only show the badge once. The value is cleared + * if the Chrome version later changes. + */ + public static final String LATEST_UNSUPPORTED_VERSION = "android_os_unsupported_chrome_version"; + + /** + * Keys for deferred recording of the outcomes of showing the clear data dialog after + * Trusted Web Activity client apps are uninstalled or have their data cleared. + */ + public static final String TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_UNINSTALL = + "twa_dialog_number_of_dismissals_on_uninstall"; + public static final String TWA_DIALOG_NUMBER_OF_DISMISSALS_ON_CLEAR_DATA = + "twa_dialog_number_of_dismissals_on_clear_data"; + + /** Key for deferred recording of WebAPK uninstalls. */ + @Deprecated + private static final String WEBAPK_NUMBER_OF_UNINSTALLS = "webapk_number_of_uninstalls"; + + /** Key for deferred recording of list of uninstalled WebAPK packages. */ + public static final String WEBAPK_UNINSTALLED_PACKAGES = "webapk_uninstalled_packages"; + + /** + * Key for whether it allows to start in service manager only mode. + * Default value is false. + */ + public static final String ALLOW_STARTING_SERVICE_MANAGER_ONLY_KEY = + "allow_starting_service_manager_only"; + + /** + * Deprecated keys for Chrome Home. + */ + @Deprecated + private static final String CHROME_HOME_USER_ENABLED_KEY = "chrome_home_user_enabled"; + @Deprecated + private static final String CHROME_HOME_OPT_OUT_SNACKBAR_SHOWN = + "chrome_home_opt_out_snackbar_shown"; + @Deprecated + private static final String CHROME_HOME_INFO_PROMO_SHOWN_KEY = "chrome_home_info_promo_shown"; + @Deprecated + private static final String CHROME_HOME_SHARED_PREFERENCES_KEY = "chrome_home_enabled_date"; + + /** + * Contains a trial group that was used to determine whether the reached code profiler should be + * enabled. + */ + public static final String REACHED_CODE_PROFILER_GROUP_KEY = "reached_code_profiler_group"; + + /** + * Key to cache whether offline indicator v2 (persistent offline indicator) is enabled. + */ + public static final String OFFLINE_INDICATOR_V2_ENABLED_KEY = "offline_indicator_v2_enabled"; + + /** + * Previously used to migrate {@link PrefServiceBridge} preferences to current version. + */ + @Deprecated + private static final String MIGRATION_PREF_KEY = "PrefMigrationVersion"; + private ChromePreferenceKeys() {} }
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index 2cefced..a842791 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -381,34 +381,27 @@ ] } -# TODO(https://crbug.com/930109): Figure out why this test fails on MAC ASAN. -if (!is_asan || !is_mac) { - js2gtest("resources_unitjs_tests") { - test_type = "webui" - sources = [ - "gaia_auth_host/password_change_authenticator_test.unitjs", - ] +js2gtest("resources_unitjs_tests") { + test_type = "webui" + sources = [ + "gaia_auth_host/password_change_authenticator_test.unitjs", + ] - # This has to be a gen_include, so it doesn't collide with other js2gtests - gen_include_files = [ "//ui/webui/resources/js/cr.js" ] + # This has to be a gen_include, so it doesn't collide with other js2gtests + gen_include_files = [ "//ui/webui/resources/js/cr.js" ] - # But these have to be extra_js_files, since it uses a native object - # EventTarget, which doesn't work at compile time. - extra_js_files = [ - "//ui/webui/resources/js/cr/event_target.js", - "gaia_auth_host/password_change_authenticator.js", - ] - defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] - } + # But these have to be extra_js_files, since it uses a native object + # EventTarget, which doesn't work at compile time. + extra_js_files = [ + "//ui/webui/resources/js/cr/event_target.js", + "gaia_auth_host/password_change_authenticator.js", + ] + defines = [ "HAS_OUT_OF_PROC_TEST_RUNNER" ] +} - source_set("browser_tests") { - testonly = true - deps = [ - ":resources_unitjs_tests", - ] - } -} else { - source_set("browser_tests") { - testonly = true - } +source_set("browser_tests") { + testonly = true + deps = [ + ":resources_unitjs_tests", + ] }
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.html b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.html index 1428af5a..62ec58f 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.html +++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.html
@@ -24,6 +24,16 @@ } </style> <div class="settings-box first"> + <div id="featureEnabledLabel" class="start"> + PLACEHOLDER Enable OS sync + </div> + <cr-toggle checked="{{osSyncPrefs.featureEnabled}}" + on-change="onFeatureEnabledChanged_" + aria-labelledby="featureEnabledLabel"> + </cr-toggle> + </div> + <!-- TODO(jamescook): Hide or disable everything when feature is off. --> + <div class="settings-box"> <div id="syncEverythingCheckboxLabel" class="start"> $i18n{syncEverythingCheckboxLabel} </div>
diff --git a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.js b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.js index 65ecd86..b1fd6e57 100644 --- a/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.js +++ b/chrome/browser/resources/settings/chromeos/os_people_page/os_sync_controls.js
@@ -87,6 +87,16 @@ }, /** + * Handler for when the feature enabled checkbox is changed. + * @param {!Event} event + * @private + */ + onFeatureEnabledChanged_: function(event) { + this.set('osSyncPrefs.featureEnabled', !!event.target.checked); + this.sendOsSyncDatatypes_(); + }, + + /** * Handler for when the sync all data types checkbox is changed. * @param {!Event} event * @private @@ -110,14 +120,14 @@ } } - this.onSingleSyncDataTypeChanged_(); + this.sendOsSyncDatatypes_(); }, /** - * Handler for when any sync data type checkbox is changed. + * Sends the osSyncPrefs dictionary back to the C++ handler. * @private */ - onSingleSyncDataTypeChanged_: function() { + sendOsSyncDatatypes_: function() { assert(this.osSyncPrefs); this.browserProxy_.setOsSyncDatatypes(this.osSyncPrefs); },
diff --git a/chrome/browser/signin/signin_util_win.cc b/chrome/browser/signin/signin_util_win.cc index dcf3887a..1e310eb 100644 --- a/chrome/browser/signin/signin_util_win.cc +++ b/chrome/browser/signin/signin_util_win.cc
@@ -65,7 +65,7 @@ // Finish the process of import credentials. This is either called directly // from ImportCredentialsFromProvider() if a browser window for the profile is // already available or is delayed until a browser can first be opened. -void FinishImportCredentialsFromProvider(const std::string& account_id, +void FinishImportCredentialsFromProvider(const CoreAccountId& account_id, Browser* browser, Profile* profile, Profile::CreateStatus status) { @@ -111,7 +111,7 @@ AboutSigninInternalsFactory::GetInstance()->GetForProfile(profile); signin_internals->OnAuthenticationResultReceived("Credential Provider"); - std::string account_id = + CoreAccountId account_id = IdentityManagerFactory::GetForProfile(profile) ->GetAccountsMutator() ->AddOrUpdateAccount(base::UTF16ToUTF8(gaia_id),
diff --git a/chrome/browser/sync/chrome_sync_client.cc b/chrome/browser/sync/chrome_sync_client.cc index adbf54e..5376da21 100644 --- a/chrome/browser/sync/chrome_sync_client.cc +++ b/chrome/browser/sync/chrome_sync_client.cc
@@ -77,6 +77,7 @@ #include "components/sync/engine/passive_model_worker.h" #include "components/sync/engine/sequenced_model_worker.h" #include "components/sync/engine/ui_model_worker.h" +#include "components/sync/model/model_type_store.h" #include "components/sync/model/model_type_store_service.h" #include "components/sync/model_impl/forwarding_model_type_controller_delegate.h" #include "components/sync_bookmarks/bookmark_sync_service.h" @@ -120,13 +121,16 @@ #if defined(OS_CHROMEOS) #include "chrome/browser/chromeos/arc/arc_util.h" +#include "chrome/browser/chromeos/printing/printers_model_type_controller.h" #include "chrome/browser/chromeos/printing/printers_sync_bridge.h" #include "chrome/browser/chromeos/printing/synced_printers_manager.h" #include "chrome/browser/chromeos/printing/synced_printers_manager_factory.h" +#include "chrome/browser/chromeos/sync/os_preferences_model_type_controller.h" #include "chrome/browser/sync/wifi_configuration_sync_service_factory.h" #include "chrome/browser/ui/app_list/arc/arc_package_sync_model_type_controller.h" #include "chrome/browser/ui/app_list/arc/arc_package_syncable_service.h" #include "chromeos/components/sync_wifi/wifi_configuration_sync_service.h" +#include "chromeos/constants/chromeos_features.h" #include "components/arc/arc_util.h" #endif // defined(OS_CHROMEOS) @@ -301,6 +305,9 @@ const base::RepeatingClosure dump_stack = base::BindRepeating( &syncer::ReportUnrecoverableError, chrome::GetChannel()); + syncer::RepeatingModelTypeStoreFactory model_type_store_factory = + GetModelTypeStoreService()->GetStoreFactory(); + if (!disabled_types.Has(syncer::SECURITY_EVENTS)) { syncer::ModelTypeControllerDelegate* delegate = SecurityEventRecorderFactory::GetForProfile(profile_) @@ -330,7 +337,7 @@ // disabled. if (!disabled_types.Has(syncer::APPS)) { controllers.push_back(std::make_unique<ExtensionModelTypeController>( - syncer::APPS, GetModelTypeStoreService()->GetStoreFactory(), + syncer::APPS, model_type_store_factory, GetSyncableServiceForType(syncer::APPS), dump_stack, profile_)); } @@ -338,7 +345,7 @@ // disabled. if (!disabled_types.Has(syncer::EXTENSIONS)) { controllers.push_back(std::make_unique<ExtensionModelTypeController>( - syncer::EXTENSIONS, GetModelTypeStoreService()->GetStoreFactory(), + syncer::EXTENSIONS, model_type_store_factory, GetSyncableServiceForType(syncer::EXTENSIONS), dump_stack, profile_)); } @@ -346,8 +353,7 @@ // disabled. if (!disabled_types.Has(syncer::EXTENSION_SETTINGS)) { controllers.push_back(std::make_unique<ExtensionSettingModelTypeController>( - syncer::EXTENSION_SETTINGS, - GetModelTypeStoreService()->GetStoreFactory(), + syncer::EXTENSION_SETTINGS, model_type_store_factory, extensions::settings_sync_util::GetSyncableServiceProvider( profile_, syncer::EXTENSION_SETTINGS), dump_stack, profile_)); @@ -357,7 +363,7 @@ // disabled. if (!disabled_types.Has(syncer::APP_SETTINGS)) { controllers.push_back(std::make_unique<ExtensionSettingModelTypeController>( - syncer::APP_SETTINGS, GetModelTypeStoreService()->GetStoreFactory(), + syncer::APP_SETTINGS, model_type_store_factory, extensions::settings_sync_util::GetSyncableServiceProvider( profile_, syncer::APP_SETTINGS), dump_stack, profile_)); @@ -380,7 +386,7 @@ // Theme sync is enabled by default. Register unless explicitly disabled. if (!disabled_types.Has(syncer::THEMES)) { controllers.push_back(std::make_unique<ExtensionModelTypeController>( - syncer::THEMES, GetModelTypeStoreService()->GetStoreFactory(), + syncer::THEMES, model_type_store_factory, GetSyncableServiceForType(syncer::THEMES), dump_stack, profile_)); } @@ -389,8 +395,7 @@ if (!disabled_types.Has(syncer::SEARCH_ENGINES)) { controllers.push_back( std::make_unique<syncer::SyncableServiceBasedModelTypeController>( - syncer::SEARCH_ENGINES, - GetModelTypeStoreService()->GetStoreFactory(), + syncer::SEARCH_ENGINES, model_type_store_factory, GetSyncableServiceForType(syncer::SEARCH_ENGINES), dump_stack)); } #endif // !defined(OS_ANDROID) @@ -401,7 +406,7 @@ if (!chromeos::switches::IsTabletFormFactor()) { controllers.push_back( std::make_unique<syncer::SyncableServiceBasedModelTypeController>( - syncer::APP_LIST, GetModelTypeStoreService()->GetStoreFactory(), + syncer::APP_LIST, model_type_store_factory, GetSyncableServiceForType(syncer::APP_LIST), dump_stack)); } #endif // BUILDFLAG(ENABLE_APP_LIST) @@ -411,7 +416,7 @@ if (!disabled_types.Has(syncer::DICTIONARY)) { controllers.push_back( std::make_unique<syncer::SyncableServiceBasedModelTypeController>( - syncer::DICTIONARY, GetModelTypeStoreService()->GetStoreFactory(), + syncer::DICTIONARY, model_type_store_factory, GetSyncableServiceForType(syncer::DICTIONARY), dump_stack)); } #endif // defined(OS_LINUX) || defined(OS_WIN) @@ -420,10 +425,30 @@ if (arc::IsArcAllowedForProfile(profile_) && !arc::IsArcAppSyncFlowDisabled()) { controllers.push_back(std::make_unique<ArcPackageSyncModelTypeController>( - GetModelTypeStoreService()->GetStoreFactory(), + model_type_store_factory, GetSyncableServiceForType(syncer::ARC_PACKAGE), dump_stack, sync_service, profile_)); } + if (chromeos::features::IsSplitSettingsSyncEnabled()) { + if (!disabled_types.Has(syncer::OS_PREFERENCES)) { + controllers.push_back(std::make_unique<OsPreferencesModelTypeController>( + syncer::OS_PREFERENCES, model_type_store_factory, + GetSyncableServiceForType(syncer::OS_PREFERENCES), dump_stack, + profile_->GetPrefs(), sync_service)); + } + if (!disabled_types.Has(syncer::OS_PRIORITY_PREFERENCES)) { + controllers.push_back(std::make_unique<OsPreferencesModelTypeController>( + syncer::OS_PRIORITY_PREFERENCES, model_type_store_factory, + GetSyncableServiceForType(syncer::OS_PRIORITY_PREFERENCES), + dump_stack, profile_->GetPrefs(), sync_service)); + } + if (!disabled_types.Has(syncer::PRINTERS)) { + controllers.push_back(std::make_unique<PrintersModelTypeController>( + std::make_unique<syncer::ForwardingModelTypeControllerDelegate>( + GetControllerDelegateForModelType(syncer::PRINTERS).get()), + profile_->GetPrefs(), sync_service)); + } + } #endif // defined(OS_CHROMEOS) return controllers;
diff --git a/chrome/browser/sync/test/integration/two_client_os_preferences_sync_test.cc b/chrome/browser/sync/test/integration/two_client_os_preferences_sync_test.cc index 2f65a51..38727a6a 100644 --- a/chrome/browser/sync/test/integration/two_client_os_preferences_sync_test.cc +++ b/chrome/browser/sync/test/integration/two_client_os_preferences_sync_test.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/sync/test/integration/sync_test.h" #include "chromeos/constants/chromeos_features.h" #include "components/prefs/pref_service.h" +#include "components/sync/base/pref_names.h" #include "testing/gtest/include/gtest/gtest.h" using preferences_helper::ChangeStringPref; @@ -35,6 +36,15 @@ // Needed for AwaitQuiescence(). bool TestUsesSelfNotifications() override { return true; } + bool SetupClients() override { + bool result = SyncTest::SetupClients(); + for (Profile* profile : GetAllProfiles()) { + profile->GetPrefs()->SetBoolean(syncer::prefs::kOsSyncFeatureEnabled, + true); + } + return result; + } + private: // The names |scoped_feature_list_| and |feature_list_| are both used in // superclasses.
diff --git a/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc b/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc index 80a800e..f4644123 100644 --- a/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc +++ b/chrome/browser/ui/ash/overview_window_drag_interactive_uitest.cc
@@ -122,8 +122,7 @@ DISALLOW_COPY_AND_ASSIGN(OverviewWindowDragTest); }; -// Flakily crashes (likely use-after-free). crbug.com/1021936 -IN_PROC_BROWSER_TEST_P(OverviewWindowDragTest, DISABLED_NormalDrag) { +IN_PROC_BROWSER_TEST_P(OverviewWindowDragTest, NormalDrag) { BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); aura::Window* browser_window = browser_view->GetWidget()->GetNativeWindow(); ui_controls::SendKeyPress(browser_window, ui::VKEY_MEDIA_LAUNCH_APP1,
diff --git a/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc b/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc index 3a0a9c2..e971527 100644 --- a/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc +++ b/chrome/browser/ui/ash/screen_rotation_interactive_uitest.cc
@@ -154,8 +154,7 @@ waiter.Wait(); } -// Flakily crashes. - crbug.com/1021936 -IN_PROC_BROWSER_TEST_P(ScreenRotationTest, DISABLED_RotateInTabletOverview) { +IN_PROC_BROWSER_TEST_P(ScreenRotationTest, RotateInTabletOverview) { // Browser window is used just to identify display. BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); gfx::NativeWindow browser_window =
diff --git a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc index c5712d8..57a8d68 100644 --- a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc +++ b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.cc
@@ -266,7 +266,7 @@ return; network_config_requested_ = true; - delegate_->OnNetworkConfigRequested(true); + delegate_->OnNetworkConfigRequested(); } void AppLaunchSplashScreenHandler::HandleContinueAppLaunch() { @@ -274,7 +274,7 @@ if (delegate_ && online_state_) { network_config_requested_ = false; network_config_done_ = true; - delegate_->OnNetworkConfigRequested(false); + delegate_->OnNetworkConfigFinished(); Show(); } }
diff --git a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h index 345b8edf..09690d5 100644 --- a/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h +++ b/chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h
@@ -28,7 +28,10 @@ virtual void OnCancelAppLaunch() {} // Invoked when the network config shortcut key is pressed. - virtual void OnNetworkConfigRequested(bool requested) {} + virtual void OnNetworkConfigRequested() {} + + // Invoked when the network config did prepare network and is closed. + virtual void OnNetworkConfigFinished() {} // Invoked when network state is changed. |online| is true if the device // is connected to the Internet.
diff --git a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc index 64b37e2..61589b9 100644 --- a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc +++ b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler.cc
@@ -78,6 +78,16 @@ const base::DictionaryValue* result; CHECK(args->GetDictionary(0, &result)); + // Start configuring the SyncService using the configuration passed to us from + // the JS layer. + syncer::SyncService* service = GetSyncService(); + + // If the sync engine has shutdown for some reason, just stop. + if (!service || !service->IsEngineInitialized()) { + sync_blocker_.reset(); + return; + } + bool sync_all_os_types; CHECK(result->GetBoolean("syncAllOsTypes", &sync_all_os_types)); @@ -91,23 +101,17 @@ selected_types.Put(type); } - // Start configuring the SyncService using the configuration passed to us from - // the JS layer. - syncer::SyncService* service = GetSyncService(); - - // If the sync engine has shutdown for some reason, just stop. - if (!service || !service->IsEngineInitialized()) { - sync_blocker_.reset(); - return; - } - // Filter out any non-registered types. The WebUI may echo back values from // toggles for in-development features hidden by feature flags. - selected_types.RetainAll( - service->GetUserSettings()->GetRegisteredSelectableOsTypes()); + SyncUserSettings* settings = service->GetUserSettings(); + selected_types.RetainAll(settings->GetRegisteredSelectableOsTypes()); + settings->SetSelectedOsTypes(sync_all_os_types, selected_types); - service->GetUserSettings()->SetSelectedOsTypes(sync_all_os_types, - selected_types); + // Update the enabled state last so that the selected types will be set before + // pref observers are notified of the change. + bool feature_enabled; + CHECK(result->GetBoolean("featureEnabled", &feature_enabled)); + settings->SetOsSyncFeatureEnabled(feature_enabled); // TODO(jamescook): Add metrics for selected types. } @@ -124,6 +128,7 @@ base::DictionaryValue args; SyncUserSettings* user_settings = service->GetUserSettings(); + args.SetBoolean("featureEnabled", user_settings->GetOsSyncFeatureEnabled()); // Tell the UI layer which data types are registered/enabled by the user. UserSelectableOsTypeSet registered_types = user_settings->GetRegisteredSelectableOsTypes();
diff --git a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc index a40e79a..223f97a 100644 --- a/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc +++ b/chrome/browser/ui/webui/chromeos/sync/os_sync_handler_unittest.cc
@@ -23,10 +23,10 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using base::DictionaryValue; using syncer::UserSelectableOsType; using syncer::UserSelectableOsTypeSet; using syncer::UserSelectableTypeSet; - using ::testing::_; using ::testing::ByMove; using ::testing::Mock; @@ -38,13 +38,16 @@ namespace { +enum FeatureConfig { FEATURE_ENABLED, FEATURE_DISABLED }; enum SyncAllConfig { SYNC_ALL_OS_TYPES, CHOOSE_WHAT_TO_SYNC }; // Creates a dictionary with the key/value pairs appropriate for a call to // HandleSetOsSyncDatatypes(). -base::DictionaryValue CreateSyncPrefs(SyncAllConfig sync_all, - UserSelectableOsTypeSet types) { - base::DictionaryValue result; +DictionaryValue CreateOsSyncPrefs(FeatureConfig feature, + SyncAllConfig sync_all, + UserSelectableOsTypeSet types) { + DictionaryValue result; + result.SetBoolean("featureEnabled", feature == FEATURE_ENABLED); result.SetBoolean("syncAllOsTypes", sync_all == SYNC_ALL_OS_TYPES); // Add all of our data types. result.SetBoolean("osPreferencesSynced", @@ -56,7 +59,7 @@ // Checks whether the passed |dictionary| contains a |key| with the given // |expected_value|. -void CheckBool(const base::DictionaryValue* dictionary, +void CheckBool(const DictionaryValue* dictionary, const std::string& key, bool expected_value) { bool actual_value; @@ -67,7 +70,7 @@ // Checks to make sure that the values stored in |dictionary| match the values // expected by the JS layer. -void CheckConfigDataTypeArguments(const base::DictionaryValue* dictionary, +void CheckConfigDataTypeArguments(const DictionaryValue* dictionary, SyncAllConfig config, UserSelectableOsTypeSet types) { CheckBool(dictionary, "syncAllOsTypes", config == SYNC_ALL_OS_TYPES); @@ -123,9 +126,10 @@ &OsSyncHandlerTest::OnSetupInProgressHandleDestroyed, base::Unretained(this)))))); - // Configure user settings with all types enabled. + // Configure user settings with the sync feature on and all types enabled. user_settings_ = mock_sync_service_->GetMockUserSettings(); - ON_CALL(*user_settings_, IsSyncRequested()).WillByDefault(Return(true)); + ON_CALL(*user_settings_, GetOsSyncFeatureEnabled()) + .WillByDefault(Return(true)); ON_CALL(*user_settings_, IsSyncAllOsTypesEnabled()) .WillByDefault(Return(true)); ON_CALL(*user_settings_, GetSelectedOsTypes()) @@ -153,9 +157,9 @@ in_progress_handle_destroyed_count_++; } - // Expects that the WebUI received an "os-sync-prefs-changed" event and + // Expects that an "os-sync-prefs-changed" event was sent to the WebUI and // returns the data passed to that event. - const base::DictionaryValue* ExpectSyncPrefsChanged() { + const DictionaryValue* ExpectOsSyncPrefsSent() { const content::TestWebUI::CallData& call_data = *web_ui_.call_data().back(); EXPECT_EQ("cr.webUIListenerCallback", call_data.function_name()); @@ -163,7 +167,7 @@ EXPECT_TRUE(call_data.arg1()->GetAsString(&event)); EXPECT_EQ(event, "os-sync-prefs-changed"); - const base::DictionaryValue* dictionary = nullptr; + const DictionaryValue* dictionary = nullptr; EXPECT_TRUE(call_data.arg2()->GetAsDictionary(&dictionary)); return dictionary; } @@ -184,12 +188,18 @@ int in_progress_handle_destroyed_count_ = 0; }; -TEST_F(OsSyncHandlerTest, SyncPrefsSentOnNavigateToPage) { +TEST_F(OsSyncHandlerTest, OsSyncPrefsSentOnNavigateToPage) { handler_->HandleDidNavigateToOsSyncPage(nullptr); + ASSERT_EQ(1U, web_ui_.call_data().size()); + ExpectOsSyncPrefsSent(); +} - EXPECT_EQ(1U, web_ui_.call_data().size()); - const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); - CheckBool(dictionary, "syncAllOsTypes", true); +TEST_F(OsSyncHandlerTest, OsSyncPrefsWhenFeatureIsDisabled) { + ON_CALL(*user_settings_, GetOsSyncFeatureEnabled()) + .WillByDefault(Return(false)); + handler_->HandleDidNavigateToOsSyncPage(nullptr); + const DictionaryValue* os_sync_prefs = ExpectOsSyncPrefsSent(); + CheckBool(os_sync_prefs, "featureEnabled", false); } TEST_F(OsSyncHandlerTest, OpenConfigPageBeforeSyncEngineInitialized) { @@ -211,8 +221,7 @@ // Update for sync prefs is sent. EXPECT_EQ(1U, web_ui_.call_data().size()); - const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); - CheckBool(dictionary, "syncAllOsTypes", true); + ExpectOsSyncPrefsSent(); } TEST_F(OsSyncHandlerTest, NavigateAwayDestroysInProgressHandle) { @@ -230,10 +239,18 @@ NotifySyncStateChanged(); } +TEST_F(OsSyncHandlerTest, UserDisablesFeature) { + base::ListValue list_args; + list_args.Append(CreateOsSyncPrefs(FEATURE_DISABLED, SYNC_ALL_OS_TYPES, + UserSelectableOsTypeSet::All())); + EXPECT_CALL(*user_settings_, SetOsSyncFeatureEnabled(false)); + handler_->HandleSetOsSyncDatatypes(&list_args); +} + TEST_F(OsSyncHandlerTest, TestSyncEverything) { base::ListValue list_args; - list_args.Append( - CreateSyncPrefs(SYNC_ALL_OS_TYPES, UserSelectableOsTypeSet::All())); + list_args.Append(CreateOsSyncPrefs(FEATURE_ENABLED, SYNC_ALL_OS_TYPES, + UserSelectableOsTypeSet::All())); EXPECT_CALL(*user_settings_, SetSelectedOsTypes(/*sync_all_os_types=*/true, _)); handler_->HandleSetOsSyncDatatypes(&list_args); @@ -245,7 +262,8 @@ for (UserSelectableOsType type : UserSelectableOsTypeSet::All()) { UserSelectableOsTypeSet types = {type}; base::ListValue list_args; - list_args.Append(CreateSyncPrefs(CHOOSE_WHAT_TO_SYNC, types)); + list_args.Append( + CreateOsSyncPrefs(FEATURE_ENABLED, CHOOSE_WHAT_TO_SYNC, types)); EXPECT_CALL(*user_settings_, SetSelectedOsTypes(false, types)); handler_->HandleSetOsSyncDatatypes(&list_args); @@ -255,8 +273,8 @@ TEST_F(OsSyncHandlerTest, TestSyncAllManually) { base::ListValue list_args; - list_args.Append( - CreateSyncPrefs(CHOOSE_WHAT_TO_SYNC, UserSelectableOsTypeSet::All())); + list_args.Append(CreateOsSyncPrefs(FEATURE_ENABLED, CHOOSE_WHAT_TO_SYNC, + UserSelectableOsTypeSet::All())); EXPECT_CALL(*user_settings_, SetSelectedOsTypes(false, UserSelectableOsTypeSet::All())); handler_->HandleSetOsSyncDatatypes(&list_args); @@ -265,7 +283,7 @@ TEST_F(OsSyncHandlerTest, ShowSetupSyncEverything) { handler_->HandleDidNavigateToOsSyncPage(nullptr); - const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); + const DictionaryValue* dictionary = ExpectOsSyncPrefsSent(); CheckBool(dictionary, "syncAllOsTypes", true); CheckBool(dictionary, "osPreferencesRegistered", true); CheckBool(dictionary, "printersRegistered", true); @@ -278,7 +296,7 @@ .WillByDefault(Return(false)); handler_->HandleDidNavigateToOsSyncPage(nullptr); - const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); + const DictionaryValue* dictionary = ExpectOsSyncPrefsSent(); CheckConfigDataTypeArguments(dictionary, CHOOSE_WHAT_TO_SYNC, UserSelectableOsTypeSet::All()); } @@ -292,7 +310,7 @@ handler_->HandleDidNavigateToOsSyncPage(nullptr); - const base::DictionaryValue* dictionary = ExpectSyncPrefsChanged(); + const DictionaryValue* dictionary = ExpectOsSyncPrefsSent(); CheckConfigDataTypeArguments(dictionary, CHOOSE_WHAT_TO_SYNC, types); Mock::VerifyAndClearExpectations(mock_sync_service_); }
diff --git a/chrome/browser/web_applications/web_app_install_task_unittest.cc b/chrome/browser/web_applications/web_app_install_task_unittest.cc index 59e85489..b183685 100644 --- a/chrome/browser/web_applications/web_app_install_task_unittest.cc +++ b/chrome/browser/web_applications/web_app_install_task_unittest.cc
@@ -1287,7 +1287,7 @@ std::unique_ptr<WebApplicationInfo> result = LoadAndRetrieveWebApplicationInfoWithIcons(url); - EXPECT_TRUE(!result); + EXPECT_FALSE(result); } { CreateDefaultDataToRetrieve(url); @@ -1296,7 +1296,7 @@ std::unique_ptr<WebApplicationInfo> result = LoadAndRetrieveWebApplicationInfoWithIcons(url); - EXPECT_TRUE(!result); + EXPECT_FALSE(result); } { CreateDefaultDataToRetrieve(start_url);
diff --git a/chrome/chrome_cleaner/engines/controllers/BUILD.gn b/chrome/chrome_cleaner/engines/controllers/BUILD.gn index 19ac2e1..d2052d0a 100644 --- a/chrome/chrome_cleaner/engines/controllers/BUILD.gn +++ b/chrome/chrome_cleaner/engines/controllers/BUILD.gn
@@ -208,7 +208,6 @@ "//chrome/chrome_cleaner/test:test_uws_catalog", "//chrome/chrome_cleaner/ui:cleaner_ui", "//chrome/chrome_cleaner/zip_archiver:common", - "//components/chrome_cleaner/public/interfaces", "//components/chrome_cleaner/test:test_name_helper", "//sandbox/win:sandbox", "//testing/gmock",
diff --git a/chrome/chrome_cleaner/engines/controllers/extension_removal_unittest.cc b/chrome/chrome_cleaner/engines/controllers/extension_removal_unittest.cc index 0ea9cc1..1cdce75 100644 --- a/chrome/chrome_cleaner/engines/controllers/extension_removal_unittest.cc +++ b/chrome/chrome_cleaner/engines/controllers/extension_removal_unittest.cc
@@ -50,7 +50,6 @@ #include "chrome/chrome_cleaner/test/test_settings_util.h" #include "chrome/chrome_cleaner/ui/silent_main_dialog.h" #include "chrome/chrome_cleaner/zip_archiver/zip_archiver.h" -#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom-test-utils.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/system/message_pipe.h" #include "sandbox/win/src/sandbox_factory.h" @@ -137,15 +136,12 @@ ExtensionCleanupTest() : mojo_task_runner_(MojoTaskRunner::Create()) {} void SetUp() override { EXPECT_CALL(mock_chrome_prompt_ipc_, MockPostPromptUserTask(_, _, _, _)) - .WillRepeatedly( - [](const std::vector<base::FilePath>& files_to_delete, - const std::vector<base::string16>& registry_keys, - const std::vector<base::string16>& extension_ids, - mojom::ChromePromptInterceptorForTesting::PromptUserCallback* - callback) { - std::move(*callback).Run( - mojom::PromptAcceptance::ACCEPTED_WITHOUT_LOGS); - }); + .WillRepeatedly([](const std::vector<base::FilePath>& files_to_delete, + const std::vector<base::string16>& registry_keys, + const std::vector<base::string16>& extension_ids, + ChromePromptIPC::PromptUserCallback* callback) { + std::move(*callback).Run(PromptUserResponse::ACCEPTED_WITHOUT_LOGS); + }); EXPECT_CALL(mock_chrome_prompt_ipc_, Initialize(_)); EXPECT_CALL(mock_chrome_prompt_ipc_, TryDeleteExtensions(_, _)) .WillRepeatedly([](base::OnceClosure delete_allowed_callback,
diff --git a/chrome/chrome_cleaner/ipc/BUILD.gn b/chrome/chrome_cleaner/ipc/BUILD.gn index 03fddfd..83c6e79 100644 --- a/chrome/chrome_cleaner/ipc/BUILD.gn +++ b/chrome/chrome_cleaner/ipc/BUILD.gn
@@ -32,9 +32,12 @@ ":mojo_task_runner", "//base", "//components/chrome_cleaner/public/interfaces", - "//components/chrome_cleaner/public/proto", "//mojo/public/cpp/platform", "//mojo/public/cpp/system", + ] + + public_deps = [ + "//components/chrome_cleaner/public/proto", "//third_party/protobuf:protobuf_lite", ] } @@ -128,7 +131,6 @@ deps = [ ":chrome_prompt_ipc", - "//components/chrome_cleaner/public/interfaces", "//testing/gmock", "//testing/gtest", ]
diff --git a/chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h b/chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h index 841c1b7..cbc8b7e 100644 --- a/chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h +++ b/chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h
@@ -8,13 +8,11 @@ #include <string> #include <vector> -#include "base/callback_forward.h" +#include "base/callback.h" +#include "base/files/file_path.h" #include "base/sequence_checker.h" #include "base/strings/string16.h" - -// This is kept in the base class for now to provide access to mojom enums which -// will be used in all classes. -#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h" +#include "components/chrome_cleaner/public/proto/chrome_prompt.pb.h" namespace chrome_cleaner { @@ -42,6 +40,17 @@ virtual void OnConnectionClosedAfterDone() = 0; }; + // If legacy Mojo IPC is in use this callback will be invoked by + // mojom::ChromePrompt::PromptUserCallback. Otherwise it will be invoked when + // a PromptUserResponse proto is received. + using PromptUserCallback = + base::OnceCallback<void(PromptUserResponse::PromptAcceptance)>; + + // If legacy Mojo IPC is in use this callback will be invoked by + // mojom::ChromePrompt::PromptUserCallback. Otherwise it is unused since + // DisableExtensions is unimplemented. + using DisableExtensionsCallback = base::OnceCallback<void(bool)>; + // Sets |error_handler| as the connection error handler and completes whatever // initialization that needs to be done separately from construction. This // object doesn't own the error handler pointer. @@ -56,13 +65,13 @@ const std::vector<base::FilePath>& files_to_delete, const std::vector<base::string16>& registry_keys, const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::PromptUserCallback callback) = 0; + PromptUserCallback callback) = 0; // Posts a PromptDisableExtensions() task to the IPC controller's thread. // Internal state must be State::kDoneInteraction when the posted task runs. virtual void PostDisableExtensionsTask( const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::DisableExtensionsCallback callback) = 0; + DisableExtensionsCallback callback) = 0; // Calls |delete_allowed_callback| if the IPC version supports deleting // extensions, |delete_not_allowed_callback| otherwise.
diff --git a/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.cc b/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.cc index cd77fa1..6f74874 100644 --- a/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.cc +++ b/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.cc
@@ -16,14 +16,14 @@ const std::vector<base::FilePath>& files_to_delete, const std::vector<base::string16>& registry_keys, const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::PromptUserCallback callback) { + PromptUserCallback callback) { MockPostPromptUserTask(files_to_delete, registry_keys, extension_ids, &callback); } void MockChromePromptIPC::PostDisableExtensionsTask( const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::DisableExtensionsCallback callback) { + DisableExtensionsCallback callback) { MockPostDisableExtensionsTask(extension_ids, &callback); }
diff --git a/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.h b/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.h index 495e93b7..06a78f3 100644 --- a/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.h +++ b/chrome/chrome_cleaner/ipc/mock_chrome_prompt_ipc.h
@@ -9,7 +9,6 @@ #include <vector> #include "chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h" -#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h" #include "testing/gmock/include/gmock/gmock.h" namespace chrome_cleaner { @@ -28,23 +27,22 @@ // Workaround for GMock's limitation, in which MOCK_METHOD* doesn't // accept base::OnceCallback parameters. Will forward any calls to // MockPost*() and pass along a raw pointer for |callback|. - void PostPromptUserTask( - const std::vector<base::FilePath>& files_to_delete, - const std::vector<base::string16>& registry_keys, - const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::PromptUserCallback callback) override; + void PostPromptUserTask(const std::vector<base::FilePath>& files_to_delete, + const std::vector<base::string16>& registry_keys, + const std::vector<base::string16>& extension_ids, + PromptUserCallback callback) override; void PostDisableExtensionsTask( const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::DisableExtensionsCallback callback) override; + DisableExtensionsCallback callback) override; MOCK_METHOD4(MockPostPromptUserTask, void(const std::vector<base::FilePath>& files_to_delete, const std::vector<base::string16>& registry_keys, const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::PromptUserCallback* callback)); + PromptUserCallback* callback)); MOCK_METHOD2(MockPostDisableExtensionsTask, void(const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::DisableExtensionsCallback* callback)); + DisableExtensionsCallback* callback)); }; } // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.cc b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.cc index c5bd0422..f0eec1b7 100644 --- a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.cc +++ b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.cc
@@ -69,29 +69,23 @@ const std::vector<base::FilePath>& files_to_delete, const std::vector<base::string16>& registry_keys, const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::PromptUserCallback callback) { + PromptUserCallback callback) { DCHECK(task_runner_); task_runner_->PostTask( FROM_HERE, - base::BindOnce( - &MojoChromePromptIPC::RunPromptUserTask, base::Unretained(this), - files_to_delete, registry_keys, extension_ids, - base::BindOnce(&MojoChromePromptIPC::OnChromeResponseReceived, - base::Unretained(this), std::move(callback)))); + base::BindOnce(&MojoChromePromptIPC::RunPromptUserTask, + base::Unretained(this), files_to_delete, registry_keys, + extension_ids, std::move(callback))); } void MojoChromePromptIPC::PostDisableExtensionsTask( const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::DisableExtensionsCallback callback) { + DisableExtensionsCallback callback) { DCHECK(task_runner_); task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &MojoChromePromptIPC::RunDisableExtensionsTask, - base::Unretained(this), extension_ids, - base::BindOnce( - &MojoChromePromptIPC::OnChromeResponseReceivedExtensions, - base::Unretained(this), std::move(callback)))); + FROM_HERE, base::BindOnce(&MojoChromePromptIPC::RunDisableExtensionsTask, + base::Unretained(this), extension_ids, + std::move(callback))); } void MojoChromePromptIPC::TryDeleteExtensions( @@ -106,22 +100,23 @@ } void MojoChromePromptIPC::OnChromeResponseReceived( - mojom::ChromePrompt::PromptUserCallback callback, + PromptUserCallback callback, mojom::PromptAcceptance prompt_acceptance) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(State::kWaitingForResponseFromChrome, state_); state_ = State::kDoneInteraction; - std::move(callback).Run(prompt_acceptance); + std::move(callback).Run( + static_cast<PromptUserResponse::PromptAcceptance>(prompt_acceptance)); } void MojoChromePromptIPC::OnChromeResponseReceivedExtensions( - mojom::ChromePrompt::DisableExtensionsCallback callback, - bool extensions_disabled_callback) { + DisableExtensionsCallback callback, + bool extensions_disabled) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(State::kDoneInteraction, state_); - std::move(callback).Run(extensions_disabled_callback); + std::move(callback).Run(extensions_disabled); } void MojoChromePromptIPC::OnConnectionError() { @@ -186,7 +181,7 @@ const std::vector<base::FilePath>& files_to_delete, const std::vector<base::string16>& registry_keys, const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::PromptUserCallback callback) { + PromptUserCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(chrome_prompt_service_); DCHECK(state_ != State::kUninitialized); @@ -200,24 +195,38 @@ state_ = State::kWaitingForResponseFromChrome; + // Mojo will invoke this callback when a response is received. The + // |prompt_acceptance| parameter is unbound and will be filled in by Mojo. + mojom::ChromePrompt::PromptUserCallback response_callback = + base::BindOnce(&MojoChromePromptIPC::OnChromeResponseReceived, + base::Unretained(this), std::move(callback)); + const auto& version_callback = base::BindRepeating( &MojoChromePromptIPC::PromptUserCheckVersion, base::Unretained(this), std::move(files_to_delete), std::move(registry_keys), // Uses the AdaptCallbackForRepeating because we are bound by the mojo API // to use a RepeatingCallback even though this only should be called once. - std::move(extension_ids), AdaptCallbackForRepeating(std::move(callback))); + std::move(extension_ids), + AdaptCallbackForRepeating(std::move(response_callback))); (*chrome_prompt_service_).QueryVersion(version_callback); } void MojoChromePromptIPC::RunDisableExtensionsTask( const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::DisableExtensionsCallback callback) { + DisableExtensionsCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK(chrome_prompt_service_); DCHECK(state_ == State::kDoneInteraction); + // Mojo will invoke this callback when a response is received. The + // |extensions_disabled| parameter is unbound and will be filled in by Mojo. + mojom::ChromePrompt::DisableExtensionsCallback response_callback = + base::BindOnce(&MojoChromePromptIPC::OnChromeResponseReceivedExtensions, + base::Unretained(this), std::move(callback)); + (*chrome_prompt_service_) - ->DisableExtensions(std::move(extension_ids), std::move(callback)); + ->DisableExtensions(std::move(extension_ids), + std::move(response_callback)); } } // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h index 46ce19af..36d7e90 100644 --- a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h +++ b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc.h
@@ -37,7 +37,7 @@ // files_to_delete, registry_keys, // base::BindOnce(&ReceivePromptResult)); // -// void ReceivePromptResult(mojom::PromptAcceptance prompt_acceptance) { +// void ReceivePromptResult(PromptAcceptance prompt_acceptance) { // ... // } class MojoChromePromptIPC : public ChromePromptIPC { @@ -55,17 +55,16 @@ // response from Chrome is received, |callback| will run on the IPC // controller's thread; clients of this class are responsible for posting // response on the right thread. - void PostPromptUserTask( - const std::vector<base::FilePath>& files_to_delete, - const std::vector<base::string16>& registry_keys, - const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::PromptUserCallback callback) override; + void PostPromptUserTask(const std::vector<base::FilePath>& files_to_delete, + const std::vector<base::string16>& registry_keys, + const std::vector<base::string16>& extension_ids, + PromptUserCallback callback) override; // Posts a PromptDisableExtensions() task to the IPC controller's thread. // Internal state must be State::kDoneInteraction when the posted task runs. void PostDisableExtensionsTask( const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::DisableExtensionsCallback callback) override; + DisableExtensionsCallback callback) override; // Queries Chrome for its version of the ChromePrompt interface. If version // >= 3 calls |delete_allowed_callback|. Calls |delete_not_allowed_callback| @@ -89,24 +88,22 @@ void RunPromptUserTask(const std::vector<base::FilePath>& files_to_delete, const std::vector<base::string16>& registry_keys, const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::PromptUserCallback callback); + PromptUserCallback callback); void RunDisableExtensionsTask( const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::DisableExtensionsCallback callback); + DisableExtensionsCallback callback); - // Callback for ChromePrompt::PromptUser, internal state must be + // Callback for mojom::ChromePrompt::PromptUser, internal state must be // State::kWaitingForResponseFromChrome. Invokes callback(prompt_acceptance) // and transitions to state State::kDoneInteraction. - void OnChromeResponseReceived( - mojom::ChromePrompt::PromptUserCallback callback, - mojom::PromptAcceptance prompt_acceptance); + void OnChromeResponseReceived(PromptUserCallback callback, + mojom::PromptAcceptance prompt_acceptance); - // Callback for ChromePrompt::DisableExtensions, internal state must be - // State::kDoneInteraction. Invokes callback(extensions_deleted_callback). - void OnChromeResponseReceivedExtensions( - mojom::ChromePrompt::DisableExtensionsCallback callback, - bool extensions_deleted_callback); + // Callback for mojom::ChromePrompt::DisableExtensions, internal state must + // be State::kDoneInteraction. Invokes callback(extensions_deleted). + void OnChromeResponseReceivedExtensions(DisableExtensionsCallback callback, + bool extensions_deleted); // Connection error handler. Invokes either // error_handler_->OnConnectionClosed() or
diff --git a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc index d6df9ac..0d503b45 100644 --- a/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc +++ b/chrome/chrome_cleaner/ipc/mojo_chrome_prompt_ipc_unittest.cc
@@ -20,6 +20,7 @@ #include "chrome/chrome_cleaner/logging/scoped_logging.h" #include "chrome/chrome_cleaner/test/test_util.h" #include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h" +#include "components/chrome_cleaner/public/proto/chrome_prompt.pb.h" #include "components/chrome_cleaner/test/test_name_helper.h" #include "mojo/public/cpp/bindings/binding.h" #include "mojo/public/cpp/system/message_pipe.h" @@ -83,7 +84,7 @@ bool uws_expected; bool uwe_expected; bool with_registry_keys; - mojom::PromptAcceptance expected_prompt_acceptance; + PromptUserResponse::PromptAcceptance expected_prompt_acceptance; ParentDisconnected expected_parent_disconnected; }; @@ -110,7 +111,8 @@ EXPECT_EQ(kBadRegistryKey, registry_keys->front()); } CloseConnectionIf(ParentDisconnected::kWhileProcessingChildRequest); - std::move(callback).Run(test_config_.expected_prompt_acceptance); + std::move(callback).Run(static_cast<mojom::PromptAcceptance>( + test_config_.expected_prompt_acceptance)); if (!test_config_.uwe_expected) { CloseConnectionIf(ParentDisconnected::kOnDone); } @@ -162,8 +164,7 @@ protected: void CreateImpl(mojo::ScopedMessagePipeHandle mojo_pipe) override { - chrome_cleaner::mojom::ChromePromptRequest chrome_prompt_request( - std::move(mojo_pipe)); + mojom::ChromePromptRequest chrome_prompt_request(std::move(mojo_pipe)); mock_chrome_prompt_ = std::make_unique<MockChromePrompt>( test_config_, std::move(chrome_prompt_request)); // At this point, the child process should be connected. @@ -234,8 +235,9 @@ private: ~ChromePromptIPCChildProcess() override = default; - void ReceivePromptResult(base::OnceClosure done, - mojom::PromptAcceptance prompt_acceptance) { + void ReceivePromptResult( + base::OnceClosure done, + PromptUserResponse::PromptAcceptance prompt_acceptance) { CHECK_EQ(expected_prompt_acceptance(), prompt_acceptance); // Unblocks the main thread. std::move(done).Run(); @@ -259,11 +261,11 @@ command_line().HasSwitch(kIncludeRegistryKeysSwitch); } - mojom::PromptAcceptance expected_prompt_acceptance() const { + PromptUserResponse::PromptAcceptance expected_prompt_acceptance() const { int val = -1; CHECK(base::StringToInt( command_line().GetSwitchValueASCII(kExpectedPromptResultSwitch), &val)); - return static_cast<mojom::PromptAcceptance>(val); + return static_cast<PromptUserResponse::PromptAcceptance>(val); } }; @@ -326,12 +328,12 @@ : kSuccessExitCode; } -class ChromePromptIPCTest - : public ::testing::TestWithParam<std::tuple<bool, - bool, - bool, - mojom::PromptAcceptance, - ParentDisconnected>> { +class ChromePromptIPCTest : public ::testing::TestWithParam< + std::tuple<bool, + bool, + bool, + PromptUserResponse::PromptAcceptance, + ParentDisconnected>> { public: void SetUp() override { mojo_task_runner_ = MojoTaskRunner::Create(); } @@ -370,7 +372,7 @@ /*uws_expected=*/Values(false), /*uwe_expected=*/Values(false), /*with_registry_keys=*/Values(false), - Values(mojom::PromptAcceptance::DENIED), + Values(PromptUserResponse::DENIED), Values(ParentDisconnected::kNone, ParentDisconnected::kOnStartup)), GetParamNameForTest()); @@ -382,9 +384,9 @@ /*uws_expected=*/Values(true), /*uwe_expected=*/Bool(), /*with_registry_keys=*/Bool(), - Values(mojom::PromptAcceptance::ACCEPTED_WITH_LOGS, - mojom::PromptAcceptance::ACCEPTED_WITHOUT_LOGS, - mojom::PromptAcceptance::DENIED), + Values(PromptUserResponse::ACCEPTED_WITH_LOGS, + PromptUserResponse::ACCEPTED_WITHOUT_LOGS, + PromptUserResponse::DENIED), Values(ParentDisconnected::kNone, ParentDisconnected::kOnStartup, ParentDisconnected::kWhileProcessingChildRequest,
diff --git a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.cc b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.cc index b885af6..2fd6e79 100644 --- a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.cc +++ b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.cc
@@ -6,6 +6,7 @@ #include <windows.h> +#include "base/bind_helpers.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/win/win_util.h" @@ -105,7 +106,7 @@ std::string file_path_utf8; if (!base::UTF16ToUTF8(file_to_delete.value().c_str(), file_to_delete.value().size(), &file_path_utf8)) { - std::move(callback).Run(PromptAcceptance::DENIED); + std::move(callback).Run(PromptUserResponse::DENIED); return; } else { prompt_user_message.add_files_to_delete(file_path_utf8); @@ -116,7 +117,7 @@ std::string registry_key_utf8; if (!base::UTF16ToUTF8(registry_key.c_str(), registry_key.size(), ®istry_key_utf8)) { - std::move(callback).Run(PromptAcceptance::DENIED); + std::move(callback).Run(PromptUserResponse::DENIED); return; } else { prompt_user_message.add_registry_keys(registry_key_utf8); @@ -127,7 +128,7 @@ std::string extension_id_utf8; if (!base::UTF16ToUTF8(extension_id.c_str(), extension_id.size(), &extension_id_utf8)) { - std::move(callback).Run(PromptAcceptance::DENIED); + std::move(callback).Run(PromptUserResponse::DENIED); return; } else { prompt_user_message.add_extension_ids(extension_id_utf8); @@ -152,7 +153,8 @@ } // Receive the response from Chrome. - PromptAcceptance prompt_acceptance = WaitForPromptAcceptance(); + PromptUserResponse::PromptAcceptance prompt_acceptance = + WaitForPromptAcceptance(); if (state_ == State::kDoneInteraction) { return; @@ -208,7 +210,7 @@ WriteByPointer(request_content.data(), kMessageLength); } -ProtoChromePromptIPC::PromptAcceptance +PromptUserResponse::PromptAcceptance ProtoChromePromptIPC::WaitForPromptAcceptance() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_EQ(State::kWaitingForResponseFromChrome, state_); @@ -223,16 +225,16 @@ if (!::ReadFile(response_read_handle_.Get(), &response_length, sizeof(response_length), &bytes_read, nullptr)) { PLOG(ERROR) << "Reading the prompt acceptance message length failed."; - return PromptAcceptance::DENIED; + return PromptUserResponse::DENIED; } if (bytes_read != sizeof(response_length)) { PLOG(ERROR) << "Short read on the prompt acceptance message length."; - return PromptAcceptance::DENIED; + return PromptUserResponse::DENIED; } if (response_length == 0 || response_length > kMaxMessageLength) { PLOG(ERROR) << "Invalid message length received: " << response_length; - return PromptAcceptance::DENIED; + return PromptUserResponse::DENIED; } // Read the response. @@ -241,23 +243,23 @@ base::WriteInto(&response_content, response_length + 1), response_length, &bytes_read, nullptr)) { PLOG(ERROR) << "Reading the prompt acceptance message failed"; - return PromptAcceptance::DENIED; + return PromptUserResponse::DENIED; } if (bytes_read != response_length) { PLOG(ERROR) << "Short read on the prompt acceptance message."; - return PromptAcceptance::DENIED; + return PromptUserResponse::DENIED; } chrome_cleaner::PromptUserResponse response; if (!response.ParseFromString(response_content)) { LOG(ERROR) << "Parsing of prompt acceptance failed."; - return PromptAcceptance::DENIED; + return PromptUserResponse::DENIED; } // Successful execution. call_connection_closed.ReplaceClosure(base::DoNothing()); - return static_cast<PromptAcceptance>(response.prompt_acceptance()); + return response.prompt_acceptance(); } } // namespace chrome_cleaner
diff --git a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.h b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.h index 7bab58d..c2a7afd 100644 --- a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.h +++ b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc.h
@@ -19,14 +19,6 @@ public: static constexpr uint32_t kMaxMessageLength = 1 * 1024 * 1024; // 1M bytes - // Currently some mojom types are used to provide as drop-in replacement - // for the existing mojo based implementation. Since they are very simple - // they will stay essentially identical once the PromptAcceptance enum is - // replaced with a hand rolled one. - using PromptAcceptance = mojom::PromptAcceptance; - using PromptUserCallback = base::OnceCallback<void(PromptAcceptance)>; - using DisableExtensionsCallback = base::OnceCallback<void(bool)>; - ProtoChromePromptIPC(base::win::ScopedHandle response_read_handle, base::win::ScopedHandle request_write_handle); ~ProtoChromePromptIPC() override; @@ -62,7 +54,7 @@ void SendBuffer(const std::string& request_content); - PromptAcceptance WaitForPromptAcceptance(); + PromptUserResponse::PromptAcceptance WaitForPromptAcceptance(); template <typename T> void WriteByValue(T value) {
diff --git a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc index bc7a361..8bc29ed 100644 --- a/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc +++ b/chrome/chrome_cleaner/ipc/proto_chrome_prompt_ipc_unittest.cc
@@ -33,7 +33,6 @@ using base::win::ScopedHandle; using testing::Bool; using testing::Values; -using PromptAcceptance = ProtoChromePromptIPC::PromptAcceptance; constexpr char kIncludeUwSSwitch[] = "include-uws"; constexpr char kIncludeRegistryKeysSwitch[] = "include-registry-keys"; @@ -128,7 +127,8 @@ bool uws_expected = false; bool with_registry_keys = false; - PromptAcceptance expected_prompt_acceptance = PromptAcceptance::DENIED; + PromptUserResponse::PromptAcceptance expected_prompt_acceptance = + PromptUserResponse::DENIED; ChromeDisconnectPoint expected_disconnection_point = ChromeDisconnectPoint::kNone; }; @@ -378,31 +378,11 @@ } // Send a response to the cleaner with the expected values. - bool SendResponse(PromptAcceptance prompt_acceptance) { + bool SendResponse(PromptUserResponse::PromptAcceptance prompt_acceptance) { DCHECK(response_write_handle_.IsValid()); - chrome_cleaner::PromptUserResponse response; - - switch (prompt_acceptance) { - case PromptAcceptance::DENIED: - response.set_prompt_acceptance( - chrome_cleaner::PromptUserResponse::DENIED); - break; - case PromptAcceptance::ACCEPTED_WITH_LOGS: - response.set_prompt_acceptance( - chrome_cleaner::PromptUserResponse::ACCEPTED_WITH_LOGS); - break; - case PromptAcceptance::ACCEPTED_WITHOUT_LOGS: - response.set_prompt_acceptance( - chrome_cleaner::PromptUserResponse::ACCEPTED_WITHOUT_LOGS); - break; - case PromptAcceptance::UNSPECIFIED: - default: - response.set_prompt_acceptance( - chrome_cleaner::PromptUserResponse::UNSPECIFIED); - break; - } - + PromptUserResponse response; + response.set_prompt_acceptance(prompt_acceptance); return SendMessage(response); } @@ -430,7 +410,8 @@ kExpectedChromeDisconnectPointSwitch); expected_prompt_acceptance_ = - GetEnumFromCommandLine<PromptAcceptance>(kExpectedPromptResultSwitch); + GetEnumFromCommandLine<PromptUserResponse::PromptAcceptance>( + kExpectedPromptResultSwitch); } base::win::ScopedHandle ExtractHandleFromCommandLine( @@ -467,7 +448,7 @@ // Execute all steps of the prompt according to passed in test config. bool Run() { DCHECK_NE(expected_disconnect_point_, ChromeDisconnectPoint::kUnspecified); - DCHECK_NE(expected_prompt_acceptance_, PromptAcceptance::UNSPECIFIED); + DCHECK_NE(expected_prompt_acceptance_, PromptUserResponse::UNSPECIFIED); CloseConnectionIfDisconectionPointReached( ChromeDisconnectPoint::kOnStartup); @@ -575,7 +556,8 @@ ChromeDisconnectPoint expected_disconnect_point_ = ChromeDisconnectPoint::kUnspecified; - PromptAcceptance expected_prompt_acceptance_ = PromptAcceptance::UNSPECIFIED; + PromptUserResponse::PromptAcceptance expected_prompt_acceptance_ = + PromptUserResponse::UNSPECIFIED; const base::CommandLine* command_line_ = base::CommandLine::ForCurrentProcess(); }; @@ -594,7 +576,10 @@ class ProtoChromePromptIPCTest : public ::testing::TestWithParam< - std::tuple<bool, bool, PromptAcceptance, ChromeDisconnectPoint>> { + std::tuple<bool, + bool, + PromptUserResponse::PromptAcceptance, + ChromeDisconnectPoint>> { private: base::test::TaskEnvironment task_environment; }; @@ -611,7 +596,8 @@ &response_read_handle_, &response_write_handle_); } - void ValidateAcceptance(PromptAcceptance prompt_acceptance) { + void ValidateAcceptance( + PromptUserResponse::PromptAcceptance prompt_acceptance) { EXPECT_EQ(prompt_acceptance, test_config_.expected_prompt_acceptance); main_runloop_.Quit(); } @@ -746,7 +732,7 @@ testing::Combine( /*[>uws_expected=<]*/ Values(false), /*[>with_registry_keys=<]*/ Values(false), - Values(PromptAcceptance::DENIED), + Values(PromptUserResponse::DENIED), Values(ChromeDisconnectPoint::kNone, ChromeDisconnectPoint::kOnStartup)), GetParamNameForTest()); @@ -757,9 +743,9 @@ testing::Combine( /*uws_expected=*/Values(true), /*with_registry_keys=*/Bool(), - Values(PromptAcceptance::ACCEPTED_WITH_LOGS, - PromptAcceptance::ACCEPTED_WITHOUT_LOGS, - PromptAcceptance::DENIED), + Values(PromptUserResponse::ACCEPTED_WITH_LOGS, + PromptUserResponse::ACCEPTED_WITHOUT_LOGS, + PromptUserResponse::DENIED), Values(ChromeDisconnectPoint::kNone, ChromeDisconnectPoint::kOnStartup, ChromeDisconnectPoint::kAfterVersion, @@ -832,8 +818,9 @@ EXPECT_TRUE(mock_chrome_->ReadRequest(request_length, &request)); } - void ValidateAcceptance(PromptAcceptance expected_prompt_acceptance, - PromptAcceptance prompt_acceptance) { + void ValidateAcceptance( + PromptUserResponse::PromptAcceptance expected_prompt_acceptance, + PromptUserResponse::PromptAcceptance prompt_acceptance) { EXPECT_EQ(prompt_acceptance, expected_prompt_acceptance); main_runloop_.Quit(); } @@ -856,8 +843,7 @@ chrome_prompt_ipc_->PostPromptUserTask( {kInvalidFilePath}, {}, {}, base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance, - base::Unretained(this), - chrome_cleaner::PromptAcceptance::DENIED)); + base::Unretained(this), PromptUserResponse::DENIED)); // Providing an invalid file path will trigger an immediate denial from the // cleaner side. No communication will happen with Chrome so we do not call @@ -873,8 +859,7 @@ chrome_prompt_ipc_->PostPromptUserTask( {}, {kInvalidRegistryKey}, {}, base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance, - base::Unretained(this), - chrome_cleaner::PromptAcceptance::DENIED)); + base::Unretained(this), PromptUserResponse::DENIED)); // Providing an invalid registry key will trigger an immediate denial from the // cleaner side. No communication will happen with Chrome so we do not call @@ -891,8 +876,7 @@ chrome_prompt_ipc_->PostPromptUserTask( {}, {}, {kInvalidExtensionID}, base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance, - base::Unretained(this), - chrome_cleaner::PromptAcceptance::DENIED)); + base::Unretained(this), PromptUserResponse::DENIED)); // Providing an invalid extension id will trigger an immediate denial from the // cleaner side. No communication will happen with Chrome so we do not call @@ -910,13 +894,14 @@ {kNonASCIIFilePath}, {}, {}, base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance, base::Unretained(this), - chrome_cleaner::PromptAcceptance::ACCEPTED_WITH_LOGS)); + PromptUserResponse::ACCEPTED_WITH_LOGS)); // Expect the prompt message. ExpectMessage(); // Send back the response. - EXPECT_TRUE(mock_chrome_->SendResponse(PromptAcceptance::ACCEPTED_WITH_LOGS)); + EXPECT_TRUE( + mock_chrome_->SendResponse(PromptUserResponse::ACCEPTED_WITH_LOGS)); // Expect the close connection message. ExpectMessage(); @@ -933,7 +918,7 @@ {kNonASCIIFilePath}, {}, {}, base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance, base::Unretained(this), - chrome_cleaner::PromptAcceptance::ACCEPTED_WITH_LOGS)); + PromptUserResponse::ACCEPTED_WITH_LOGS)); // Expect the prompt message. ExpectMessage(); @@ -958,7 +943,7 @@ {kNonASCIIFilePath}, {}, {}, base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance, base::Unretained(this), - chrome_cleaner::PromptAcceptance::ACCEPTED_WITH_LOGS)); + PromptUserResponse::ACCEPTED_WITH_LOGS)); // Expect the prompt message. ExpectMessage(); @@ -983,14 +968,13 @@ {kNonASCIIFilePath}, {}, {}, base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance, base::Unretained(this), - chrome_cleaner::PromptAcceptance::ACCEPTED_WITH_LOGS)); + PromptUserResponse::ACCEPTED_WITH_LOGS)); // Expect the prompt message. ExpectMessage(); - chrome_cleaner::PromptUserResponse response; - response.set_prompt_acceptance( - chrome_cleaner::PromptUserResponse::ACCEPTED_WITH_LOGS); + PromptUserResponse response; + response.set_prompt_acceptance(PromptUserResponse::ACCEPTED_WITH_LOGS); std::string response_content; response.SerializeToString(&response_content); @@ -1020,14 +1004,13 @@ {kNonASCIIFilePath}, {}, {}, base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance, base::Unretained(this), - chrome_cleaner::PromptAcceptance::ACCEPTED_WITH_LOGS)); + PromptUserResponse::ACCEPTED_WITH_LOGS)); // Expect the prompt message. ExpectMessage(); - chrome_cleaner::PromptUserResponse response; - response.set_prompt_acceptance( - chrome_cleaner::PromptUserResponse::ACCEPTED_WITH_LOGS); + PromptUserResponse response; + response.set_prompt_acceptance(PromptUserResponse::ACCEPTED_WITH_LOGS); std::string response_content; response.SerializeToString(&response_content); @@ -1055,8 +1038,7 @@ chrome_prompt_ipc_->PostPromptUserTask( {kNonASCIIFilePath}, {}, {}, base::BindOnce(&ProtoChromePromptSameProcessTest::ValidateAcceptance, - base::Unretained(this), - chrome_cleaner::PromptAcceptance::UNSPECIFIED)); + base::Unretained(this), PromptUserResponse::UNSPECIFIED)); // Expect the prompt message. ExpectMessage();
diff --git a/chrome/chrome_cleaner/ui/BUILD.gn b/chrome/chrome_cleaner/ui/BUILD.gn index ea8933b..36eed5a1 100644 --- a/chrome/chrome_cleaner/ui/BUILD.gn +++ b/chrome/chrome_cleaner/ui/BUILD.gn
@@ -24,7 +24,11 @@ "//chrome/chrome_cleaner/pup_data:pup_data_base", "//chrome/chrome_cleaner/settings", "//components/chrome_cleaner/public/constants:constants", - "//components/chrome_cleaner/public/interfaces", + ] + + public_deps = [ + "//components/chrome_cleaner/public/proto", + "//third_party/protobuf:protobuf_lite", ] }
diff --git a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.cc b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.cc index ffb8bf7..2cad2ff 100644 --- a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.cc +++ b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.cc
@@ -81,24 +81,24 @@ void ChromeProxyMainDialog::PostPromptResultReceivedTask( scoped_refptr<base::SequencedTaskRunner> task_runner, - mojom::PromptAcceptance prompt_acceptance) { + PromptUserResponse::PromptAcceptance prompt_acceptance) { task_runner->PostTask( FROM_HERE, base::BindOnce(&ChromeProxyMainDialog::PromptResultReceived, base::Unretained(this), prompt_acceptance)); } void ChromeProxyMainDialog::PromptResultReceived( - mojom::PromptAcceptance prompt_acceptance) { + PromptUserResponse::PromptAcceptance prompt_acceptance) { Settings::GetInstance()->set_logs_allowed_in_cleanup_mode( - prompt_acceptance == mojom::PromptAcceptance::ACCEPTED_WITH_LOGS); + prompt_acceptance == PromptUserResponse::ACCEPTED_WITH_LOGS); delegate()->AcceptedCleanup( - prompt_acceptance == mojom::PromptAcceptance::ACCEPTED_WITH_LOGS || - prompt_acceptance == mojom::PromptAcceptance::ACCEPTED_WITHOUT_LOGS); + prompt_acceptance == PromptUserResponse::ACCEPTED_WITH_LOGS || + prompt_acceptance == PromptUserResponse::ACCEPTED_WITHOUT_LOGS); } void ChromeProxyMainDialog::PostCloseAfterReceivingResponseTask( scoped_refptr<base::SequencedTaskRunner> task_runner, - mojom::PromptAcceptance prompt_acceptance) { + PromptUserResponse::PromptAcceptance prompt_acceptance) { task_runner->PostTask( FROM_HERE, base::BindOnce(&ChromeProxyMainDialog::CloseAfterReceivingResponse, @@ -106,7 +106,7 @@ } void ChromeProxyMainDialog::CloseAfterReceivingResponse( - mojom::PromptAcceptance /*prompt_acceptance*/) { + PromptUserResponse::PromptAcceptance /*prompt_acceptance*/) { delegate()->OnClose(); }
diff --git a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.h b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.h index f734aed8..44537e4 100644 --- a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.h +++ b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog.h
@@ -14,7 +14,7 @@ #include "chrome/chrome_cleaner/ipc/chrome_prompt_ipc.h" #include "chrome/chrome_cleaner/ui/main_dialog_api.h" #include "components/chrome_cleaner/public/constants/result_codes.h" -#include "components/chrome_cleaner/public/interfaces/chrome_prompt.mojom.h" +#include "components/chrome_cleaner/public/proto/chrome_prompt.pb.h" namespace chrome_cleaner { @@ -46,22 +46,24 @@ // thread. void PostPromptResultReceivedTask( scoped_refptr<base::SequencedTaskRunner> task_runner, - mojom::PromptAcceptance prompt_acceptance); + PromptUserResponse::PromptAcceptance prompt_acceptance); // Handles the prompt acceptance result received from Chrome. This should // only be called by PostPromptResultReceivedTask(), that will handle posting // it to the right thread. - void PromptResultReceived(mojom::PromptAcceptance prompt_acceptance); + void PromptResultReceived( + PromptUserResponse::PromptAcceptance prompt_acceptance); // Callback for the Mojo IPC that posts CloseAfterReceivingResponse() on the // UI thread. void PostCloseAfterReceivingResponseTask( scoped_refptr<base::SequencedTaskRunner> task_runner, - mojom::PromptAcceptance prompt_acceptance); + PromptUserResponse::PromptAcceptance prompt_acceptance); // Closes the dialog after receiving a response from Chrome when no UwS is // found in the system. - void CloseAfterReceivingResponse(mojom::PromptAcceptance prompt_acceptance); + void CloseAfterReceivingResponse( + PromptUserResponse::PromptAcceptance prompt_acceptance); // Pointer to the wrapper for the Mojo IPC to send scan results to Chrome. ChromePromptIPC* chrome_prompt_ipc_;
diff --git a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog_unittest.cc b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog_unittest.cc index 879a71c2..18743d8 100644 --- a/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog_unittest.cc +++ b/chrome/chrome_cleaner/ui/chrome_proxy_main_dialog_unittest.cc
@@ -16,13 +16,13 @@ #include "chrome/chrome_cleaner/test/test_pup_data.h" #include "chrome/chrome_cleaner/test/test_settings_util.h" #include "chrome/chrome_cleaner/ui/mock_main_dialog_delegate.h" +#include "components/chrome_cleaner/public/proto/chrome_prompt.pb.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace chrome_cleaner { namespace { -using mojom::PromptAcceptance; using ::testing::_; using ::testing::Eq; using ::testing::Invoke; @@ -58,8 +58,8 @@ .WillOnce(Invoke([](const std::vector<base::FilePath>& files_to_delete, const std::vector<base::string16>& registry_keys, const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::PromptUserCallback* callback) { - std::move(*callback).Run(PromptAcceptance::DENIED); + ChromePromptIPC::PromptUserCallback* callback) { + std::move(*callback).Run(PromptUserResponse::DENIED); })); dialog_->NoPUPsFound(); @@ -77,7 +77,7 @@ } class ConfirmCleanupChromeProxyMainDialogTest - : public ::testing::TestWithParam<PromptAcceptance> { + : public ::testing::TestWithParam<PromptUserResponse::PromptAcceptance> { public: void SetUp() override { Settings::SetInstanceForTesting(&mock_settings_); } @@ -88,11 +88,12 @@ TEST_P(ConfirmCleanupChromeProxyMainDialogTest, ConfirmCleanup) { constexpr UwSId kFakePupId = 1024; - PromptAcceptance prompt_acceptance = GetParam(); + PromptUserResponse::PromptAcceptance prompt_acceptance = GetParam(); bool accept_cleanup = - prompt_acceptance == PromptAcceptance::ACCEPTED_WITH_LOGS || - prompt_acceptance == PromptAcceptance::ACCEPTED_WITHOUT_LOGS; - bool logs_allowed = prompt_acceptance == PromptAcceptance::ACCEPTED_WITH_LOGS; + prompt_acceptance == PromptUserResponse::ACCEPTED_WITH_LOGS || + prompt_acceptance == PromptUserResponse::ACCEPTED_WITHOUT_LOGS; + bool logs_allowed = + prompt_acceptance == PromptUserResponse::ACCEPTED_WITH_LOGS; base::test::SingleThreadTaskEnvironment task_environment( base::test::SingleThreadTaskEnvironment::MainThreadType::UI); @@ -139,7 +140,7 @@ const std::vector<base::FilePath>& files_to_delete, const std::vector<base::string16>& registry_keys, const std::vector<base::string16>& extension_ids, - mojom::ChromePrompt::PromptUserCallback* callback) { + ChromePromptIPC::PromptUserCallback* callback) { std::move(*callback).Run(prompt_acceptance); })); @@ -156,9 +157,9 @@ INSTANTIATE_TEST_SUITE_P( All, ConfirmCleanupChromeProxyMainDialogTest, - testing::Values(PromptAcceptance::ACCEPTED_WITH_LOGS, - PromptAcceptance::ACCEPTED_WITHOUT_LOGS, - PromptAcceptance::DENIED)); + testing::Values(PromptUserResponse::ACCEPTED_WITH_LOGS, + PromptUserResponse::ACCEPTED_WITHOUT_LOGS, + PromptUserResponse::DENIED)); } // namespace } // namespace chrome_cleaner
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.cc b/chrome/credential_provider/gaiacp/gaia_credential_base.cc index 5d01d00b..96653e9 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_base.cc
@@ -1174,7 +1174,7 @@ HRESULT CGaiaCredentialBase::UnAdvise(void) { LOGFN(INFO); - events_.Release(); + events_.Reset(); return S_OK; } @@ -1945,7 +1945,7 @@ HRESULT CGaiaCredentialBase::Terminate() { LOGFN(INFO); SetDeselected(); - provider_.Release(); + provider_.Reset(); return S_OK; }
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base.h b/chrome/credential_provider/gaiacp/gaia_credential_base.h index f33a7d37..e9d64b4 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base.h +++ b/chrome/credential_provider/gaiacp/gaia_credential_base.h
@@ -7,6 +7,8 @@ #include "chrome/credential_provider/gaiacp/stdafx.h" +#include <wrl/client.h> + #include <memory> #include "base/strings/string16.h" @@ -62,7 +64,7 @@ UIProcessInfo(); ~UIProcessInfo(); - CComPtr<IGaiaCredential> credential; + Microsoft::WRL::ComPtr<IGaiaCredential> credential; base::win::ScopedHandle logon_token; base::win::ScopedProcessInformation procinfo; StdParentHandles parent_handles; @@ -76,7 +78,9 @@ ~CGaiaCredentialBase(); // Members to access user credentials. - const CComPtr<IGaiaCredentialProvider>& provider() const { return provider_; } + const Microsoft::WRL::ComPtr<IGaiaCredentialProvider> provider() const { + return provider_; + } const CComBSTR& get_username() const { return username_; } const CComBSTR& get_password() const { return password_; } const CComBSTR& get_sid() const { return user_sid_; } @@ -269,8 +273,8 @@ HRESULT RecoverWindowsPasswordIfPossible(base::string16* recovered_password); - CComPtr<ICredentialProviderCredentialEvents> events_; - CComPtr<IGaiaCredentialProvider> provider_; + Microsoft::WRL::ComPtr<ICredentialProviderCredentialEvents> events_; + Microsoft::WRL::ComPtr<IGaiaCredentialProvider> provider_; // Handle to the logon UI process. HANDLE logon_ui_process_ = INVALID_HANDLE_VALUE;
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc index 0ac11f1..09dfa76 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_base_unittests.cc
@@ -5,6 +5,7 @@ #include <windows.h> #include <sddl.h> // For ConvertSidToStringSid() +#include <wrl/client.h> #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" @@ -67,13 +68,13 @@ TEST_F(GcpGaiaCredentialBaseTest, Advise) { // Create provider with credentials. This should Advise the credential. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); // Release ref count so the credential can be deleted by the call to // ReleaseProvider. - cred.Release(); + cred.Reset(); // Release the provider. This should unadvise the credential. ASSERT_EQ(S_OK, ReleaseProvider()); @@ -81,7 +82,7 @@ TEST_F(GcpGaiaCredentialBaseTest, SetSelected) { // Create provider and credential only. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); @@ -97,7 +98,7 @@ FakeInternetAvailabilityChecker::kHicForceNo); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); @@ -106,12 +107,12 @@ TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_GlsLoadingFailed) { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); // Fail loading the gls logon UI. test->FailLoadingGaiaLogonStub(); @@ -121,7 +122,7 @@ TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_Start) { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); @@ -130,12 +131,12 @@ TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_Finish) { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -159,12 +160,12 @@ TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_SetDeselectedBeforeReportResult) { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -211,12 +212,12 @@ TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_Abort) { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, test->SetDefaultExitCode(kUiecAbort)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -238,12 +239,12 @@ &first_sid)); ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount()); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -258,12 +259,12 @@ TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_MultipleCalls) { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); constexpr wchar_t kStartGlsEventName[] = L"GetSerialization_MultipleCalls_Wait"; @@ -325,16 +326,16 @@ base::UTF8ToUTF16(kDefaultGaiaId), base::string16(), &sid)); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(CPFS_HIDDEN, fake_credential_provider_credential_events()->GetFieldState( - cred, FID_FORGOT_PASSWORD_LINK)); + cred.Get(), FID_FORGOT_PASSWORD_LINK)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -344,11 +345,11 @@ if (!enable_forgot_password_registry_value) { ASSERT_EQ(CPFS_HIDDEN, fake_credential_provider_credential_events()->GetFieldState( - cred, FID_FORGOT_PASSWORD_LINK)); + cred.Get(), FID_FORGOT_PASSWORD_LINK)); } else { ASSERT_EQ(CPFS_DISPLAY_IN_SELECTED_TILE, fake_credential_provider_credential_events()->GetFieldState( - cred, FID_FORGOT_PASSWORD_LINK)); + cred.Get(), FID_FORGOT_PASSWORD_LINK)); } // Update the Windows password to be the real password created for the user. @@ -382,16 +383,16 @@ base::UTF8ToUTF16(kDefaultGaiaId), base::string16(), &sid)); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(CPFS_HIDDEN, fake_credential_provider_credential_events()->GetFieldState( - cred, FID_FORGOT_PASSWORD_LINK)); + cred.Get(), FID_FORGOT_PASSWORD_LINK)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -400,7 +401,7 @@ ASSERT_EQ(CPFS_DISPLAY_IN_SELECTED_TILE, fake_credential_provider_credential_events()->GetFieldState( - cred, FID_FORGOT_PASSWORD_LINK)); + cred.Get(), FID_FORGOT_PASSWORD_LINK)); // Check that the process has not finished yet. CREDENTIAL_PROVIDER_GET_SERIALIZATION_RESPONSE cpgsr; @@ -452,12 +453,12 @@ base::UTF8ToUTF16(kDefaultGaiaId), base::string16(), &sid)); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -499,12 +500,12 @@ base::UTF8ToUTF16(kDefaultGaiaId), base::string16(), &sid)); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -555,12 +556,12 @@ TEST_F(GcpGaiaCredentialBaseTest, GetSerialization_Cancel) { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); // This event is merely used to keep the gls running while it is cancelled // through SetDeselected(). @@ -586,7 +587,7 @@ TEST_F(GcpGaiaCredentialBaseTest, FailedUserCreation) { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); @@ -602,12 +603,12 @@ TEST_F(GcpGaiaCredentialBaseTest, StripEmailTLD) { USES_CONVERSION; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); constexpr char email[] = "foo@imfl.info"; @@ -622,7 +623,7 @@ TEST_F(GcpGaiaCredentialBaseTest, NewUserDisabledThroughUsageScenario) { USES_CONVERSION; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; // Set the other user tile so that we can get the anonymous credential // that may try create a new user. @@ -662,7 +663,7 @@ fake_user_array()->SetAccountOptions(CPAO_EMPTY_LOCAL); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); @@ -691,14 +692,14 @@ ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount()); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; // Create with invalid token handle response. SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse); ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); // User should have invalid token handle and be locked. EXPECT_FALSE( @@ -743,14 +744,14 @@ ASSERT_EQ(2ul, fake_os_user_manager()->GetUserCount()); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; // Create with valid token handle response and sign in the anonymous // credential with the user that should still be valid. ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -799,12 +800,12 @@ USES_CONVERSION; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); constexpr char email[] = "bar@gmail.com"; @@ -820,12 +821,12 @@ USES_CONVERSION; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); constexpr char email[] = "toto@googlemail.com"; @@ -840,12 +841,12 @@ TEST_F(GcpGaiaCredentialBaseTest, InvalidUsernameCharacters) { USES_CONVERSION; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); constexpr char email[] = "a\\[]:|<>+=;?*z@gmail.com"; @@ -861,12 +862,12 @@ USES_CONVERSION; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); constexpr char email[] = "areallylongemailadressdude@gmail.com"; @@ -881,12 +882,12 @@ TEST_F(GcpGaiaCredentialBaseTest, EmailTooLong2) { USES_CONVERSION; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); constexpr char email[] = "foo@areallylongdomaindude.com"; @@ -903,12 +904,12 @@ constexpr char email[] = "foo"; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, test->SetGlsEmailAddress(email)); @@ -924,12 +925,12 @@ constexpr char email[] = "@com"; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, test->SetGlsEmailAddress(email)); @@ -945,12 +946,12 @@ constexpr char email[] = "@.com"; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, test->SetGlsEmailAddress(email)); @@ -966,7 +967,7 @@ void SetUp() override; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred_; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred_; // The admin sdk users directory get URL. std::string get_cd_user_url_ = base::StringPrintf( "https://www.googleapis.com/admin/directory/v1/users/" @@ -996,8 +997,8 @@ fake_http_url_fetcher_factory()->SetFakeFailedResponse( GURL(gaia_urls_->oauth2_token_url().spec().c_str()), E_FAIL); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred_.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred_.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -1030,8 +1031,8 @@ GURL(gaia_urls_->oauth2_token_url().spec().c_str()), FakeWinHttpUrlFetcher::Headers(), "{}"); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred_.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred_.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -1066,8 +1067,8 @@ fake_http_url_fetcher_factory()->SetFakeResponse( GURL(get_cd_user_url_.c_str()), FakeWinHttpUrlFetcher::Headers(), "{}"); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred_.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred_.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -1096,8 +1097,8 @@ fake_http_url_fetcher_factory()->SetFakeFailedResponse( GURL(get_cd_user_url_.c_str()), E_FAIL); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred_.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred_.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -1150,8 +1151,8 @@ GURL(get_cd_user_url_.c_str()), FakeWinHttpUrlFetcher::Headers(), admin_sdk_response); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred_.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred_.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -1205,8 +1206,8 @@ GURL(get_cd_user_url_.c_str()), FakeWinHttpUrlFetcher::Headers(), admin_sdk_response); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred_.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred_.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -1294,12 +1295,12 @@ } // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); test->SetGlsEmailAddress(user_email); @@ -1428,7 +1429,7 @@ // Sign on once to store the password in the LSA { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); @@ -1469,12 +1470,12 @@ // automatically. { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); // Send back a different gaia password to force a password update. ASSERT_EQ(S_OK, test->SetGlsGaiaPassword(kNewPassword)); @@ -1485,8 +1486,8 @@ ASSERT_EQ(S_OK, StartLogonProcessAndWait()); - CComPtr<ITestCredentialProvider> test_provider; - ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider)); + Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider; + ASSERT_EQ(S_OK, created_provider().As(&test_provider)); // If either password storage or recovery failed then the user will need to // enter their old Windows password. @@ -1498,7 +1499,7 @@ // through escros service fails. ASSERT_EQ(CPFS_DISPLAY_IN_SELECTED_TILE, fake_credential_provider_credential_events()->GetFieldState( - cred, FID_CURRENT_PASSWORD_FIELD)); + cred.Get(), FID_CURRENT_PASSWORD_FIELD)); // Set the correct old password so that the user can sign in. ASSERT_EQ(S_OK, @@ -1511,7 +1512,7 @@ // through escrow service succeeds. ASSERT_EQ(CPFS_HIDDEN, fake_credential_provider_credential_events()->GetFieldState( - cred, FID_CURRENT_PASSWORD_FIELD)); + cred.Get(), FID_CURRENT_PASSWORD_FIELD)); // Make sure the new password is sent to the provider. EXPECT_STREQ(A2OLE(kNewPassword), OLE2CW(test_provider->password())); @@ -1537,12 +1538,12 @@ if (generate_public_key_again_result != 0) { constexpr char kNewPassword2[] = "password3"; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); // Send back a different gaia password to force a password update. ASSERT_EQ(S_OK, test->SetGlsGaiaPassword(kNewPassword2)); @@ -1553,8 +1554,8 @@ ASSERT_EQ(S_OK, StartLogonProcessAndWait()); - CComPtr<ITestCredentialProvider> test_provider; - ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider)); + Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider; + ASSERT_EQ(S_OK, created_provider().As(&test_provider)); // Logon should not complete but there is no error message. EXPECT_EQ(test_provider->credentials_changed_fired(), false); @@ -1647,7 +1648,7 @@ // Sign on once to store the password in the LSA { // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); @@ -1666,12 +1667,12 @@ constexpr char kNewPassword[] = "password2"; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); // Send back a different gaia password to force a password update. ASSERT_EQ(S_OK, test->SetGlsGaiaPassword(kNewPassword)); @@ -1682,8 +1683,8 @@ ASSERT_EQ(S_OK, StartLogonProcessAndWait()); - CComPtr<ITestCredentialProvider> test_provider; - ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider)); + Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider; + ASSERT_EQ(S_OK, created_provider().As(&test_provider)); // Empty escrow service url will disable password // recovery and force the user to enter their password. @@ -1745,14 +1746,14 @@ ASSERT_EQ(current_full_name, (BSTR)full_name); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; // Create with invalid token handle response so that a reauth occurs. SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse); ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, test->SetGlsEmailAddress(std::string()));
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc index 1bfc4ba..fa75de0 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider.cc
@@ -51,13 +51,14 @@ namespace { // Initializes an object that implements IReauthCredential. -HRESULT InitializeReauthCredential(CGaiaCredentialProvider* provider, - const base::string16& sid, - const base::string16& domain, - const base::string16& username, - const CComPtr<IGaiaCredential>& gaia_cred) { - CComPtr<IReauthCredential> reauth; - HRESULT hr = gaia_cred.QueryInterface(&reauth); +HRESULT InitializeReauthCredential( + CGaiaCredentialProvider* provider, + const base::string16& sid, + const base::string16& domain, + const base::string16& username, + const Microsoft::WRL::ComPtr<IGaiaCredential>& gaia_cred) { + Microsoft::WRL::ComPtr<IReauthCredential> reauth; + HRESULT hr = gaia_cred.As(&reauth); if (FAILED(hr)) { LOG(ERROR) << "Could not get reauth credential interface hr=" << putHR(hr); return hr; @@ -107,8 +108,7 @@ } return CComCreator<CComObject<CredentialT>>::CreateInstance( - nullptr, IID_IGaiaCredential, - reinterpret_cast<void**>(&credential_com_ptr->gaia_cred)); + nullptr, IID_PPV_ARGS(&credential_com_ptr->gaia_cred)); } } // namespace @@ -224,7 +224,7 @@ } bool CGaiaCredentialProvider::ProviderConcurrentState::SetAutoLogonCredential( - const CComPtr<IGaiaCredential>& auto_logon_credential) { + const Microsoft::WRL::ComPtr<IGaiaCredential>& auto_logon_credential) { base::AutoLock locker(state_update_lock_); // Always update the credential. auto_logon_credential_ = auto_logon_credential; @@ -282,7 +282,7 @@ void CGaiaCredentialProvider::ProviderConcurrentState::InternalReset() { users_need_to_be_refreshed_ = false; - auto_logon_credential_.Release(); + auto_logon_credential_.Reset(); } CGaiaCredentialProvider::CGaiaCredentialProvider() {} @@ -318,10 +318,10 @@ CHECK(!token_handle_updater_); // Reset event support. advise_context_ = 0; - events_.Release(); + events_.Reset(); set_serialization_sid_.clear(); concurrent_state_.Reset(); - user_array_.Release(); + user_array_.Reset(); } void CGaiaCredentialProvider::CleanupOlderVersions() { @@ -392,7 +392,7 @@ } for (DWORD i = 0; i < count; ++i) { - CComPtr<ICredentialProviderUser> user; + Microsoft::WRL::ComPtr<ICredentialProviderUser> user; hr = users->GetAt(i, &user); if (FAILED(hr)) { LOGFN(ERROR) << "users->GetAt hr=" << putHR(hr); @@ -469,7 +469,7 @@ } void CGaiaCredentialProvider::AddCredentialAndCheckAutoLogon( - const CComPtr<IGaiaCredential>& cred, + const Microsoft::WRL::ComPtr<IGaiaCredential>& cred, const base::string16& sid, GaiaCredentialComPtrStorage* auto_logon_credential) { USES_CONVERSION; @@ -486,8 +486,8 @@ // If serialization sid is set, then try to see if this credential is a reauth // credential that needs to be auto signed in. - CComPtr<IReauthCredential> associated_user; - if (FAILED(cred.QueryInterface(&associated_user))) + Microsoft::WRL::ComPtr<IReauthCredential> associated_user; + if (FAILED(cred.As(&associated_user))) return; if (set_serialization_sid_ != sid) @@ -512,7 +512,7 @@ if (FAILED(hr)) LOG(ERROR) << "Could not create anonymous credential hr=" << putHR(hr); - hr = CreateReauthCredentials(user_array_, auto_logon_credential); + hr = CreateReauthCredentials(user_array_.Get(), auto_logon_credential); if (FAILED(hr)) LOG(ERROR) << "CreateReauthCredentials hr=" << putHR(hr); } @@ -552,10 +552,8 @@ CHECK(!credential || AssociatedUserValidator::Get()->IsDenyAccessUpdateBlocked()); - CComPtr<IGaiaCredential> gaia_credential; - if (credential->QueryInterface(IID_IGaiaCredential, - reinterpret_cast<void**>(&gaia_credential)) == - S_OK) { + Microsoft::WRL::ComPtr<IGaiaCredential> gaia_credential; + if (credential->QueryInterface(IID_PPV_ARGS(&gaia_credential)) == S_OK) { // Try to set the auto logon credential. If it succeeds we can raise a // credential changed event. if (concurrent_state_.SetAutoLogonCredential(gaia_credential) && events_) @@ -799,7 +797,7 @@ for (size_t i = 0; i < users_.size() && *default_index == CREDENTIAL_PROVIDER_NO_DEFAULT; ++i) { - if (local_auto_logon_credential.gaia_cred.IsEqualObject(users_[i])) + if (local_auto_logon_credential.gaia_cred == users_[i]) *default_index = i; }
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider.h b/chrome/credential_provider/gaiacp/gaia_credential_provider.h index 54edb10..e22dd396 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider.h +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider.h
@@ -5,6 +5,8 @@ #ifndef CHROME_CREDENTIAL_PROVIDER_GAIACP_GAIA_CREDENTIAL_PROVIDER_H_ #define CHROME_CREDENTIAL_PROVIDER_GAIACP_GAIA_CREDENTIAL_PROVIDER_H_ +#include <wrl/client.h> + #include <limits> #include <memory> #include <set> @@ -72,12 +74,12 @@ // determine the result of this query. static bool CanNewUsersBeCreated(CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus); - // Struct to allow passing CComPtr by pointer without the implicit conversion - // to ** version of the CComPtr + // Struct to allow passing ComPtr by pointer without the implicit conversion + // to ** version of the ComPtr struct GaiaCredentialComPtrStorage { GaiaCredentialComPtrStorage(); ~GaiaCredentialComPtrStorage(); - CComPtr<IGaiaCredential> gaia_cred; + Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred; }; typedef HRESULT (*CredentialCreatorFn)(GaiaCredentialComPtrStorage*); @@ -124,7 +126,7 @@ // required if a previous call to RequestUserRefreshIfNeeded was made that // requested a credential changed event. bool SetAutoLogonCredential( - const CComPtr<IGaiaCredential>& auto_logon_credential); + const Microsoft::WRL::ComPtr<IGaiaCredential>& auto_logon_credential); // Gets the current valid update state of the provider to determnie whether // an auto logon needs to be done or a refresh of the credentials. The two @@ -143,7 +145,7 @@ void InternalReset(); // Reference to the credential that authenticated the user. - CComPtr<IGaiaCredential> auto_logon_credential_; + Microsoft::WRL::ComPtr<IGaiaCredential> auto_logon_credential_; // Set in NotifyUserAccessDenied to notify the main thread that it will need // to update credentials on the next call to GetCredentialCount. This @@ -184,7 +186,7 @@ // |auto_logon_credential| with a reference to the credential that needs to // perform auto logon (if any). void AddCredentialAndCheckAutoLogon( - const CComPtr<IGaiaCredential>& cred, + const Microsoft::WRL::ComPtr<IGaiaCredential>& cred, const base::string16& sid, GaiaCredentialComPtrStorage* auto_logon_credential); @@ -231,15 +233,15 @@ CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus_ = CPUS_INVALID; DWORD cpus_flags_ = 0; UINT_PTR advise_context_; - CComPtr<ICredentialProviderEvents> events_; - CComPtr<ICredentialProviderUserArray> user_array_; + Microsoft::WRL::ComPtr<ICredentialProviderEvents> events_; + Microsoft::WRL::ComPtr<ICredentialProviderUserArray> user_array_; // List of credentials exposed by this provider. The first is always the // Gaia credential for creating new users. The rest are reauth credentials. - std::vector<CComPtr<IGaiaCredential>> users_; + std::vector<Microsoft::WRL::ComPtr<IGaiaCredential>> users_; // Reference to the credential that authenticated the user. - CComPtr<IGaiaCredential> auto_logon_credential_; + Microsoft::WRL::ComPtr<IGaiaCredential> auto_logon_credential_; // Background thread updater of token handles that is created on startup to // ensure that user must sign in through gaia if their token handle becomes
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc index e610f3c..1e3df553 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_provider_unittests.cc
@@ -6,6 +6,7 @@ #include <atlcom.h> #include <atlcomcli.h> #include <credentialprovider.h> +#include <wrl/client.h> #include <tuple> @@ -29,10 +30,10 @@ class GcpCredentialProviderTest : public GlsRunnerTestBase {}; TEST_F(GcpCredentialProviderTest, Basic) { - CComPtr<IGaiaCredentialProvider> provider; + Microsoft::WRL::ComPtr<IGaiaCredentialProvider> provider; ASSERT_EQ(S_OK, CComCreator<CComObject<CGaiaCredentialProvider>>::CreateInstance( - nullptr, IID_IGaiaCredentialProvider, (void**)&provider)); + nullptr, IID_PPV_ARGS(&provider))); } TEST_F(GcpCredentialProviderTest, SetUserArray_NoGaiaUsers) { @@ -41,7 +42,7 @@ L"username", L"password", L"full name", L"comment", L"", L"", &sid)); - CComPtr<ICredentialProvider> provider; + Microsoft::WRL::ComPtr<ICredentialProvider> provider; DWORD count = 0; ASSERT_EQ(S_OK, InitializeProviderWithCredentials(&count, &provider)); @@ -49,14 +50,14 @@ // requisite registry entry will be counted. EXPECT_EQ(1u, count); - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &cred)); - CComPtr<ICredentialProviderCredential2> cred2; - ASSERT_NE(S_OK, cred.QueryInterface(&cred2)); + Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cred2; + ASSERT_NE(S_OK, cred.As(&cred2)); - CComPtr<IReauthCredential> reauth_cred; - ASSERT_NE(S_OK, cred.QueryInterface(&reauth_cred)); + Microsoft::WRL::ComPtr<IReauthCredential> reauth_cred; + ASSERT_NE(S_OK, cred.As(&reauth_cred)); } TEST_F(GcpCredentialProviderTest, CpusLogon) { @@ -65,7 +66,7 @@ L"username", L"password", L"full name", L"comment", L"", L"", &sid)); - CComPtr<ICredentialProvider> provider; + Microsoft::WRL::ComPtr<ICredentialProvider> provider; DWORD count = 0; ASSERT_EQ(S_OK, InitializeProviderWithCredentials(&count, &provider)); @@ -73,14 +74,14 @@ // requisite registry entry will be counted. EXPECT_EQ(1u, count); - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &cred)); - CComPtr<ICredentialProviderCredential2> cred2; - ASSERT_NE(S_OK, cred.QueryInterface(&cred2)); + Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cred2; + ASSERT_NE(S_OK, cred.As(&cred2)); - CComPtr<IReauthCredential> reauth_cred; - ASSERT_NE(S_OK, cred.QueryInterface(&reauth_cred)); + Microsoft::WRL::ComPtr<IReauthCredential> reauth_cred; + ASSERT_NE(S_OK, cred.As(&reauth_cred)); } TEST_F(GcpCredentialProviderTest, CpusUnlock) { @@ -89,7 +90,7 @@ L"username", L"password", L"full name", L"comment", L"", L"", &sid)); - CComPtr<ICredentialProvider> provider; + Microsoft::WRL::ComPtr<ICredentialProvider> provider; DWORD count = 0; SetUsageScenario(CPUS_UNLOCK_WORKSTATION); ASSERT_EQ(S_OK, InitializeProviderWithCredentials(&count, &provider)); @@ -106,17 +107,17 @@ L"username", L"password", L"full name", L"comment", L"", L"", &sid)); - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ICredentialProvider> provider = created_provider(); + Microsoft::WRL::ComPtr<ICredentialProvider> provider = created_provider(); - CComPtr<IGaiaCredentialProvider> gaia_provider; - ASSERT_EQ(S_OK, provider.QueryInterface(&gaia_provider)); + Microsoft::WRL::ComPtr<IGaiaCredentialProvider> gaia_provider; + ASSERT_EQ(S_OK, provider.As(&gaia_provider)); // Notify that user access is denied to fake a forced recreation of the users. - CComPtr<ICredentialUpdateEventsHandler> update_handler; - ASSERT_EQ(S_OK, provider.QueryInterface(&update_handler)); + Microsoft::WRL::ComPtr<ICredentialUpdateEventsHandler> update_handler; + ASSERT_EQ(S_OK, provider.As(&update_handler)); update_handler->UpdateCredentialsIfNeeded(true); // Credential changed event should have been received. @@ -130,8 +131,8 @@ AssociatedUserValidator::ScopedBlockDenyAccessUpdate deny_update_locker( AssociatedUserValidator::Get()); ASSERT_EQ(S_OK, gaia_provider->OnUserAuthenticated( - cred, CComBSTR(L"username"), CComBSTR(L"password"), sid, - true)); + cred.Get(), CComBSTR(L"username"), + CComBSTR(L"password"), sid, true)); } // No credential changed should have been signalled here. @@ -149,9 +150,9 @@ EXPECT_EQ(0u, default_index); EXPECT_TRUE(autologon); - CComPtr<ICredentialProviderCredential> auto_logon_cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> auto_logon_cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &auto_logon_cred)); - EXPECT_TRUE(auto_logon_cred.IsEqualObject(cred)); + EXPECT_EQ(auto_logon_cred, cred); // The next call to GetCredentialCount should return re-created credentials. @@ -169,9 +170,9 @@ EXPECT_EQ(CREDENTIAL_PROVIDER_NO_DEFAULT, default_index); EXPECT_FALSE(autologon); - CComPtr<ICredentialProviderCredential> new_cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> new_cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &new_cred)); - EXPECT_FALSE(new_cred.IsEqualObject(cred)); + EXPECT_NE(new_cred, cred); // Another request to refresh the credentials should yield no credential // changed event or refresh of credentials. @@ -189,9 +190,9 @@ EXPECT_EQ(CREDENTIAL_PROVIDER_NO_DEFAULT, default_index); EXPECT_FALSE(autologon); - CComPtr<ICredentialProviderCredential> unchanged_cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> unchanged_cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &unchanged_cred)); - EXPECT_TRUE(new_cred.IsEqualObject(unchanged_cred)); + EXPECT_EQ(new_cred, unchanged_cred); } TEST_F(GcpCredentialProviderTest, AutoLogonBeforeUserRefresh) { @@ -201,15 +202,15 @@ L"username", L"password", L"full name", L"comment", L"", L"", &sid)); - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ICredentialProvider> provider = created_provider(); - CComPtr<IGaiaCredentialProvider> gaia_provider; - ASSERT_EQ(S_OK, provider.QueryInterface(&gaia_provider)); + Microsoft::WRL::ComPtr<ICredentialProvider> provider = created_provider(); + Microsoft::WRL::ComPtr<IGaiaCredentialProvider> gaia_provider; + ASSERT_EQ(S_OK, provider.As(&gaia_provider)); - CComPtr<ICredentialUpdateEventsHandler> update_handler; - ASSERT_EQ(S_OK, provider.QueryInterface(&update_handler)); + Microsoft::WRL::ComPtr<ICredentialUpdateEventsHandler> update_handler; + ASSERT_EQ(S_OK, provider.As(&update_handler)); // Notify user auto logon first and then notify user access denied to ensure // that auto logon always has precedence over user access denied. @@ -218,8 +219,8 @@ AssociatedUserValidator::ScopedBlockDenyAccessUpdate deny_update_locker( AssociatedUserValidator::Get()); ASSERT_EQ(S_OK, gaia_provider->OnUserAuthenticated( - cred, CComBSTR(L"username"), CComBSTR(L"password"), sid, - true)); + cred.Get(), CComBSTR(L"username"), + CComBSTR(L"password"), sid, true)); } // Credential changed event should have been received. @@ -245,9 +246,9 @@ EXPECT_EQ(0u, default_index); EXPECT_TRUE(autologon); - CComPtr<ICredentialProviderCredential> auto_logon_cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> auto_logon_cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &auto_logon_cred)); - EXPECT_TRUE(auto_logon_cred.IsEqualObject(cred)); + EXPECT_EQ(auto_logon_cred, cred); // The next call to GetCredentialCount should return re-created credentials. @@ -265,9 +266,9 @@ EXPECT_EQ(CREDENTIAL_PROVIDER_NO_DEFAULT, default_index); EXPECT_FALSE(autologon); - CComPtr<ICredentialProviderCredential> new_cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> new_cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &new_cred)); - EXPECT_FALSE(new_cred.IsEqualObject(cred)); + EXPECT_NE(new_cred, cred); // Deactivate the CP. ASSERT_EQ(S_OK, provider->UnAdvise()); @@ -286,8 +287,8 @@ L"gaia-id", L"foo@gmail.com", &sid)); { - CComPtr<ICredentialProviderCredential> cred; - CComPtr<ICredentialProvider> provider; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProvider> provider; DWORD count = 0; ASSERT_EQ(S_OK, InitializeProviderWithCredentials(&count, &provider)); @@ -305,7 +306,7 @@ fake_os_user_manager()->RemoveUser(kDummyUsername, kDummyPassword)); { - CComPtr<ICredentialProvider> provider; + Microsoft::WRL::ComPtr<ICredentialProvider> provider; DWORD count = 0; ASSERT_EQ(S_OK, InitializeProviderWithCredentials(&count, &provider)); @@ -313,14 +314,14 @@ ASSERT_EQ(1u, count); // And this credential should be the anonymous one. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(0, &cred)); - CComPtr<ICredentialProviderCredential2> cred2; - ASSERT_NE(S_OK, cred.QueryInterface(&cred2)); + Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cred2; + ASSERT_NE(S_OK, cred.As(&cred2)); - CComPtr<IReauthCredential> reauth_cred; - ASSERT_NE(S_OK, cred.QueryInterface(&reauth_cred)); + Microsoft::WRL::ComPtr<IReauthCredential> reauth_cred; + ASSERT_NE(S_OK, cred.As(&reauth_cred)); // Release the CP. ASSERT_EQ(S_OK, provider->UnAdvise()); @@ -332,11 +333,11 @@ TEST_F(GcpCredentialProviderExecutionTest, UnAdviseDuringGls) { USES_CONVERSION; - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); // This event is merely used to keep the gls running while it is killed by // Terminate(). @@ -401,8 +402,8 @@ GetAuthenticationPackageId(&cpcs.ulAuthenticationPackage); cpcs.clsidCredentialProvider = CLSID_GaiaCredentialProvider; - CComPtr<ICredentialProviderCredential> cred; - CComPtr<ICredentialProvider> provider; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProvider> provider; SetDefaultTokenHandleResponse(valid_token_handles ? kDefaultValidTokenHandleResponse : kDefaultInvalidTokenHandleResponse); @@ -480,8 +481,8 @@ if (!has_token_handle) ASSERT_EQ(S_OK, SetUserProperty((BSTR)sid, kUserTokenHandle, L"")); - CComPtr<ICredentialProviderCredential> cred; - CComPtr<ICredentialProvider> provider; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProvider> provider; DWORD count = 0; SetDefaultTokenHandleResponse(valid_token_handle ? kDefaultValidTokenHandleResponse @@ -496,10 +497,10 @@ ASSERT_EQ(should_reauth_user ? 2u : 1u, count); if (should_reauth_user) { - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(1, &cred)); - CComPtr<IReauthCredential> reauth; - EXPECT_EQ(S_OK, cred.QueryInterface(&reauth)); + Microsoft::WRL::ComPtr<IReauthCredential> reauth; + EXPECT_EQ(S_OK, cred.As(&reauth)); } } @@ -577,8 +578,8 @@ L"non-empty-token-handle")); } - CComPtr<ICredentialProviderCredential> cred; - CComPtr<ICredentialProvider> provider; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProvider> provider; DWORD count = 0; SetDefaultTokenHandleResponse(valid_token_handle ? kDefaultValidTokenHandleResponse @@ -600,19 +601,19 @@ } if (should_reauth_user) { - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(1, &cred)); - CComPtr<IReauthCredential> reauth; - EXPECT_EQ(S_OK, cred.QueryInterface(&reauth)); + Microsoft::WRL::ComPtr<IReauthCredential> reauth; + EXPECT_EQ(S_OK, cred.As(&reauth)); } // When there are two reauth credentials, validate that the second one // is also a reauth credential. if (should_reauth_user && !valid_token_handle) { - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, provider->GetCredentialAt(2, &cred)); - CComPtr<IReauthCredential> reauth; - EXPECT_EQ(S_OK, cred.QueryInterface(&reauth)); + Microsoft::WRL::ComPtr<IReauthCredential> reauth; + EXPECT_EQ(S_OK, cred.As(&reauth)); } } @@ -679,7 +680,7 @@ SetSidLockingWorkstation(second_user_locking_system ? OLE2CW(second_sid) : OLE2CW(first_sid)); - CComPtr<ICredentialProvider> provider; + Microsoft::WRL::ComPtr<ICredentialProvider> provider; DWORD count = 0; SetUsageScenario(cpus); SetDefaultTokenHandleResponse(valid_token_handles @@ -707,9 +708,9 @@ if (expected_credentials == 0) return; - CComPtr<ICredentialProviderCredential> cred; - CComPtr<ICredentialProviderCredential2> cred2; - CComPtr<IReauthCredential> reauth; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cred2; + Microsoft::WRL::ComPtr<IReauthCredential> reauth; DWORD first_non_anonymous_cred_index = 0; @@ -719,7 +720,7 @@ if (other_user_tile_available) { EXPECT_EQ(S_OK, provider->GetCredentialAt(first_non_anonymous_cred_index++, &cred)); - EXPECT_EQ(S_OK, cred.QueryInterface(&cred2)); + EXPECT_EQ(S_OK, cred.As(&cred2)); } // Not unlocking workstation: if there are more credentials then they should @@ -731,21 +732,21 @@ if (first_non_anonymous_cred_index < expected_credentials) { EXPECT_EQ(S_OK, provider->GetCredentialAt( first_non_anonymous_cred_index++, &cred)); - EXPECT_EQ(S_OK, cred.QueryInterface(&reauth)); - EXPECT_EQ(S_OK, cred.QueryInterface(&cred2)); + EXPECT_EQ(S_OK, cred.As(&reauth)); + EXPECT_EQ(S_OK, cred.As(&cred2)); EXPECT_EQ(S_OK, provider->GetCredentialAt( first_non_anonymous_cred_index++, &cred)); - EXPECT_EQ(S_OK, cred.QueryInterface(&reauth)); - EXPECT_EQ(S_OK, cred.QueryInterface(&cred2)); + EXPECT_EQ(S_OK, cred.As(&reauth)); + EXPECT_EQ(S_OK, cred.As(&cred2)); } } else if (!other_user_tile_available) { // Only the user who locked the computer should be returned as a credential // and it should be a ICredentialProviderCredential2 with the correct sid. EXPECT_EQ(S_OK, provider->GetCredentialAt(first_non_anonymous_cred_index++, &cred)); - EXPECT_EQ(S_OK, cred.QueryInterface(&reauth)); - EXPECT_EQ(S_OK, cred.QueryInterface(&cred2)); + EXPECT_EQ(S_OK, cred.As(&reauth)); + EXPECT_EQ(S_OK, cred.As(&cred2)); wchar_t* sid; EXPECT_EQ(S_OK, cred2->GetUserSid(&sid));
diff --git a/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc b/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc index 51fa2c8..3f2f692 100644 --- a/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc +++ b/chrome/credential_provider/gaiacp/gaia_credential_unittests.cc
@@ -5,6 +5,7 @@ #include <atlbase.h> #include <atlcom.h> #include <atlcomcli.h> +#include <wrl/client.h> #include "base/json/json_writer.h" #include "base/strings/string_number_conversions.h" @@ -55,35 +56,35 @@ TEST_F(GcpGaiaCredentialTest, OnUserAuthenticated) { USES_CONVERSION; - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<IGaiaCredential> gaia_cred; - ASSERT_EQ(S_OK, cred.QueryInterface(&gaia_cred)); + Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred; + ASSERT_EQ(S_OK, cred.As(&gaia_cred)); CComBSTR error; ASSERT_EQ(S_OK, gaia_cred->OnUserAuthenticated(signin_result(), &error)); - CComPtr<ITestCredentialProvider> test_provider; - ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider)); + Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider; + ASSERT_EQ(S_OK, created_provider().As(&test_provider)); EXPECT_TRUE(test_provider->credentials_changed_fired()); } TEST_F(GcpGaiaCredentialTest, OnUserAuthenticated_SamePassword) { USES_CONVERSION; - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<IGaiaCredential> gaia_cred; - ASSERT_EQ(S_OK, cred.QueryInterface(&gaia_cred)); + Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred; + ASSERT_EQ(S_OK, cred.As(&gaia_cred)); CComBSTR error; ASSERT_EQ(S_OK, gaia_cred->OnUserAuthenticated(signin_result(), &error)); - CComPtr<ITestCredentialProvider> test_provider; - ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider)); + Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider; + ASSERT_EQ(S_OK, created_provider().As(&test_provider)); CComBSTR first_sid = test_provider->sid(); // Report to register the user. @@ -115,18 +116,18 @@ base::UTF8ToUTF16(test_data_storage.GetSuccessId()).c_str(), base::UTF8ToUTF16(test_data_storage.GetSuccessEmail()).c_str(), &sid)); - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<IGaiaCredential> gaia_cred; - ASSERT_EQ(S_OK, cred.QueryInterface(&gaia_cred)); + Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred; + ASSERT_EQ(S_OK, cred.As(&gaia_cred)); CComBSTR error; ASSERT_EQ(S_OK, gaia_cred->OnUserAuthenticated(signin_result(), &error)); - CComPtr<ITestCredentialProvider> test_provider; - ASSERT_EQ(S_OK, created_provider().QueryInterface(&test_provider)); + Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider; + ASSERT_EQ(S_OK, created_provider().As(&test_provider)); EXPECT_TRUE(test_provider->credentials_changed_fired()); test_provider->ResetCredentialsChangedFired(); @@ -157,15 +158,15 @@ ASSERT_EQ(2u, fake_os_user_manager()->GetUserCount()); // Start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<IGaiaCredential> gaia_cred; - ASSERT_EQ(S_OK, cred.QueryInterface(&gaia_cred)); + Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred; + ASSERT_EQ(S_OK, cred.As(&gaia_cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, test->SetGlsEmailAddress(base::UTF16ToUTF8(base_username) + "@gmail.com")); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -227,14 +228,14 @@ fake_os_user_manager()->GetUserCount()); // Create provider. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(0, &cred)); - CComPtr<IGaiaCredential> gaia_cred; - ASSERT_EQ(S_OK, cred.QueryInterface(&gaia_cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<IGaiaCredential> gaia_cred; + ASSERT_EQ(S_OK, cred.As(&gaia_cred)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); // Start logon. ASSERT_EQ(S_OK, StartLogonProcessAndWait());
diff --git a/chrome/credential_provider/gaiacp/internet_availability_checker.cc b/chrome/credential_provider/gaiacp/internet_availability_checker.cc index 86ebb67..29ecdde8 100644 --- a/chrome/credential_provider/gaiacp/internet_availability_checker.cc +++ b/chrome/credential_provider/gaiacp/internet_availability_checker.cc
@@ -4,10 +4,10 @@ #include "chrome/credential_provider/gaiacp/internet_availability_checker.h" -#include <netlistmgr.h> // For CLSID_NetworkListManager - #include <atlbase.h> #include <atlcom.h> +#include <netlistmgr.h> // For CLSID_NetworkListManager +#include <wrl/client.h> #include "chrome/credential_provider/gaiacp/gcp_utils.h" #include "chrome/credential_provider/gaiacp/logging.h" @@ -20,8 +20,9 @@ // If any errors occur, return that internet connection is available. At // worst the credential provider will try to connect and fail. - CComPtr<INetworkListManager> manager; - HRESULT hr = manager.CoCreateInstance(CLSID_NetworkListManager); + Microsoft::WRL::ComPtr<INetworkListManager> manager; + HRESULT hr = ::CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_ALL, + IID_PPV_ARGS(&manager)); if (FAILED(hr)) { LOGFN(ERROR) << "CoCreateInstance(NetworkListManager) hr=" << putHR(hr); return true;
diff --git a/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc b/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc index 4ea60f1..57a7fb60 100644 --- a/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc +++ b/chrome/credential_provider/gaiacp/reauth_credential_unittests.cc
@@ -5,6 +5,7 @@ #include <atlbase.h> #include <atlcom.h> #include <atlcomcli.h> +#include <wrl/client.h> #include "base/json/json_writer.h" #include "base/strings/utf_string_conversions.h" @@ -49,7 +50,7 @@ USES_CONVERSION; CredentialProviderSigninDialogTestDataStorage test_data_storage; - CComPtr<IReauthCredential> reauth; + Microsoft::WRL::ComPtr<IReauthCredential> reauth; ASSERT_EQ(S_OK, CComCreator<CComObject<CReauthCredential>>::CreateInstance( nullptr, IID_IReauthCredential, (void**)&reauth)); ASSERT_TRUE(!!reauth); @@ -61,9 +62,8 @@ ASSERT_EQ(S_OK, reauth->SetEmailForReauth(CComBSTR( A2COLE(test_data_storage.GetSuccessEmail().c_str())))); - CComPtr<ICredentialProviderCredential2> cpc2; - ASSERT_EQ(S_OK, reauth->QueryInterface(IID_ICredentialProviderCredential2, - reinterpret_cast<void**>(&cpc2))); + Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cpc2; + ASSERT_EQ(S_OK, reauth.As(&cpc2)); wchar_t* sid; CComBSTR username; ASSERT_EQ(S_OK, cpc2->GetUserSid(&sid)); @@ -97,7 +97,7 @@ ASSERT_EQ(S_OK, SetGlobalFlagForTesting(kRegEnableADAssociation, is_ad_association_enabled)); - CComPtr<IReauthCredential> reauth; + Microsoft::WRL::ComPtr<IReauthCredential> reauth; ASSERT_EQ(S_OK, CComCreator<CComObject<CReauthCredential>>::CreateInstance( nullptr, IID_IReauthCredential, (void**)&reauth)); ASSERT_TRUE(!!reauth); @@ -132,9 +132,8 @@ ASSERT_EQ(S_OK, reauth->SetEmailForReauth(CComBSTR(email))); } - CComPtr<ICredentialProviderCredential2> cpc2; - ASSERT_EQ(S_OK, reauth->QueryInterface(IID_ICredentialProviderCredential2, - reinterpret_cast<void**>(&cpc2))); + Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cpc2; + ASSERT_EQ(S_OK, reauth.As(&cpc2)); LPWSTR string_value = nullptr; ASSERT_EQ(S_OK, cpc2->GetStringValue(FID_DESCRIPTION, &string_value)); @@ -193,7 +192,7 @@ GoogleMdmEnrolledStatusForTesting forced_enrolled_status(enrolled_mdm); - CComPtr<IReauthCredential> reauth; + Microsoft::WRL::ComPtr<IReauthCredential> reauth; ASSERT_EQ(S_OK, CComCreator<CComObject<CReauthCredential>>::CreateInstance( nullptr, IID_IReauthCredential, (void**)&reauth)); ASSERT_TRUE(!!reauth); @@ -231,9 +230,8 @@ ASSERT_EQ(S_OK, reauth->SetEmailForReauth(CComBSTR(email))); - CComPtr<ICredentialProviderCredential2> cpc2; - ASSERT_EQ(S_OK, reauth->QueryInterface(IID_ICredentialProviderCredential2, - reinterpret_cast<void**>(&cpc2))); + Microsoft::WRL::ComPtr<ICredentialProviderCredential2> cpc2; + ASSERT_EQ(S_OK, reauth.As(&cpc2)); LPWSTR string_value = nullptr; ASSERT_EQ(S_OK, cpc2->GetStringValue(FID_DESCRIPTION, &string_value)); @@ -282,7 +280,7 @@ OLE2CW(email), &sid)); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; // Create with invalid token handle response so that a reauth occurs. SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse); @@ -331,7 +329,7 @@ OLE2CW(email), L"domain", &sid)); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred)); @@ -387,14 +385,14 @@ &second_sid)); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; // Create with invalid token handle response so that a reauth occurs. SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse); ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); // Force the GLS to return an invalid Gaia Id without reporting the usual // kUiecEMailMissmatch exit code when this happens. This will test whether @@ -425,14 +423,14 @@ OLE2CW(email), &sid)); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; // Create with invalid token handle response so that a reauth occurs. SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse); ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, test->SetGlsEmailAddress(std::string())); @@ -459,14 +457,14 @@ base::string16(), &sid)); // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; // Create with invalid token handle response so that a reauth occurs. SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse); ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, StartLogonProcessAndWait()); @@ -496,14 +494,14 @@ std::string unexpected_gaia_id = "unexpected-gaia-id"; // Create provider and start logon. - CComPtr<ICredentialProviderCredential> cred; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> cred; // Create with invalid token handle response so that a reauth occurs. SetDefaultTokenHandleResponse(kDefaultInvalidTokenHandleResponse); ASSERT_EQ(S_OK, InitializeProviderAndGetCredential(1, &cred)); - CComPtr<ITestCredential> test; - ASSERT_EQ(S_OK, cred.QueryInterface(&test)); + Microsoft::WRL::ComPtr<ITestCredential> test; + ASSERT_EQ(S_OK, cred.As(&test)); ASSERT_EQ(S_OK, test->SetGlsEmailAddress(std::string())); ASSERT_EQ(S_OK, test->SetGaiaIdOverride(unexpected_gaia_id,
diff --git a/chrome/credential_provider/test/com_fakes.cc b/chrome/credential_provider/test/com_fakes.cc index 577ad91a..7c19b992 100644 --- a/chrome/credential_provider/test/com_fakes.cc +++ b/chrome/credential_provider/test/com_fakes.cc
@@ -262,23 +262,18 @@ [](CGaiaCredentialProvider::GaiaCredentialComPtrStorage* cred_ptr_storage) { return CComCreator<CComObject<CTestGaiaCredential>>::CreateInstance( - nullptr, IID_IGaiaCredential, - reinterpret_cast<void**>(&cred_ptr_storage->gaia_cred)); + nullptr, IID_PPV_ARGS(&cred_ptr_storage->gaia_cred)); }, [](CGaiaCredentialProvider::GaiaCredentialComPtrStorage* cred_ptr_storage) { return CComCreator<CComObject<CTestOtherUserGaiaCredential>>:: - CreateInstance( - nullptr, IID_IGaiaCredential, - reinterpret_cast<void**>(&cred_ptr_storage->gaia_cred)); + CreateInstance(nullptr, IID_PPV_ARGS(&cred_ptr_storage->gaia_cred)); }, [](CGaiaCredentialProvider::GaiaCredentialComPtrStorage* cred_ptr_storage) { return CComCreator<CComObject<testing::CTestCredentialForInherited< CReauthCredential, IReauthCredential>>>:: - CreateInstance( - nullptr, IID_IGaiaCredential, - reinterpret_cast<void**>(&cred_ptr_storage->gaia_cred)); + CreateInstance(nullptr, IID_PPV_ARGS(&cred_ptr_storage->gaia_cred)); }); }
diff --git a/chrome/credential_provider/test/gcp_setup_unittests.cc b/chrome/credential_provider/test/gcp_setup_unittests.cc index 394790f..408d1f49 100644 --- a/chrome/credential_provider/test/gcp_setup_unittests.cc +++ b/chrome/credential_provider/test/gcp_setup_unittests.cc
@@ -8,6 +8,7 @@ #include <lmerr.h> #include <objbase.h> #include <unknwn.h> +#include <wrl/client.h> #include <memory> @@ -348,10 +349,10 @@ locked_file.Close(); - CComPtr<IGaiaCredentialProvider> provider; + Microsoft::WRL::ComPtr<IGaiaCredentialProvider> provider; ASSERT_EQ(S_OK, CComCreator<CComObject<CGaiaCredentialProvider>>::CreateInstance( - nullptr, IID_IGaiaCredentialProvider, (void**)&provider)); + nullptr, IID_PPV_ARGS(&provider))); // Make sure newer version exists and old version is gone. ExpectAllFilesToExist(true, product_version());
diff --git a/chrome/credential_provider/test/gls_runner_test_base.cc b/chrome/credential_provider/test/gls_runner_test_base.cc index 4feb0569..9032c5f 100644 --- a/chrome/credential_provider/test/gls_runner_test_base.cc +++ b/chrome/credential_provider/test/gls_runner_test_base.cc
@@ -176,7 +176,7 @@ gaia_provider_->GetCredentialCount(&count, &default_index, &autologon); if (SUCCEEDED(get_count_hr)) { for (DWORD i = 0; i < count; ++i) { - CComPtr<ICredentialProviderCredential> credential; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> credential; HRESULT get_hr = gaia_provider_->GetCredentialAt(i, &credential); EXPECT_EQ(get_hr, S_OK); if (SUCCEEDED(get_hr)) { @@ -195,7 +195,7 @@ HRESULT unadvise_hr = gaia_provider_->UnAdvise(); if (FAILED(unadvise_hr)) hr = unadvise_hr; - gaia_provider_.Release(); + gaia_provider_.Reset(); return hr; } @@ -208,7 +208,7 @@ if (FAILED(hr)) return hr; - return gaia_provider_.QueryInterface(provider); + return gaia_provider_.CopyTo(IID_PPV_ARGS(provider)); } HRESULT GlsRunnerTestBase::InitializeProviderWithRemoteCredentials( @@ -218,7 +218,7 @@ if (FAILED(hr)) return hr; - return gaia_provider_.QueryInterface(provider); + return gaia_provider_.CopyTo(IID_PPV_ARGS(provider)); } HRESULT GlsRunnerTestBase::InitializeProviderAndGetCredential( @@ -240,7 +240,7 @@ if (FAILED(hr)) return hr; - EXPECT_EQ(S_OK, testing_cred_.QueryInterface(credential)); + EXPECT_EQ(S_OK, testing_cred_.CopyTo(IID_PPV_ARGS(credential))); return S_OK; } @@ -250,12 +250,10 @@ if (count) *count = 0; - CComPtr<ICredentialProvider> provider; - + Microsoft::WRL::ComPtr<ICredentialProvider> provider; HRESULT hr = CComCreator<CComObject<CTestGaiaCredentialProvider>>::CreateInstance( - nullptr, IID_ICredentialProvider, - reinterpret_cast<void**>(&provider)); + nullptr, IID_PPV_ARGS(&provider)); if (FAILED(hr)) return hr; @@ -285,8 +283,8 @@ } // Give list of users visible on welcome screen. - CComPtr<ICredentialProviderSetUserArray> provider_user_array; - hr = provider.QueryInterface(&provider_user_array); + Microsoft::WRL::ComPtr<ICredentialProviderSetUserArray> provider_user_array; + hr = provider.As(&provider_user_array); if (FAILED(hr)) return hr; @@ -342,7 +340,7 @@ // Advise all the credentials for (DWORD i = 0; i < *count; ++i) { - CComPtr<ICredentialProviderCredential> current_credential; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> current_credential; hr = gaia_provider_->GetCredentialAt(i, ¤t_credential); if (FAILED(hr)) return hr; @@ -370,7 +368,7 @@ // Initialize the default field states by calling GetFieldState of // ICredentialProviderCredential. for (DWORD i = 0; count && i < *count; ++i) { - CComPtr<ICredentialProviderCredential> current_credential; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> current_credential; hr = gaia_provider_->GetCredentialAt(i, ¤t_credential); if (FAILED(hr)) return hr; @@ -383,7 +381,7 @@ return hr; hr = fake_credential_provider_credential_events()->SetFieldState( - current_credential, fieldID, cpfs); + current_credential.Get(), fieldID, cpfs); if (FAILED(hr)) return hr; } @@ -393,7 +391,7 @@ } HRESULT GlsRunnerTestBase::ApplyProviderFilter( - const CComPtr<ICredentialProvider>& provider, + const Microsoft::WRL::ComPtr<ICredentialProvider>& provider, const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs_in, CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs_out, HRESULT* update_remote_credentials_hr) { @@ -402,7 +400,7 @@ // Filter only lives long enough to apply filter and get serialization // credentials. - CComPtr<ICredentialProviderFilter> filter; + Microsoft::WRL::ComPtr<ICredentialProviderFilter> filter; HRESULT hr = CComCreator<CComObject<CGaiaCredentialProviderFilter>>::CreateInstance( nullptr, IID_ICredentialProviderFilter, (void**)&filter); @@ -469,8 +467,8 @@ } HRESULT GlsRunnerTestBase::WaitForLogonProcess() { - CComPtr<testing::ITestCredential> test; - HRESULT hr = testing_cred_->QueryInterface(&test); + Microsoft::WRL::ComPtr<testing::ITestCredential> test; + HRESULT hr = testing_cred_.As(&test); if (FAILED(hr)) return hr; return test->WaitForGls(); @@ -533,9 +531,10 @@ if (!logon_process_started_successfully_) return S_OK; - CComPtr<ICredentialProviderCredential> local_testing_cred = testing_cred_; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> local_testing_cred = + testing_cred_; // Release ownership on the testing_cred_ which should be finishing. - testing_cred_.Release(); + testing_cred_.Reset(); HRESULT hr = FinishLogonProcessWithCred( expected_success, expected_credentials_change_fired, @@ -558,7 +557,8 @@ bool expected_success, bool expected_credentials_change_fired, int expected_error_message, - const CComPtr<ICredentialProviderCredential>& local_testing_cred) { + const Microsoft::WRL::ComPtr<ICredentialProviderCredential>& + local_testing_cred) { // If no logon process was started, there is nothing to finish. if (!logon_process_started_successfully_) return S_OK; @@ -566,13 +566,13 @@ logon_process_started_successfully_ = false; DCHECK(gaia_provider_); - CComPtr<ITestCredential> test_cred; - HRESULT hr = local_testing_cred.QueryInterface(&test_cred); + Microsoft::WRL::ComPtr<ITestCredential> test_cred; + HRESULT hr = local_testing_cred.As(&test_cred); if (FAILED(hr)) return hr; - CComPtr<ITestCredentialProvider> test_provider; - hr = gaia_provider_.QueryInterface(&test_provider); + Microsoft::WRL::ComPtr<ITestCredentialProvider> test_provider; + hr = gaia_provider_.As(&test_provider); if (FAILED(hr)) return hr; @@ -624,9 +624,10 @@ } HRESULT GlsRunnerTestBase::ReportLogonProcessResult( - const CComPtr<ICredentialProviderCredential>& local_testing_cred) { - CComPtr<ITestCredential> test_cred; - HRESULT hr = local_testing_cred.QueryInterface(&test_cred); + const Microsoft::WRL::ComPtr<ICredentialProviderCredential>& + local_testing_cred) { + Microsoft::WRL::ComPtr<ITestCredential> test_cred; + HRESULT hr = local_testing_cred.As(&test_cred); if (FAILED(hr)) return hr;
diff --git a/chrome/credential_provider/test/gls_runner_test_base.h b/chrome/credential_provider/test/gls_runner_test_base.h index 5196358..6f813d5 100644 --- a/chrome/credential_provider/test/gls_runner_test_base.h +++ b/chrome/credential_provider/test/gls_runner_test_base.h
@@ -5,6 +5,8 @@ #ifndef CHROME_CREDENTIAL_PROVIDER_TEST_GLS_RUNNER_TEST_BASE_H_ #define CHROME_CREDENTIAL_PROVIDER_TEST_GLS_RUNNER_TEST_BASE_H_ +#include <wrl/client.h> + #include "base/test/test_reg_util_win.h" #include "chrome/credential_provider/common/gcp_strings.h" #include "chrome/credential_provider/gaiacp/gaia_credential_provider.h" @@ -74,7 +76,7 @@ return &fake_internet_checker_; } - const CComPtr<ICredentialProvider>& created_provider() const { + const Microsoft::WRL::ComPtr<ICredentialProvider>& created_provider() const { return gaia_provider_; } @@ -159,16 +161,18 @@ bool expected_success, bool expected_credentials_change_fired, int expected_error_message, - const CComPtr<ICredentialProviderCredential>& local_testing_cred); + const Microsoft::WRL::ComPtr<ICredentialProviderCredential>& + local_testing_cred); HRESULT ReportLogonProcessResult( - const CComPtr<ICredentialProviderCredential>& local_testing_cred); + const Microsoft::WRL::ComPtr<ICredentialProviderCredential>& + local_testing_cred); private: HRESULT InternalInitializeProvider( const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs_in, DWORD* count); HRESULT ApplyProviderFilter( - const CComPtr<ICredentialProvider>& provider, + const Microsoft::WRL::ComPtr<ICredentialProvider>& provider, const CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs_in, CREDENTIAL_PROVIDER_CREDENTIAL_SERIALIZATION* pcpcs_out, HRESULT* update_remote_credentials_hr); @@ -193,14 +197,14 @@ base::string16 sid_locking_workstation_; // Reference to the provider that is created and owned by this class. - CComPtr<ICredentialProvider> gaia_provider_; + Microsoft::WRL::ComPtr<ICredentialProvider> gaia_provider_; // Reference to the credential in provider that is being tested by this class. // This member is kept so that it can be automatically released on destruction // of the test if the test did not explicitly release it. This allows us to // write less boiler plate test code and ensures that proper destruction order // of the credentials is respected. - CComPtr<ICredentialProviderCredential> testing_cred_; + Microsoft::WRL::ComPtr<ICredentialProviderCredential> testing_cred_; // Keeps track of whether a logon process has started for |testing_cred_|. // Testers who do not explicitly call FinishLogonProcess before the end of
diff --git a/chrome/installer/util/copy_tree_work_item.cc b/chrome/installer/util/copy_tree_work_item.cc index 4dd39a73..9dcf4b2 100644 --- a/chrome/installer/util/copy_tree_work_item.cc +++ b/chrome/installer/util/copy_tree_work_item.cc
@@ -126,14 +126,25 @@ } } +// static bool CopyTreeWorkItem::IsFileInUse(const base::FilePath& path) { if (!base::PathExists(path)) return false; - HANDLE handle = ::CreateFile(path.value().c_str(), FILE_ALL_ACCESS, - NULL, NULL, OPEN_EXISTING, NULL, NULL); - if (handle == INVALID_HANDLE_VALUE) + // A running executable is open with exclusive write access, so attempting to + // write to it will fail with a sharing violation. A more precise method would + // be to open the file with DELETE access and attempt to set the delete + // disposition on the handle. This would fail if the file was mapped into a + // process's address space, but succeed otherwise. This seems like overkill, + // however. + HANDLE handle = + ::CreateFile(path.value().c_str(), FILE_WRITE_DATA, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, OPEN_EXISTING, 0, nullptr); + if (handle == INVALID_HANDLE_VALUE) { + DPCHECK(::GetLastError() == ERROR_SHARING_VIOLATION); return true; + } CloseHandle(handle); return false;
diff --git a/chrome/installer/util/copy_tree_work_item.h b/chrome/installer/util/copy_tree_work_item.h index 56e5cf67..c69aa92 100644 --- a/chrome/installer/util/copy_tree_work_item.h +++ b/chrome/installer/util/copy_tree_work_item.h
@@ -46,7 +46,7 @@ void RollbackImpl() override; // Checks if the path specified is in use (and hence can not be deleted) - bool IsFileInUse(const base::FilePath& path); + static bool IsFileInUse(const base::FilePath& path); // Source path to copy files from. base::FilePath source_path_;
diff --git a/chrome/installer/util/copy_tree_work_item_unittest.cc b/chrome/installer/util/copy_tree_work_item_unittest.cc index cea4012..4d1b94b 100644 --- a/chrome/installer/util/copy_tree_work_item_unittest.cc +++ b/chrome/installer/util/copy_tree_work_item_unittest.cc
@@ -44,19 +44,6 @@ file.close(); } -bool IsFileInUse(const base::FilePath& path) { - if (!base::PathExists(path)) - return false; - - HANDLE handle = ::CreateFile(path.value().c_str(), FILE_ALL_ACCESS, - NULL, NULL, OPEN_EXISTING, NULL, NULL); - if (handle == INVALID_HANDLE_VALUE) - return true; - - CloseHandle(handle); - return false; -} - // Simple function to read text from a file. std::wstring ReadTextFile(const std::wstring& filename) { WCHAR contents[64]; @@ -398,6 +385,7 @@ alternate_to = alternate_to.AppendASCII("Alternate_To"); base::CopyFile(exe_full_path, file_name_to); ASSERT_TRUE(base::PathExists(file_name_to)); + ASSERT_FALSE(CopyTreeWorkItem::IsFileInUse(file_name_to)); VLOG(1) << "copy ourself from " << exe_full_path.value() << " to " << file_name_to.value(); @@ -446,10 +434,10 @@ work_item.reset(WorkItem::CreateCopyTreeWorkItem( file_name_from, file_name_to, temp_dir_.GetPath(), WorkItem::NEW_NAME_IF_IN_USE, alternate_to)); - if (IsFileInUse(file_name_to)) + if (CopyTreeWorkItem::IsFileInUse(file_name_to)) base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(2)); // If file is still in use, the rest of the test will fail. - ASSERT_FALSE(IsFileInUse(file_name_to)); + ASSERT_FALSE(CopyTreeWorkItem::IsFileInUse(file_name_to)); EXPECT_TRUE(work_item->Do()); // Get the path of backup file
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index c14d79d..048cdfb 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -1426,7 +1426,6 @@ "//chrome/browser/media/router:test_support", "//chrome/browser/resources/chromeos/autoclick:browser_tests", "//chrome/browser/resources/chromeos/chromevox:browser_tests", - "//chrome/browser/resources/chromeos/login:browser_tests", "//chrome/browser/resources/chromeos/select_to_speak:browser_tests", "//chrome/browser/resources/chromeos/switch_access:browser_tests", "//chrome/services/file_util/public/cpp:browser_tests", @@ -1458,6 +1457,7 @@ ] if (is_chromeos) { deps += [ + "//chrome/browser/resources/chromeos/login:browser_tests", "//chromeos/components/help_app_ui:browser_tests_js", "//chromeos/components/media_app_ui:browser_tests_js", ]
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java index 3690ebc..5174bbd 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/NewTabPageTestUtils.java
@@ -12,7 +12,7 @@ import org.chromium.chrome.browser.ntp.IncognitoNewTabPage; import org.chromium.chrome.browser.ntp.NewTabPage; -import org.chromium.chrome.browser.preferences.ChromePreferenceManager; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; import org.chromium.chrome.browser.suggestions.SiteSuggestion; import org.chromium.chrome.browser.suggestions.tile.TileSectionType; @@ -101,6 +101,6 @@ fakeAccountManager.addAccountHolderExplicitly(new AccountHolder.Builder(account).build()); assertFalse(AccountManagerFacade.get().isUpdatePending().get()); assertFalse(SharedPreferencesManager.getInstance().readBoolean( - ChromePreferenceManager.NTP_SIGNIN_PROMO_DISMISSED, false)); + ChromePreferenceKeys.NTP_SIGNIN_PROMO_DISMISSED, false)); } }
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 915b614..8722e24 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -67,11 +67,20 @@ const base::Feature kCrostiniWebUIInstaller{"CrostiniWebUIInstaller", base::FEATURE_ENABLED_BY_DEFAULT}; +// Deprecates the CryptAuth v1 DeviceSync flow. Note: During the first phase +// of the v2 DeviceSync rollout, v1 and v2 DeviceSync run in parallel. This flag +// is needed to deprecate the v1 service during the second phase of the rollout. +// kCryptAuthV2DeviceSync should be enabled before this flag is flipped. +const base::Feature kCryptAuthV1DeviceSyncDeprecate{ + "CryptAuthV1DeviceSyncDeprecate", base::FEATURE_DISABLED_BY_DEFAULT}; + // Enables or disables using Cryptauth's GetDevicesActivityStatus API. const base::Feature kCryptAuthV2DeviceActivityStatus{ "CryptAuthV2DeviceActivityStatus", base::FEATURE_DISABLED_BY_DEFAULT}; -// Enables or disables the CryptAuth v2 DeviceSync flow. +// Enables or disables the CryptAuth v2 DeviceSync flow. Regardless of this +// flag, v1 DeviceSync will continue to operate until it is deprecated via the +// feature flag kCryptAuthV1DeviceSyncDeprecate. const base::Feature kCryptAuthV2DeviceSync{"CryptAuthV2DeviceSync", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index b59fe29..2d17f750 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -41,6 +41,8 @@ COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kCrostiniWebUIInstaller; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +extern const base::Feature kCryptAuthV1DeviceSyncDeprecate; +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kCryptAuthV2DeviceActivityStatus; COMPONENT_EXPORT(CHROMEOS_CONSTANTS) extern const base::Feature kCryptAuthV2DeviceSync;
diff --git a/components/BUILD.gn b/components/BUILD.gn index 7e247c6..800f4a7c 100644 --- a/components/BUILD.gn +++ b/components/BUILD.gn
@@ -568,6 +568,7 @@ "//testing/gmock", "//testing/gtest", "//ui/base", + "//ui/native_theme:native_theme", "//url", ]
diff --git a/components/autofill_assistant/browser/actions/collect_user_data_action.cc b/components/autofill_assistant/browser/actions/collect_user_data_action.cc index 8233f06..7882fa0 100644 --- a/components/autofill_assistant/browser/actions/collect_user_data_action.cc +++ b/components/autofill_assistant/browser/actions/collect_user_data_action.cc
@@ -309,15 +309,19 @@ std::unique_ptr<CollectUserDataOptions> collect_user_data_options, std::vector<WebsiteLoginFetcher::Login> logins) { for (const auto& login : logins) { - LoginChoice choice = { - base::NumberToString(collect_user_data_options->login_choices.size()), - login.username, login_option.preselection_priority()}; - collect_user_data_options->login_choices.emplace_back(std::move(choice)); + auto identifier = + base::NumberToString(collect_user_data_options->login_choices.size()); + collect_user_data_options->login_choices.emplace_back( + identifier, login.username, login_option.sublabel(), + login_option.sublabel_accessibility_hint(), + login_option.preselection_priority(), + login_option.has_info_popup() + ? base::make_optional(login_option.info_popup()) + : base::nullopt); login_details_map_.emplace( - choice.identifier, - std::make_unique<LoginDetails>( - login_option.choose_automatically_if_no_other_options(), - login_option.payload(), login)); + identifier, std::make_unique<LoginDetails>( + login_option.choose_automatically_if_no_other_options(), + login_option.payload(), login)); } ShowToUser(std::move(collect_user_data_options)); } @@ -577,9 +581,14 @@ base::NumberToString( collect_user_data_options->login_choices.size()), login_option.custom().label(), + login_option.sublabel(), + login_option.sublabel_accessibility_hint(), login_option.has_preselection_priority() ? login_option.preselection_priority() - : -1}; + : -1, + login_option.has_info_popup() + ? base::make_optional(login_option.info_popup()) + : base::nullopt}; collect_user_data_options->login_choices.emplace_back( std::move(choice)); login_details_map_.emplace(
diff --git a/components/autofill_assistant/browser/service.proto b/components/autofill_assistant/browser/service.proto index 9e8f5df..4e0ea92 100644 --- a/components/autofill_assistant/browser/service.proto +++ b/components/autofill_assistant/browser/service.proto
@@ -1206,6 +1206,14 @@ optional bool request_payer_phone = 4; } +// A generic read-only popup message. +message InfoPopupProto { + // The title of the popup window. + optional string title = 1; + // The text of the popup window. + optional string text = 2; +} + message LoginDetailsProto { // A custom login option which will be handled by the backend, e.g., // 'Guest checkout' or 'Log in with Google'. @@ -1218,6 +1226,13 @@ message LoginOptionPasswordManagerProto {} message LoginOptionProto { + // If set, an info icon will be shown that displays a popup when tapped. + optional InfoPopupProto info_popup = 6; + + // The optional sublabel to display beneath the label. + optional string sublabel = 7; + optional string sublabel_accessibility_hint = 8; + // If the option was chosen, this payload will be returned to the server. optional bytes payload = 1;
diff --git a/components/autofill_assistant/browser/user_data.cc b/components/autofill_assistant/browser/user_data.cc index c518bdf..2ba170b 100644 --- a/components/autofill_assistant/browser/user_data.cc +++ b/components/autofill_assistant/browser/user_data.cc
@@ -10,10 +10,19 @@ namespace autofill_assistant { -LoginChoice::LoginChoice(const std::string& id, - const std::string& text, - int priority) - : identifier(id), label(text), preselect_priority(priority) {} +LoginChoice::LoginChoice(const std::string& _identifier, + const std::string& _label, + const std::string& _sublabel, + const std::string& _sublabel_accessibility_hint, + int _preselect_priority, + const base::Optional<InfoPopupProto>& _info_popup) + : identifier(_identifier), + label(_label), + sublabel(_sublabel), + sublabel_accessibility_hint(_sublabel_accessibility_hint), + preselect_priority(_preselect_priority), + info_popup(_info_popup) {} +LoginChoice::LoginChoice(const LoginChoice& another) = default; LoginChoice::~LoginChoice() = default; UserData::UserData() = default;
diff --git a/components/autofill_assistant/browser/user_data.h b/components/autofill_assistant/browser/user_data.h index 9337f3e..4b1815d 100644 --- a/components/autofill_assistant/browser/user_data.h +++ b/components/autofill_assistant/browser/user_data.h
@@ -11,6 +11,7 @@ #include <vector> #include "base/callback.h" +#include "base/optional.h" #include "components/autofill_assistant/browser/service.pb.h" #include "components/autofill_assistant/browser/user_action.h" @@ -38,15 +39,27 @@ // Represents a concrete login choice in the UI, e.g., 'Guest checkout' or // a particular Chrome PWM login account. struct LoginChoice { - LoginChoice(const std::string& id, const std::string& text, int priority); + LoginChoice(const std::string& id, + const std::string& label, + const std::string& sublabel, + const std::string& sublabel_accessibility_hint, + int priority, + const base::Optional<InfoPopupProto>& info_popup); + LoginChoice(const LoginChoice& another); ~LoginChoice(); // Uniquely identifies this login choice. std::string identifier; // The label to display to the user. std::string label; + // The sublabel to display to the user. + std::string sublabel; + // The a11y hint for |sublabel|. + std::string sublabel_accessibility_hint; // The priority to pre-select this choice (-1 == not set/automatic). int preselect_priority = -1; + // The popup to show to provide more information about this login choice. + base::Optional<InfoPopupProto> info_popup; }; // Struct for holding the user data.
diff --git a/components/browser_sync/profile_sync_components_factory_impl.cc b/components/browser_sync/profile_sync_components_factory_impl.cc index 2c4d92be..2ae3cb5b 100644 --- a/components/browser_sync/profile_sync_components_factory_impl.cc +++ b/components/browser_sync/profile_sync_components_factory_impl.cc
@@ -319,26 +319,10 @@ } #if defined(OS_CHROMEOS) - if (chromeos::features::IsSplitSettingsSyncEnabled()) { - if (!disabled_types.Has(syncer::OS_PREFERENCES)) { - controllers.push_back( - std::make_unique<SyncableServiceBasedModelTypeController>( - syncer::OS_PREFERENCES, - sync_client_->GetModelTypeStoreService()->GetStoreFactory(), - sync_client_->GetSyncableServiceForType(syncer::OS_PREFERENCES), - dump_stack)); - } - if (!disabled_types.Has(syncer::OS_PRIORITY_PREFERENCES)) { - controllers.push_back( - std::make_unique<SyncableServiceBasedModelTypeController>( - syncer::OS_PRIORITY_PREFERENCES, - sync_client_->GetModelTypeStoreService()->GetStoreFactory(), - sync_client_->GetSyncableServiceForType( - syncer::OS_PRIORITY_PREFERENCES), - dump_stack)); - } - } - if (!disabled_types.Has(syncer::PRINTERS)) { + // When SplitSettingsSync is enabled the controller is created in + // ChromeSyncClient so it can live near other printer-related sync code. + if (!disabled_types.Has(syncer::PRINTERS) && + !chromeos::features::IsSplitSettingsSyncEnabled()) { controllers.push_back( CreateModelTypeControllerForModelRunningOnUIThread(syncer::PRINTERS)); }
diff --git a/components/dom_distiller/content/browser/BUILD.gn b/components/dom_distiller/content/browser/BUILD.gn index cc183878..aa6f3a99 100644 --- a/components/dom_distiller/content/browser/BUILD.gn +++ b/components/dom_distiller/content/browser/BUILD.gn
@@ -16,7 +16,6 @@ "distiller_javascript_utils.h", "distiller_page_web_contents.cc", "distiller_page_web_contents.h", - "distiller_ui_handle.h", "dom_distiller_viewer_source.cc", "dom_distiller_viewer_source.h", "web_contents_main_frame_observer.cc",
diff --git a/components/dom_distiller/content/browser/distillability_driver.cc b/components/dom_distiller/content/browser/distillability_driver.cc index 683917f..75606c3 100644 --- a/components/dom_distiller/content/browser/distillability_driver.cc +++ b/components/dom_distiller/content/browser/distillability_driver.cc
@@ -63,12 +63,6 @@ std::move(receiver)); } -void DistillabilityDriver::AddObserver(DistillabilityObserver* observer) { - if (!observers_.HasObserver(observer)) { - observers_.AddObserver(observer); - } -} - void DistillabilityDriver::OnDistillability( const DistillabilityResult& result) { latest_result_ = result;
diff --git a/components/dom_distiller/content/browser/distillability_driver.h b/components/dom_distiller/content/browser/distillability_driver.h index 516311f..272eab9 100644 --- a/components/dom_distiller/content/browser/distillability_driver.h +++ b/components/dom_distiller/content/browser/distillability_driver.h
@@ -28,7 +28,9 @@ void CreateDistillabilityService( mojo::PendingReceiver<mojom::DistillabilityService> receiver); - void AddObserver(DistillabilityObserver* observer); + base::ObserverList<DistillabilityObserver>* GetObserverList() { + return &observers_; + } base::Optional<DistillabilityResult> GetLatestResult() const { return latest_result_; }
diff --git a/components/dom_distiller/content/browser/distillable_page_utils.cc b/components/dom_distiller/content/browser/distillable_page_utils.cc index b666b154..24ac793 100644 --- a/components/dom_distiller/content/browser/distillable_page_utils.cc +++ b/components/dom_distiller/content/browser/distillable_page_utils.cc
@@ -59,13 +59,34 @@ void AddObserver(content::WebContents* web_contents, DistillabilityObserver* observer) { + DCHECK(observer); CHECK(web_contents); DistillabilityDriver::CreateForWebContents(web_contents); DistillabilityDriver* driver = DistillabilityDriver::FromWebContents(web_contents); CHECK(driver); - driver->AddObserver(observer); + base::ObserverList<DistillabilityObserver>* observer_list = + driver->GetObserverList(); + if (!observer_list->HasObserver(observer)) { + observer_list->AddObserver(observer); + } +} + +void RemoveObserver(content::WebContents* web_contents, + DistillabilityObserver* observer) { + DCHECK(observer); + CHECK(web_contents); + DistillabilityDriver::CreateForWebContents(web_contents); + + DistillabilityDriver* driver = + DistillabilityDriver::FromWebContents(web_contents); + CHECK(driver); + base::ObserverList<DistillabilityObserver>* observer_list = + driver->GetObserverList(); + if (observer_list->HasObserver(observer)) { + observer_list->RemoveObserver(observer); + } } base::Optional<DistillabilityResult> GetLatestResult(
diff --git a/components/dom_distiller/content/browser/distillable_page_utils.h b/components/dom_distiller/content/browser/distillable_page_utils.h index 3754622..599a7ab 100644 --- a/components/dom_distiller/content/browser/distillable_page_utils.h +++ b/components/dom_distiller/content/browser/distillable_page_utils.h
@@ -40,11 +40,14 @@ virtual void OnResult(const DistillabilityResult& result) = 0; }; -// Set the delegate to receive the result of whether the page is distillable. +// Add/remove objects to the list of observers to notify when the distillability +// service returns a result. // -// |web_contents| must be non-null. +// |web_contents| and |observer| must both be non-null. void AddObserver(content::WebContents* web_contents, DistillabilityObserver* observer); +void RemoveObserver(content::WebContents* web_contents, + DistillabilityObserver* observer); base::Optional<DistillabilityResult> GetLatestResult( content::WebContents* web_contents);
diff --git a/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc b/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc index 9d993ad87..faf05be 100644 --- a/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc +++ b/components/dom_distiller/content/browser/distiller_javascript_service_impl.cc
@@ -4,21 +4,13 @@ #include "components/dom_distiller/content/browser/distiller_javascript_service_impl.h" -#include <memory> -#include <utility> - -#include "base/metrics/user_metrics.h" -#include "components/dom_distiller/content/browser/distiller_ui_handle.h" -#include "components/dom_distiller/core/feedback_reporter.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" namespace dom_distiller { DistillerJavaScriptServiceImpl::DistillerJavaScriptServiceImpl( - content::RenderFrameHost* render_frame_host, DistillerUIHandle* distiller_ui_handle) - : render_frame_host_(render_frame_host), - distiller_ui_handle_(distiller_ui_handle) {} + : distiller_ui_handle_(distiller_ui_handle) {} DistillerJavaScriptServiceImpl::~DistillerJavaScriptServiceImpl() {} @@ -26,18 +18,16 @@ if (!distiller_ui_handle_) { return; } - content::WebContents* contents = - content::WebContents::FromRenderFrameHost(render_frame_host_); - distiller_ui_handle_->OpenSettings(contents); + + distiller_ui_handle_->OpenSettings(); } void CreateDistillerJavaScriptService( DistillerUIHandle* distiller_ui_handle, - mojo::PendingReceiver<mojom::DistillerJavaScriptService> receiver, - content::RenderFrameHost* render_frame_host) { - mojo::MakeSelfOwnedReceiver(std::make_unique<DistillerJavaScriptServiceImpl>( - render_frame_host, distiller_ui_handle), - std::move(receiver)); + mojo::PendingReceiver<mojom::DistillerJavaScriptService> receiver) { + mojo::MakeSelfOwnedReceiver( + std::make_unique<DistillerJavaScriptServiceImpl>(distiller_ui_handle), + std::move(receiver)); } } // namespace dom_distiller
diff --git a/components/dom_distiller/content/browser/distiller_javascript_service_impl.h b/components/dom_distiller/content/browser/distiller_javascript_service_impl.h index 1bd75c26..b5c5dd8 100644 --- a/components/dom_distiller/content/browser/distiller_javascript_service_impl.h +++ b/components/dom_distiller/content/browser/distiller_javascript_service_impl.h
@@ -6,8 +6,8 @@ #define COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_DISTILLER_JAVASCRIPT_SERVICE_IMPL_H_ #include "base/macros.h" -#include "components/dom_distiller/content/browser/distiller_ui_handle.h" #include "components/dom_distiller/content/common/mojom/distiller_javascript_service.mojom.h" +#include "components/dom_distiller/core/distiller_ui_handle.h" #include "mojo/public/cpp/bindings/pending_receiver.h" namespace dom_distiller { @@ -16,8 +16,7 @@ class DistillerJavaScriptServiceImpl : public mojom::DistillerJavaScriptService { public: - DistillerJavaScriptServiceImpl(content::RenderFrameHost* render_frame_host, - DistillerUIHandle* distiller_ui_handle); + DistillerJavaScriptServiceImpl(DistillerUIHandle* distiller_ui_handle); ~DistillerJavaScriptServiceImpl() override; // Mojo mojom::DistillerJavaScriptService implementation. @@ -26,7 +25,6 @@ void HandleDistillerOpenSettingsCall() override; private: - content::RenderFrameHost* render_frame_host_; DistillerUIHandle* distiller_ui_handle_; DISALLOW_COPY_AND_ASSIGN(DistillerJavaScriptServiceImpl); @@ -35,8 +33,7 @@ // static void CreateDistillerJavaScriptService( DistillerUIHandle* distiller_ui_handle, - mojo::PendingReceiver<mojom::DistillerJavaScriptService> receiver, - content::RenderFrameHost* render_frame_host); + mojo::PendingReceiver<mojom::DistillerJavaScriptService> receiver); } // namespace dom_distiller
diff --git a/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc b/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc index d9208b5..6f57f7b4 100644 --- a/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc +++ b/components/dom_distiller/content/browser/dom_distiller_viewer_source.cc
@@ -18,9 +18,7 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/threading/thread_task_runner_handle.h" -#include "components/dom_distiller/content/browser/distiller_javascript_service_impl.h" #include "components/dom_distiller/content/browser/distiller_javascript_utils.h" -#include "components/dom_distiller/content/browser/distiller_ui_handle.h" #include "components/dom_distiller/content/common/mojom/distiller_page_notifier_service.mojom.h" #include "components/dom_distiller/core/distilled_page_prefs.h" #include "components/dom_distiller/core/dom_distiller_request_view_base.h" @@ -41,7 +39,6 @@ #include "mojo/public/cpp/bindings/remote.h" #include "net/base/url_util.h" #include "net/url_request/url_request.h" -#include "services/service_manager/public/cpp/binder_registry.h" #include "services/service_manager/public/cpp/interface_provider.h" #include "ui/base/l10n/l10n_util.h" @@ -56,8 +53,7 @@ public: RequestViewerHandle(content::WebContents* web_contents, const GURL& expected_url, - DistilledPagePrefs* distilled_page_prefs, - DistillerUIHandle* ui_handle); + DistilledPagePrefs* distilled_page_prefs); ~RequestViewerHandle() override; // content::WebContentsObserver implementation: @@ -66,10 +62,6 @@ void RenderProcessGone(base::TerminationStatus status) override; void WebContentsDestroyed() override; void DOMContentLoaded(content::RenderFrameHost* render_frame_host) override; - void OnInterfaceRequestFromFrame( - content::RenderFrameHost* render_frame_host, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) override; private: // Sends JavaScript to the attached Viewer, buffering data if the viewer isn't @@ -91,30 +83,17 @@ // Temporary store of pending JavaScript if the page isn't ready to receive // data from distillation. std::string buffer_; - - // An object for accessing chrome-specific UI controls including external - // feedback and opening the distiller settings. Guaranteed to outlive this - // object. - DistillerUIHandle* distiller_ui_handle_; - - service_manager::BinderRegistryWithArgs<content::RenderFrameHost*> - frame_interfaces_; }; DomDistillerViewerSource::RequestViewerHandle::RequestViewerHandle( content::WebContents* web_contents, const GURL& expected_url, - DistilledPagePrefs* distilled_page_prefs, - DistillerUIHandle* ui_handle) + DistilledPagePrefs* distilled_page_prefs) : DomDistillerRequestViewBase(distilled_page_prefs), expected_url_(expected_url), - waiting_for_page_ready_(true), - distiller_ui_handle_(ui_handle) { + waiting_for_page_ready_(true) { content::WebContentsObserver::Observe(web_contents); distilled_page_prefs_->AddObserver(this); - - frame_interfaces_.AddInterface( - base::Bind(&CreateDistillerJavaScriptService, distiller_ui_handle_)); } DomDistillerViewerSource::RequestViewerHandle::~RequestViewerHandle() { @@ -213,21 +192,10 @@ // No need to Cancel() here. } -void DomDistillerViewerSource::RequestViewerHandle::OnInterfaceRequestFromFrame( - content::RenderFrameHost* render_frame_host, - const std::string& interface_name, - mojo::ScopedMessagePipeHandle* interface_pipe) { - frame_interfaces_.TryBindInterface(interface_name, interface_pipe, - render_frame_host); -} - DomDistillerViewerSource::DomDistillerViewerSource( DomDistillerServiceInterface* dom_distiller_service, - const std::string& scheme, - std::unique_ptr<DistillerUIHandle> ui_handle) - : scheme_(scheme), - dom_distiller_service_(dom_distiller_service), - distiller_ui_handle_(std::move(ui_handle)) {} + const std::string& scheme) + : scheme_(scheme), dom_distiller_service_(dom_distiller_service) {} DomDistillerViewerSource::~DomDistillerViewerSource() {} @@ -277,8 +245,7 @@ } RequestViewerHandle* request_viewer_handle = new RequestViewerHandle(web_contents, request_url, - dom_distiller_service_->GetDistilledPagePrefs(), - distiller_ui_handle_.get()); + dom_distiller_service_->GetDistilledPagePrefs()); std::unique_ptr<ViewerHandle> viewer_handle = viewer::CreateViewRequest( dom_distiller_service_, request_url, request_viewer_handle, web_contents->GetContainerBounds().size());
diff --git a/components/dom_distiller/content/browser/dom_distiller_viewer_source.h b/components/dom_distiller/content/browser/dom_distiller_viewer_source.h index 85f1899..f011c182 100644 --- a/components/dom_distiller/content/browser/dom_distiller_viewer_source.h +++ b/components/dom_distiller/content/browser/dom_distiller_viewer_source.h
@@ -10,7 +10,6 @@ #include "base/compiler_specific.h" #include "base/macros.h" -#include "components/dom_distiller/content/browser/distiller_ui_handle.h" #include "content/public/browser/url_data_source.h" #include "content/public/browser/web_contents.h" @@ -23,8 +22,7 @@ class DomDistillerViewerSource : public content::URLDataSource { public: DomDistillerViewerSource(DomDistillerServiceInterface* dom_distiller_service, - const std::string& scheme, - std::unique_ptr<DistillerUIHandle> ui_handle); + const std::string& scheme); ~DomDistillerViewerSource() override; class RequestViewerHandle; @@ -52,10 +50,6 @@ // the list of articles. DomDistillerServiceInterface* dom_distiller_service_; - // An object for accessing chrome-specific UI controls including external - // feedback and opening the distiller settings. - std::unique_ptr<DistillerUIHandle> distiller_ui_handle_; - DISALLOW_COPY_AND_ASSIGN(DomDistillerViewerSource); };
diff --git a/components/dom_distiller/content/browser/dom_distiller_viewer_source_unittest.cc b/components/dom_distiller/content/browser/dom_distiller_viewer_source_unittest.cc index 5238069e..7da63c81 100644 --- a/components/dom_distiller/content/browser/dom_distiller_viewer_source_unittest.cc +++ b/components/dom_distiller/content/browser/dom_distiller_viewer_source_unittest.cc
@@ -14,7 +14,7 @@ class DomDistillerViewerSourceTest : public testing::Test { public: void SetUp() override { - source_.reset(new DomDistillerViewerSource(nullptr, kTestScheme, nullptr)); + source_.reset(new DomDistillerViewerSource(nullptr, kTestScheme)); } protected:
diff --git a/components/dom_distiller/content/renderer/distiller_native_javascript.cc b/components/dom_distiller/content/renderer/distiller_native_javascript.cc index e6a4ce4..0c1831e 100644 --- a/components/dom_distiller/content/renderer/distiller_native_javascript.cc +++ b/components/dom_distiller/content/renderer/distiller_native_javascript.cc
@@ -12,7 +12,7 @@ #include "content/public/renderer/render_frame.h" #include "gin/arguments.h" #include "gin/function_template.h" -#include "services/service_manager/public/cpp/interface_provider.h" +#include "third_party/blink/public/common/browser_interface_broker_proxy.h" #include "third_party/blink/public/web/blink.h" #include "v8/include/v8.h" @@ -66,7 +66,7 @@ void DistillerNativeJavaScript::EnsureServiceConnected() { if (!distiller_js_service_) { - render_frame_->GetRemoteInterfaces()->GetInterface( + render_frame_->GetBrowserInterfaceBroker()->GetInterface( distiller_js_service_.BindNewPipeAndPassReceiver()); } }
diff --git a/components/dom_distiller/core/BUILD.gn b/components/dom_distiller/core/BUILD.gn index 4a681d84..14bf4db 100644 --- a/components/dom_distiller/core/BUILD.gn +++ b/components/dom_distiller/core/BUILD.gn
@@ -20,6 +20,7 @@ "distiller.h", "distiller_page.cc", "distiller_page.h", + "distiller_ui_handle.h", "distiller_url_fetcher.cc", "distiller_url_fetcher.h", "dom_distiller_constants.cc",
diff --git a/components/dom_distiller/content/browser/distiller_ui_handle.h b/components/dom_distiller/core/distiller_ui_handle.h similarity index 62% rename from components/dom_distiller/content/browser/distiller_ui_handle.h rename to components/dom_distiller/core/distiller_ui_handle.h index 36e58ff..6ecb7a6 100644 --- a/components/dom_distiller/content/browser/distiller_ui_handle.h +++ b/components/dom_distiller/core/distiller_ui_handle.h
@@ -2,11 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_DISTILLER_UI_HANDLE_H_ -#define COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_DISTILLER_UI_HANDLE_H_ +#ifndef COMPONENTS_DOM_DISTILLER_CORE_DISTILLER_UI_HANDLE_H_ +#define COMPONENTS_DOM_DISTILLER_CORE_DISTILLER_UI_HANDLE_H_ #include "base/macros.h" -#include "content/public/browser/web_contents.h" #include "url/gurl.h" namespace dom_distiller { @@ -19,7 +18,7 @@ virtual ~DistillerUIHandle() {} // Open the UI settings for dom distiller. - virtual void OpenSettings(content::WebContents* web_contents) = 0; + virtual void OpenSettings() = 0; private: DISALLOW_COPY_AND_ASSIGN(DistillerUIHandle); @@ -27,4 +26,4 @@ } // namespace dom_distiller -#endif // COMPONENTS_DOM_DISTILLER_CONTENT_BROWSER_DISTILLER_UI_HANDLE_H_ +#endif // COMPONENTS_DOM_DISTILLER_CORE_DISTILLER_UI_HANDLE_H_
diff --git a/components/dom_distiller/core/dom_distiller_service.cc b/components/dom_distiller/core/dom_distiller_service.cc index 34abda8..2311459c 100644 --- a/components/dom_distiller/core/dom_distiller_service.cc +++ b/components/dom_distiller/core/dom_distiller_service.cc
@@ -35,11 +35,13 @@ DomDistillerService::DomDistillerService( std::unique_ptr<DistillerFactory> distiller_factory, std::unique_ptr<DistillerPageFactory> distiller_page_factory, - std::unique_ptr<DistilledPagePrefs> distilled_page_prefs) + std::unique_ptr<DistilledPagePrefs> distilled_page_prefs, + std::unique_ptr<DistillerUIHandle> distiller_ui_handle) : content_store_(new InMemoryContentStore(kDefaultMaxNumCachedEntries)), distiller_factory_(std::move(distiller_factory)), distiller_page_factory_(std::move(distiller_page_factory)), - distilled_page_prefs_(std::move(distilled_page_prefs)) {} + distilled_page_prefs_(std::move(distilled_page_prefs)), + distiller_ui_handle_(std::move(distiller_ui_handle)) {} DomDistillerService::~DomDistillerService() {} @@ -123,4 +125,8 @@ return distilled_page_prefs_.get(); } +DistillerUIHandle* DomDistillerService::GetDistillerUIHandle() { + return distiller_ui_handle_.get(); +} + } // namespace dom_distiller
diff --git a/components/dom_distiller/core/dom_distiller_service.h b/components/dom_distiller/core/dom_distiller_service.h index bb9d000..2cf44ba 100644 --- a/components/dom_distiller/core/dom_distiller_service.h +++ b/components/dom_distiller/core/dom_distiller_service.h
@@ -14,6 +14,7 @@ #include "components/dom_distiller/core/article_entry.h" #include "components/dom_distiller/core/distilled_page_prefs.h" #include "components/dom_distiller/core/distiller_page.h" +#include "components/dom_distiller/core/distiller_ui_handle.h" class GURL; @@ -53,6 +54,10 @@ // DomDistillerService. virtual DistilledPagePrefs* GetDistilledPagePrefs() = 0; + // Returns the DistillerUIHandle owned by the instance of + // DomDistillerService. + virtual DistillerUIHandle* GetDistillerUIHandle() = 0; + protected: DomDistillerServiceInterface() {} @@ -66,7 +71,8 @@ DomDistillerService( std::unique_ptr<DistillerFactory> distiller_factory, std::unique_ptr<DistillerPageFactory> distiller_page_factory, - std::unique_ptr<DistilledPagePrefs> distilled_page_prefs); + std::unique_ptr<DistilledPagePrefs> distilled_page_prefs, + std::unique_ptr<DistillerUIHandle> distiller_ui_handle); ~DomDistillerService() override; // DomDistillerServiceInterface implementation. @@ -79,6 +85,7 @@ std::unique_ptr<DistillerPage> CreateDefaultDistillerPageWithHandle( std::unique_ptr<SourcePageHandle> handle) override; DistilledPagePrefs* GetDistilledPagePrefs() override; + DistillerUIHandle* GetDistillerUIHandle() override; private: void CancelTask(TaskTracker* task); @@ -99,6 +106,10 @@ std::unique_ptr<DistillerPageFactory> distiller_page_factory_; std::unique_ptr<DistilledPagePrefs> distilled_page_prefs_; + // An object for accessing chrome-specific UI controls including external + // feedback and opening the distiller settings. + std::unique_ptr<DistillerUIHandle> distiller_ui_handle_; + typedef std::vector<std::unique_ptr<TaskTracker>> TaskList; TaskList tasks_;
diff --git a/components/dom_distiller/core/dom_distiller_service_unittest.cc b/components/dom_distiller/core/dom_distiller_service_unittest.cc index 24f8b0d..b2efb10 100644 --- a/components/dom_distiller/core/dom_distiller_service_unittest.cc +++ b/components/dom_distiller/core/dom_distiller_service_unittest.cc
@@ -68,7 +68,8 @@ service_.reset(new DomDistillerService( std::unique_ptr<DistillerFactory>(distiller_factory_), std::unique_ptr<DistillerPageFactory>(distiller_page_factory_), - std::unique_ptr<DistilledPagePrefs>())); + /* distilled_page_prefs */ nullptr, + /* distiller_ui_handle */ nullptr)); } void TearDown() override {
diff --git a/components/dom_distiller/core/viewer_unittest.cc b/components/dom_distiller/core/viewer_unittest.cc index 20285cd..a03ec3c2 100644 --- a/components/dom_distiller/core/viewer_unittest.cc +++ b/components/dom_distiller/core/viewer_unittest.cc
@@ -5,6 +5,7 @@ #include "components/dom_distiller/core/viewer.h" #include "components/dom_distiller/core/distilled_page_prefs.h" +#include "components/dom_distiller/core/distiller_ui_handle.h" #include "components/dom_distiller/core/dom_distiller_service.h" #include "components/dom_distiller/core/task_tracker.h" #include "components/dom_distiller/core/url_constants.h" @@ -57,6 +58,7 @@ return std::unique_ptr<DistillerPage>(); } DistilledPagePrefs* GetDistilledPagePrefs() override; + DistillerUIHandle* GetDistillerUIHandle() override; }; class DomDistillerViewerTest : public testing::Test { @@ -113,6 +115,10 @@ return nullptr; } +DistillerUIHandle* TestDomDistillerService::GetDistillerUIHandle() { + return nullptr; +} + TEST_F(DomDistillerViewerTest, TestGetDistilledPageThemeJsOutput) { std::string kDarkJs = "useTheme('dark');"; std::string kSepiaJs = "useTheme('sepia');";
diff --git a/components/dom_distiller/standalone/content_extractor_browsertest.cc b/components/dom_distiller/standalone/content_extractor_browsertest.cc index b0c9284..44bf091 100644 --- a/components/dom_distiller/standalone/content_extractor_browsertest.cc +++ b/components/dom_distiller/standalone/content_extractor_browsertest.cc
@@ -164,7 +164,8 @@ return std::make_unique<DomDistillerService>( std::move(distiller_factory), std::move(distiller_page_factory), - std::make_unique<DistilledPagePrefs>(pref_service)); + std::make_unique<DistilledPagePrefs>(pref_service), + /* distiller_ui_handle */ nullptr); } void AddComponentsTestResources() {
diff --git a/components/drive/BUILD.gn b/components/drive/BUILD.gn index 9b8cb960..dec1fd2 100644 --- a/components/drive/BUILD.gn +++ b/components/drive/BUILD.gn
@@ -17,26 +17,10 @@ "drive_uploader.h", "event_logger.cc", "event_logger.h", - "file_change.cc", - "file_change.h", "file_errors.cc", "file_errors.h", "file_system_core_util.cc", "file_system_core_util.h", - "file_system_metadata.cc", - "file_system_metadata.h", - "file_write_watcher.cc", - "file_write_watcher.h", - "job_list.cc", - "job_list.h", - "job_queue.cc", - "job_queue.h", - "job_scheduler.cc", - "job_scheduler.h", - "local_file_reader.cc", - "local_file_reader.h", - "resource_entry_conversion.cc", - "resource_entry_conversion.h", "resource_metadata_storage.cc", "resource_metadata_storage.h", "service/drive_api_service.cc", @@ -46,17 +30,11 @@ ] deps = [ "//base", - "//base:i18n", "//components/invalidation/public", "//components/keyed_service/core", - "//components/prefs", - - # TODO(lukasza): Remove this dependency (see DEPS file for more info). - "//content/public/browser", - "//google_apis", "//google_apis/drive", - "//net", "//services/device/public/mojom", + "//services/network/public/cpp:cpp", "//third_party/cacheinvalidation", "//third_party/leveldatabase", "//third_party/re2", @@ -84,11 +62,7 @@ ] deps = [ ":drive", - ":proto", "//base", - "//components/prefs:test_support", - "//content/test:test_support", - "//google_apis:test_support", "//google_apis/drive:test_support", "//net:net", ] @@ -97,56 +71,14 @@ if (is_chromeos) { source_set("drive_chromeos") { sources = [ - "chromeos/change_list_processor.cc", - "chromeos/change_list_processor.h", - "chromeos/drive_file_util.cc", - "chromeos/drive_file_util.h", - "chromeos/drive_operation_queue.h", - "chromeos/file_cache.cc", - "chromeos/file_cache.h", - "chromeos/file_system_interface.cc", - "chromeos/file_system_interface.h", - "chromeos/file_system_observer.h", - "chromeos/remove_stale_cache_files.cc", - "chromeos/remove_stale_cache_files.h", - "chromeos/resource_metadata.cc", - "chromeos/resource_metadata.h", "chromeos/search_metadata.cc", "chromeos/search_metadata.h", - "chromeos/team_drive.cc", - "chromeos/team_drive.h", - "chromeos/team_drive_list_observer.h", ] deps = [ ":drive", "//base", "//base:i18n", - "//components/prefs", - "//google_apis", - "//google_apis/drive", "//net", ] - public_deps = [ - ":proto", - ] - } - static_library("test_support_chromeos") { - testonly = true - sources = [ - "chromeos/drive_test_util.cc", - "chromeos/drive_test_util.h", - "chromeos/fake_free_disk_space_getter.cc", - "chromeos/fake_free_disk_space_getter.h", - ] - deps = [ - ":drive", - ":drive_chromeos", - ":proto", - "//base", - "//components/prefs:test_support", - "//content/test:test_support", - "//google_apis:test_support", - "//google_apis/drive:test_support", - ] } }
diff --git a/components/drive/DEPS b/components/drive/DEPS index 851b225..5885c14 100644 --- a/components/drive/DEPS +++ b/components/drive/DEPS
@@ -1,7 +1,6 @@ include_rules = [ "+components/invalidation", "+components/keyed_service", - "+components/prefs", "+google_apis", "+google/cacheinvalidation/types.pb.h", "+mojo/public", @@ -16,37 +15,8 @@ specific_include_rules = { # The following test dependencies should be removed to fully componentize this # directory. crbug.com/498951 - "drive_test_util\.h": [ - "+content/public/test/test_utils.h", - ], - - # The following test dependencies should be removed to fully componentize this - # directory. crbug.com/498951 - r"(change_list_processor_unittest\.cc" - r"|drive_file_util_unittest\.cc" - r"|file_cache_unittest\.cc" - r"|file_system_core_util_unittest\.cc" - r"|file_write_watcher_unittest\.cc" - r"|job_scheduler_unittest\.cc" - r"|remove_stale_cache_files_unittest\.cc" - r"|resource_metadata_storage_unittest\.cc" - r"|resource_metadata_unittest\.cc" - r"|search_metadata_unittest\.cc" - r")": [ + "resource_metadata_storage_unittest\.cc": [ "+content/public/test/browser_task_environment.h", - ], - - # The following test dependencies should be removed to fully componentize this - # directory. crbug.com/498951 - r"(drive_uploader\.cc" - r"|file_write_watcher_unittest\.cc" - r")": [ - "+content/public/browser/browser_thread.h", - ], - - # The dependency below is ok and can stay here for the long-term, because it - # is guarded by #if defined(OS_CHROMEOS) in the source code. - "file_cache\.h": [ - "+third_party/cros_system_api/constants/cryptohome.h", + "+content/public/test/test_utils.h", ], }
diff --git a/components/drive/change_list_processor_unittest.cc b/components/drive/change_list_processor_unittest.cc deleted file mode 100644 index 4213205..0000000 --- a/components/drive/change_list_processor_unittest.cc +++ /dev/null
@@ -1,803 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/chromeos/change_list_processor.h" - -#include <stddef.h> -#include <stdint.h> -#include <memory> -#include <utility> - -#include "base/command_line.h" -#include "base/files/scoped_temp_dir.h" -#include "base/single_thread_task_runner.h" -#include "base/stl_util.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/values.h" -#include "components/drive/chromeos/drive_test_util.h" -#include "components/drive/chromeos/fake_free_disk_space_getter.h" -#include "components/drive/chromeos/file_cache.h" -#include "components/drive/chromeos/resource_metadata.h" -#include "components/drive/drive.pb.h" -#include "components/drive/file_change.h" -#include "components/drive/file_system_core_util.h" -#include "content/public/test/browser_task_environment.h" -#include "google_apis/drive/drive_api_parser.h" -#include "google_apis/drive/test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { -namespace internal { - -namespace { - -constexpr char kBaseStartPageToken[] = "123"; -constexpr char kRootId[] = "fake_root"; - -enum FileOrDirectory { - FILE, - DIRECTORY, -}; - -struct EntryExpectation { - std::string path; - std::string id; - std::string parent_id; - FileOrDirectory type; -}; - -// Returns a basic change list which contains some files and directories. -std::vector<std::unique_ptr<ChangeList>> CreateBaseChangeList() { - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - // Add directories to the change list. - ResourceEntry directory; - directory.mutable_file_info()->set_is_directory(true); - - directory.set_title("Directory 1"); - directory.set_resource_id("1_folder_resource_id"); - change_lists[0]->mutable_entries()->push_back(directory); - change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); - - directory.set_title("Sub Directory Folder"); - directory.set_resource_id("sub_dir_folder_resource_id"); - change_lists[0]->mutable_entries()->push_back(directory); - change_lists[0]->mutable_parent_resource_ids()->push_back( - "1_folder_resource_id"); - - directory.set_title("Sub Sub Directory Folder"); - directory.set_resource_id("sub_sub_directory_folder_id"); - change_lists[0]->mutable_entries()->push_back(directory); - change_lists[0]->mutable_parent_resource_ids()->push_back( - "sub_dir_folder_resource_id"); - - directory.set_title("Directory 2 excludeDir-test"); - directory.set_resource_id("sub_dir_folder_2_self_link"); - change_lists[0]->mutable_entries()->push_back(directory); - change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); - - // Add files to the change list. - ResourceEntry file; - - file.set_title("File 1.txt"); - file.set_resource_id("2_file_resource_id"); - change_lists[0]->mutable_entries()->push_back(file); - change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); - - file.set_title("SubDirectory File 1.txt"); - file.set_resource_id("subdirectory_file_1_id"); - Property* const property = file.mutable_new_properties()->Add(); - property->set_key("hello"); - property->set_value("world"); - change_lists[0]->mutable_entries()->push_back(file); - change_lists[0]->mutable_parent_resource_ids()->push_back( - "1_folder_resource_id"); - - file.set_title("Orphan File 1.txt"); - file.set_resource_id("1_orphanfile_resource_id"); - change_lists[0]->mutable_entries()->push_back(file); - change_lists[0]->mutable_parent_resource_ids()->push_back(""); - - change_lists[0]->set_new_start_page_token(kBaseStartPageToken); - return change_lists; -} - -class ChangeListProcessorTest : public testing::Test { - protected: - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - - metadata_storage_.reset(new ResourceMetadataStorage( - temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); - ASSERT_TRUE(metadata_storage_->Initialize()); - - fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>(); - cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(), - base::ThreadTaskRunnerHandle::Get().get(), - fake_free_disk_space_getter_.get())); - ASSERT_TRUE(cache_->Initialize()); - - metadata_.reset( - new internal::ResourceMetadata(metadata_storage_.get(), cache_.get(), - base::ThreadTaskRunnerHandle::Get())); - ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize()); - } - - // Applies the |changes| to |metadata_| as a full resource list of - // start page token |kBaseStartPageToken|. - FileError ApplyFullResourceList( - std::vector<std::unique_ptr<ChangeList>> changes) { - ChangeListProcessor processor(util::kTeamDriveIdDefaultCorpus, - util::GetDriveMyDriveRootPath(), - metadata_.get(), nullptr); - return processor.ApplyUserChangeList(kBaseStartPageToken, kRootId, - std::move(changes), - false /* is_delta_update */); - } - - // Applies |changes| to |metadata_| as a delta update. The |changes| are - // treated as user's changelists. Delta changelists should contain their - // start page token in themselves. |changede_team_drives| returns any team - // drives that were added or removed as part of the change list. - FileError ApplyUserChangeList( - std::vector<std::unique_ptr<ChangeList>> changes, - FileChange* changed_files, - FileChange* changed_team_drives) { - ChangeListProcessor processor(util::kTeamDriveIdDefaultCorpus, - util::GetDriveMyDriveRootPath(), - metadata_.get(), nullptr); - FileError error = processor.ApplyUserChangeList(kBaseStartPageToken, - kRootId, std::move(changes), - true /* is_delta_update */); - *changed_files = processor.changed_files(); - *changed_team_drives = processor.changed_team_drives(); - return error; - } - - // Gets the resource entry for the path from |metadata_| synchronously. - // Returns null if the entry does not exist. - std::unique_ptr<ResourceEntry> GetResourceEntry(const std::string& path) { - std::unique_ptr<ResourceEntry> entry(new ResourceEntry); - FileError error = metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe(path), entry.get()); - if (error != FILE_ERROR_OK) - entry.reset(); - return entry; - } - - content::BrowserTaskEnvironment task_environment_; - base::ScopedTempDir temp_dir_; - std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests> - metadata_storage_; - std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_; - std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_; - std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_; -}; - -} // namespace - -TEST_F(ChangeListProcessorTest, ApplyFullResourceList) { - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - - const EntryExpectation kExpected[] = { - // Root files - {"drive/root", kRootId, "", DIRECTORY}, - {"drive/root/File 1.txt", - "2_file_resource_id", kRootId, FILE}, - // Subdirectory files - {"drive/root/Directory 1", - "1_folder_resource_id", kRootId, DIRECTORY}, - {"drive/root/Directory 1/SubDirectory File 1.txt", - "subdirectory_file_1_id", "1_folder_resource_id", FILE}, - {"drive/root/Directory 2 excludeDir-test", - "sub_dir_folder_2_self_link", kRootId, DIRECTORY}, - // Deeper - {"drive/root/Directory 1/Sub Directory Folder", - "sub_dir_folder_resource_id", - "1_folder_resource_id", DIRECTORY}, - {"drive/root/Directory 1/Sub Directory Folder/Sub Sub Directory Folder", - "sub_sub_directory_folder_id", - "sub_dir_folder_resource_id", DIRECTORY}, - // Orphan - {"drive/other/Orphan File 1.txt", "1_orphanfile_resource_id", - "", FILE}, - }; - - for (size_t i = 0; i < base::size(kExpected); ++i) { - std::unique_ptr<ResourceEntry> entry = GetResourceEntry(kExpected[i].path); - ASSERT_TRUE(entry) << "for path: " << kExpected[i].path; - EXPECT_EQ(kExpected[i].id, entry->resource_id()); - - ResourceEntry parent_entry; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryById( - entry->parent_local_id(), &parent_entry)); - EXPECT_EQ(kExpected[i].parent_id, parent_entry.resource_id()); - EXPECT_EQ(kExpected[i].type, - entry->file_info().is_directory() ? DIRECTORY : FILE); - } - - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ(kBaseStartPageToken, start_page_token); -} - -TEST_F(ChangeListProcessorTest, DeltaFileAddedInNewDirectory) { - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - ResourceEntry new_folder; - new_folder.set_resource_id("new_folder_resource_id"); - new_folder.set_title("New Directory"); - new_folder.mutable_file_info()->set_is_directory(true); - change_lists[0]->mutable_entries()->push_back(new_folder); - change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); - - ResourceEntry new_file; - new_file.set_resource_id("file_added_in_new_dir_id"); - new_file.set_title("File in new dir.txt"); - change_lists[0]->mutable_entries()->push_back(new_file); - change_lists[0]->mutable_parent_resource_ids()->push_back( - new_folder.resource_id()); - - change_lists[0]->set_new_start_page_token("16730"); - - // Apply the changelist and check the effect. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16730", start_page_token); - EXPECT_TRUE(GetResourceEntry("drive/root/New Directory")); - EXPECT_TRUE(GetResourceEntry( - "drive/root/New Directory/File in new dir.txt")); - - EXPECT_TRUE(changed_team_drives.empty()); - EXPECT_EQ(2U, changed_files.size()); - EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe( - "drive/root/New Directory/File in new dir.txt"))); - EXPECT_TRUE(changed_files.count( - base::FilePath::FromUTF8Unsafe("drive/root/New Directory"))); -} - -TEST_F(ChangeListProcessorTest, DeltaDirMovedFromRootToDirectory) { - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - ResourceEntry entry; - entry.set_resource_id("1_folder_resource_id"); - entry.set_title("Directory 1"); - entry.mutable_file_info()->set_is_directory(true); - change_lists[0]->mutable_entries()->push_back(entry); - change_lists[0]->mutable_parent_resource_ids()->push_back( - "sub_dir_folder_2_self_link"); - - change_lists[0]->set_new_start_page_token("16809"); - - // Apply the changelist and check the effect. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16809", start_page_token); - EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1")); - EXPECT_TRUE(GetResourceEntry( - "drive/root/Directory 2 excludeDir-test/Directory 1")); - - EXPECT_TRUE(changed_team_drives.empty()); - EXPECT_EQ(2U, changed_files.size()); - EXPECT_TRUE(changed_files.CountDirectory( - base::FilePath::FromUTF8Unsafe("drive/root"))); - EXPECT_TRUE(changed_files.count( - base::FilePath::FromUTF8Unsafe("drive/root/Directory 1"))); - EXPECT_TRUE(changed_files.CountDirectory(base::FilePath::FromUTF8Unsafe( - "drive/root/Directory 2 excludeDir-test"))); - EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe( - "drive/root/Directory 2 excludeDir-test/Directory 1"))); -} - -TEST_F(ChangeListProcessorTest, DeltaFileMovedFromDirectoryToRoot) { - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - ResourceEntry entry; - entry.set_resource_id("subdirectory_file_1_id"); - entry.set_title("SubDirectory File 1.txt"); - change_lists[0]->mutable_entries()->push_back(entry); - change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); - - change_lists[0]->set_new_start_page_token("16815"); - - // Apply the changelist and check the effect. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16815", start_page_token); - EXPECT_FALSE(GetResourceEntry( - "drive/root/Directory 1/SubDirectory File 1.txt")); - EXPECT_TRUE(GetResourceEntry("drive/root/SubDirectory File 1.txt")); - - EXPECT_TRUE(changed_team_drives.empty()); - EXPECT_EQ(2U, changed_files.size()); - EXPECT_TRUE(changed_files.count( - base::FilePath::FromUTF8Unsafe("drive/root/SubDirectory File 1.txt"))); - EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe( - "drive/root/Directory 1/SubDirectory File 1.txt"))); -} - -TEST_F(ChangeListProcessorTest, DeltaFileRenamedInDirectory) { - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - ResourceEntry entry; - entry.set_resource_id("subdirectory_file_1_id"); - entry.set_title("New SubDirectory File 1.txt"); - change_lists[0]->mutable_entries()->push_back(entry); - change_lists[0]->mutable_parent_resource_ids()->push_back( - "1_folder_resource_id"); - - change_lists[0]->set_new_start_page_token("16767"); - - // Apply the changelist and check the effect. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - - EXPECT_TRUE(changed_team_drives.empty()); - EXPECT_EQ(2U, changed_files.size()); - EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe( - "drive/root/Directory 1/SubDirectory File 1.txt"))); - EXPECT_TRUE(changed_files.count(base::FilePath::FromUTF8Unsafe( - "drive/root/Directory 1/New SubDirectory File 1.txt"))); - - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16767", start_page_token); - EXPECT_FALSE(GetResourceEntry( - "drive/root/Directory 1/SubDirectory File 1.txt")); - std::unique_ptr<ResourceEntry> new_entry( - GetResourceEntry("drive/root/Directory 1/New SubDirectory File 1.txt")); - ASSERT_TRUE(new_entry); - - // Keep the to-be-synced properties. - ASSERT_EQ(1, new_entry->mutable_new_properties()->size()); - const Property& new_property = new_entry->new_properties().Get(0); - EXPECT_EQ("hello", new_property.key()); -} - -TEST_F(ChangeListProcessorTest, DeltaAddAndDeleteFileInRoot) { - // Create ChangeList to add a file. - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - ResourceEntry entry; - entry.set_resource_id("added_in_root_id"); - entry.set_title("Added file.txt"); - change_lists[0]->mutable_entries()->push_back(entry); - change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); - - change_lists[0]->set_new_start_page_token("16683"); - - // Apply. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16683", start_page_token); - EXPECT_TRUE(GetResourceEntry("drive/root/Added file.txt")); - EXPECT_TRUE(changed_team_drives.empty()); - EXPECT_EQ(1U, changed_files.size()); - EXPECT_TRUE(changed_files.count( - base::FilePath::FromUTF8Unsafe("drive/root/Added file.txt"))); - - // Create ChangeList to delete the file. - change_lists.push_back(std::make_unique<ChangeList>()); - - entry.set_deleted(true); - change_lists[0]->mutable_entries()->push_back(entry); - change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); - - change_lists[0]->set_new_start_page_token("16687"); - - // Apply. - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16687", start_page_token); - EXPECT_FALSE(GetResourceEntry("drive/root/Added file.txt")); - EXPECT_TRUE(changed_team_drives.empty()); - EXPECT_EQ(1U, changed_files.size()); - EXPECT_TRUE(changed_files.count( - base::FilePath::FromUTF8Unsafe("drive/root/Added file.txt"))); -} - - -TEST_F(ChangeListProcessorTest, DeltaAddAndDeleteFileFromExistingDirectory) { - // Create ChangeList to add a file. - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - ResourceEntry entry; - entry.set_resource_id("added_in_root_id"); - entry.set_title("Added file.txt"); - change_lists[0]->mutable_entries()->push_back(entry); - change_lists[0]->mutable_parent_resource_ids()->push_back( - "1_folder_resource_id"); - - change_lists[0]->set_new_start_page_token("16730"); - - // Apply. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16730", start_page_token); - EXPECT_TRUE(GetResourceEntry("drive/root/Directory 1/Added file.txt")); - - EXPECT_TRUE(changed_team_drives.empty()); - EXPECT_EQ(1U, changed_files.size()); - EXPECT_TRUE(changed_files.count( - base::FilePath::FromUTF8Unsafe("drive/root/Directory 1/Added file.txt"))); - - // Create ChangeList to delete the file. - change_lists.push_back(std::make_unique<ChangeList>()); - - entry.set_deleted(true); - change_lists[0]->mutable_entries()->push_back(entry); - change_lists[0]->mutable_parent_resource_ids()->push_back( - "1_folder_resource_id"); - - change_lists[0]->set_new_start_page_token("16770"); - - // Apply. - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16770", start_page_token); - EXPECT_FALSE(GetResourceEntry("drive/root/Directory 1/Added file.txt")); - - EXPECT_TRUE(changed_team_drives.empty()); - EXPECT_EQ(1U, changed_files.size()); - EXPECT_TRUE(changed_files.count( - base::FilePath::FromUTF8Unsafe("drive/root/Directory 1/Added file.txt"))); -} - -TEST_F(ChangeListProcessorTest, DeltaAddFileToNewButDeletedDirectory) { - // Create a change which contains the following updates: - // 1) A new PDF file is added to a new directory - // 2) but the new directory is marked "deleted" (i.e. moved to Trash) - // Hence, the PDF file should be just ignored. - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - ResourceEntry file; - file.set_resource_id("file_added_in_deleted_id"); - file.set_title("new_pdf_file.pdf"); - file.set_deleted(true); - change_lists[0]->mutable_entries()->push_back(file); - change_lists[0]->mutable_parent_resource_ids()->push_back( - "new_folder_resource_id"); - - ResourceEntry directory; - directory.set_resource_id("new_folder_resource_id"); - directory.set_title("New Directory"); - directory.mutable_file_info()->set_is_directory(true); - directory.set_deleted(true); - change_lists[0]->mutable_entries()->push_back(directory); - change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); - - change_lists[0]->set_new_start_page_token("16730"); - - // Apply the changelist and check the effect. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16730", start_page_token); - EXPECT_FALSE(GetResourceEntry("drive/root/New Directory/new_pdf_file.pdf")); - - EXPECT_TRUE(changed_team_drives.empty()); - EXPECT_TRUE(changed_files.empty()); -} - -TEST_F(ChangeListProcessorTest, RefreshDirectory) { - // Prepare metadata. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - - // Create change list. - std::unique_ptr<ChangeList> change_list(new ChangeList); - - // Add a new file to the change list. - ResourceEntry new_file; - new_file.set_title("new_file"); - new_file.set_resource_id("new_file_id"); - change_list->mutable_entries()->push_back(new_file); - change_list->mutable_parent_resource_ids()->push_back(kRootId); - - // Add "Directory 1" to the map with a new name. - ResourceEntry dir1; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( - util::GetDriveMyDriveRootPath().AppendASCII("Directory 1"), &dir1)); - dir1.set_title(dir1.title() + " (renamed)"); - change_list->mutable_entries()->push_back(dir1); - change_list->mutable_parent_resource_ids()->push_back(kRootId); - - // Update the directory with the map. - ResourceEntry root; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( - util::GetDriveMyDriveRootPath(), &root)); - const std::string kNewStartpageToken = "12345"; - ResourceEntryVector refreshed_entries; - EXPECT_EQ(FILE_ERROR_OK, - ChangeListProcessor::RefreshDirectory( - metadata_.get(), - DirectoryFetchInfo(root.local_id(), kRootId, kNewStartpageToken, - util::GetDriveMyDriveRootPath(), - util::GetDriveMyDriveRootPath()), - std::move(change_list), &refreshed_entries)); - - // "new_file" should be added. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( - util::GetDriveMyDriveRootPath().AppendASCII(new_file.title()), &entry)); - - // "Directory 1" should be renamed. - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( - util::GetDriveMyDriveRootPath().AppendASCII(dir1.title()), &entry)); -} - -TEST_F(ChangeListProcessorTest, RefreshDirectory_WrongParentId) { - // Prepare metadata. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - - // Create change list and add a new file to it. - std::unique_ptr<ChangeList> change_list(new ChangeList); - ResourceEntry new_file; - new_file.set_title("new_file"); - new_file.set_resource_id("new_file_id"); - // This entry should not be added because the parent ID does not match. - change_list->mutable_parent_resource_ids()->push_back( - "some-random-resource-id"); - change_list->mutable_entries()->push_back(new_file); - - - // Update the directory. - ResourceEntry root; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( - util::GetDriveMyDriveRootPath(), &root)); - const std::string kNewStartpageToken = "12345"; - ResourceEntryVector refreshed_entries; - EXPECT_EQ(FILE_ERROR_OK, - ChangeListProcessor::RefreshDirectory( - metadata_.get(), - DirectoryFetchInfo(root.local_id(), kRootId, kNewStartpageToken, - util::GetDriveMyDriveRootPath(), - util::GetDriveMyDriveRootPath()), - std::move(change_list), &refreshed_entries)); - - // "new_file" should not be added. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_NOT_FOUND, metadata_->GetResourceEntryByPath( - util::GetDriveMyDriveRootPath().AppendASCII(new_file.title()), &entry)); -} - -TEST_F(ChangeListProcessorTest, SharedFilesWithNoParentInFeed) { - // Prepare metadata. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - - // Create change lists. - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - // Add a new file with non-existing parent resource id to the change lists. - ResourceEntry new_file; - new_file.set_title("new_file"); - new_file.set_resource_id("new_file_id"); - change_lists[0]->mutable_entries()->push_back(new_file); - change_lists[0]->mutable_parent_resource_ids()->push_back("nonexisting"); - change_lists[0]->set_new_start_page_token("123"); - - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - - // "new_file" should be added under drive/other. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( - util::GetDriveGrandRootPath().AppendASCII("other/new_file"), &entry)); -} - -TEST_F(ChangeListProcessorTest, ModificationDate) { - // Prepare metadata. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - - // Create change lists with a new file. - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - const base::Time now = base::Time::Now(); - ResourceEntry new_file_remote; - new_file_remote.set_title("new_file_remote"); - new_file_remote.set_resource_id("new_file_id"); - new_file_remote.set_modification_date(now.ToInternalValue()); - - change_lists[0]->mutable_entries()->push_back(new_file_remote); - change_lists[0]->mutable_parent_resource_ids()->push_back(kRootId); - change_lists[0]->set_new_start_page_token("123"); - - // Add the same file locally, but with a different name, a dirty metadata - // state, and a newer modification date. - ResourceEntry root; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath( - util::GetDriveMyDriveRootPath(), &root)); - - ResourceEntry new_file_local; - new_file_local.set_resource_id(new_file_remote.resource_id()); - new_file_local.set_parent_local_id(root.local_id()); - new_file_local.set_title("new_file_local"); - new_file_local.set_metadata_edit_state(ResourceEntry::DIRTY); - new_file_local.set_modification_date( - (now + base::TimeDelta::FromSeconds(1)).ToInternalValue()); - std::string local_id; - EXPECT_EQ(FILE_ERROR_OK, metadata_->AddEntry(new_file_local, &local_id)); - - // Apply the change. - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - - // The change is rejected due to the old modification date. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryById(local_id, &entry)); - EXPECT_EQ(new_file_local.title(), entry.title()); -} - -TEST_F(ChangeListProcessorTest, AddNewTeamDrive) { - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - ResourceEntry team_drive; - team_drive.set_resource_id("team_drive_resource_id"); - team_drive.set_title("New Team Drive"); - team_drive.mutable_file_info()->set_is_directory(true); - team_drive.mutable_file_info()->set_is_team_drive_root(true); - team_drive.set_parent_local_id(util::kDriveTeamDrivesDirLocalId); - change_lists[0]->mutable_entries()->push_back(team_drive); - change_lists[0]->mutable_parent_resource_ids()->push_back( - util::kDriveTeamDrivesDirLocalId); - - change_lists[0]->set_new_start_page_token("16730"); - - // Apply the changelist and check the effect. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16730", start_page_token); - - constexpr char kExpectedPath[] = "drive/team_drives/New Team Drive"; - EXPECT_TRUE(GetResourceEntry(kExpectedPath)); - - // A new team drive will be in both changed_files and changed_team_drives. - EXPECT_EQ(1U, changed_files.size()); - EXPECT_TRUE( - changed_files.count(base::FilePath::FromUTF8Unsafe(kExpectedPath))); - - EXPECT_EQ(1U, changed_team_drives.size()); - EXPECT_TRUE( - changed_team_drives.count(base::FilePath::FromUTF8Unsafe(kExpectedPath))); -} - -TEST_F(ChangeListProcessorTest, AddAndDeleteTeamDrive) { - // Create ChangeList to add a file. - std::vector<std::unique_ptr<ChangeList>> change_lists; - change_lists.push_back(std::make_unique<ChangeList>()); - - ResourceEntry team_drive; - team_drive.set_resource_id("team_drive_resource_id"); - team_drive.set_title("New Team Drive"); - team_drive.mutable_file_info()->set_is_directory(true); - team_drive.mutable_file_info()->set_is_team_drive_root(true); - team_drive.set_parent_local_id(util::kDriveTeamDrivesDirLocalId); - change_lists[0]->mutable_entries()->push_back(team_drive); - change_lists[0]->mutable_parent_resource_ids()->push_back( - util::kDriveTeamDrivesDirLocalId); - - change_lists[0]->set_new_start_page_token("16683"); - - // Apply. - EXPECT_EQ(FILE_ERROR_OK, ApplyFullResourceList(CreateBaseChangeList())); - FileChange changed_files; - FileChange changed_team_drives; - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16683", start_page_token); - constexpr char kExpectedPath[] = "drive/team_drives/New Team Drive"; - - EXPECT_TRUE(GetResourceEntry(kExpectedPath)); - EXPECT_EQ(1U, changed_files.size()); - EXPECT_TRUE( - changed_files.count(base::FilePath::FromUTF8Unsafe(kExpectedPath))); - EXPECT_EQ(1U, changed_team_drives.size()); - EXPECT_TRUE( - changed_team_drives.count(base::FilePath::FromUTF8Unsafe(kExpectedPath))); - - // Create ChangeList to delete the file. - change_lists.push_back(std::make_unique<ChangeList>()); - - team_drive.set_deleted(true); - change_lists[0]->mutable_entries()->push_back(team_drive); - change_lists[0]->mutable_parent_resource_ids()->push_back( - util::kDriveTeamDrivesDirLocalId); - - change_lists[0]->set_new_start_page_token("16687"); - - // Apply. - EXPECT_EQ(FILE_ERROR_OK, - ApplyUserChangeList(std::move(change_lists), &changed_files, - &changed_team_drives)); - EXPECT_EQ(FILE_ERROR_OK, metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ("16687", start_page_token); - EXPECT_FALSE(GetResourceEntry(kExpectedPath)); - EXPECT_EQ(1U, changed_files.size()); - EXPECT_TRUE( - changed_files.count(base::FilePath::FromUTF8Unsafe(kExpectedPath))); - EXPECT_EQ(1U, changed_team_drives.size()); - EXPECT_TRUE( - changed_team_drives.count(base::FilePath::FromUTF8Unsafe(kExpectedPath))); -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/chromeos/change_list_processor.cc b/components/drive/chromeos/change_list_processor.cc deleted file mode 100644 index 42fbcbf..0000000 --- a/components/drive/chromeos/change_list_processor.cc +++ /dev/null
@@ -1,561 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/chromeos/change_list_processor.h" - -#include <stddef.h> - -#include <memory> -#include <utility> -#include <vector> - -#include "base/metrics/histogram_macros.h" -#include "base/strings/string_number_conversions.h" -#include "base/synchronization/atomic_flag.h" -#include "components/drive/chromeos/drive_file_util.h" -#include "components/drive/chromeos/resource_metadata.h" -#include "components/drive/drive.pb.h" -#include "components/drive/drive_api_util.h" -#include "components/drive/file_change.h" -#include "components/drive/file_system_core_util.h" -#include "components/drive/resource_entry_conversion.h" -#include "google_apis/drive/drive_api_parser.h" - -namespace drive { -namespace internal { - -namespace { - -// Returns true if it's OK to overwrite the local entry with the remote one. -bool ShouldApplyChange(const ResourceEntry& local_entry, - const ResourceEntry& remote_entry) { - if (local_entry.metadata_edit_state() == ResourceEntry::CLEAN) - return true; - return base::Time::FromInternalValue(remote_entry.modification_date()) > - base::Time::FromInternalValue(local_entry.modification_date()); -} - -} // namespace - -DirectoryFetchInfo::DirectoryFetchInfo() = default; - -DirectoryFetchInfo::~DirectoryFetchInfo() = default; - -DirectoryFetchInfo::DirectoryFetchInfo(const std::string& local_id, - const std::string& resource_id, - const std::string& start_page_token, - const base::FilePath& root_entry_path, - const base::FilePath& directory_path) - : local_id_(local_id), - resource_id_(resource_id), - start_page_token_(start_page_token), - root_entry_path_(root_entry_path), - directory_path_(directory_path) {} - -DirectoryFetchInfo::DirectoryFetchInfo(const DirectoryFetchInfo& other) = - default; - -std::string DirectoryFetchInfo::ToString() const { - return ("local_id: " + local_id_ + ", resource_id: " + resource_id_ + - ", start_page_token: " + start_page_token_ + - ", root_entry_path: " + root_entry_path_.value() + - ", directory_path: " + directory_path_.value()); -} - -ChangeList::ChangeList() = default; - -ChangeList::ChangeList(const google_apis::TeamDriveList& team_drive_list) { - const std::vector<std::unique_ptr<google_apis::TeamDriveResource>>& items = - team_drive_list.items(); - entries_.resize(items.size()); - parent_resource_ids_.resize(items.size(), ""); - for (size_t i = 0; i < items.size(); ++i) { - ConvertTeamDriveResourceToResourceEntry(*items[i], &entries_[i]); - } -} - -ChangeList::ChangeList(const google_apis::ChangeList& change_list) - : next_url_(change_list.next_link()), - new_start_page_token_(change_list.new_start_page_token()) { - const std::vector<std::unique_ptr<google_apis::ChangeResource>>& items = - change_list.items(); - entries_.resize(items.size()); - parent_resource_ids_.resize(items.size()); - for (size_t i = 0; i < items.size(); ++i) { - ConvertChangeResourceToResourceEntry(*items[i], &entries_[i], - &parent_resource_ids_[i]); - } -} - -ChangeList::ChangeList(const google_apis::FileList& file_list) - : next_url_(file_list.next_link()) { - const std::vector<std::unique_ptr<google_apis::FileResource>>& items = - file_list.items(); - entries_.resize(items.size()); - parent_resource_ids_.resize(items.size()); - for (size_t i = 0; i < items.size(); ++i) { - ConvertFileResourceToResourceEntry(*items[i], &entries_[i], - &parent_resource_ids_[i]); - } -} - -ChangeList::~ChangeList() = default; - -class ChangeListProcessor::ChangeListToEntryMapUMAStats { - public: - ChangeListToEntryMapUMAStats() - : num_regular_files_(0), num_hosted_documents_(0) {} - - // Increments number of files. - void IncrementNumFiles(bool is_hosted_document) { - is_hosted_document ? num_hosted_documents_++ : num_regular_files_++; - } - - // Updates UMA histograms with file counts. - void UpdateFileCountUmaHistograms() { - const int num_total_files = num_hosted_documents_ + num_regular_files_; - UMA_HISTOGRAM_COUNTS_1M("Drive.NumberOfRegularFiles", num_regular_files_); - UMA_HISTOGRAM_COUNTS_1M("Drive.NumberOfHostedDocuments", - num_hosted_documents_); - UMA_HISTOGRAM_COUNTS_1M("Drive.NumberOfTotalFiles", num_total_files); - } - - private: - int num_regular_files_; - int num_hosted_documents_; -}; - -ChangeListProcessor::ChangeListProcessor(const std::string& team_drive_id, - const base::FilePath& root_entry_path, - ResourceMetadata* resource_metadata, - base::AtomicFlag* in_shutdown) - : resource_metadata_(resource_metadata), - in_shutdown_(in_shutdown), - changed_files_(new FileChange), - changed_team_drives_(new FileChange), - team_drive_id_(team_drive_id), - root_entry_path_(root_entry_path) {} - -ChangeListProcessor::~ChangeListProcessor() = default; - -FileError ChangeListProcessor::ApplyUserChangeList( - const std::string& start_page_token, - const std::string& root_resource_id, - std::vector<std::unique_ptr<ChangeList>> change_lists, - bool is_delta_update) { - std::string new_start_page_token = start_page_token; - if (is_delta_update) { - if (!change_lists.empty()) { - // The start_page_token appears in the first page of the change list. - // The start_page_token does not appear in the full resource list. - new_start_page_token = change_lists[0]->new_start_page_token(); - DCHECK(!new_start_page_token.empty()); - } - } - - // Update the resource ID of the entry, if required. - - // Multiple team drives can have the same root_entry_path_, so try looking up - // via the team_drive_id first. - ResourceEntry root; - FileError error = FILE_ERROR_OK; - if (!team_drive_id_.empty()) { - std::string local_id; - error = resource_metadata_->GetIdByResourceId(team_drive_id_, &local_id); - if (error != FILE_ERROR_OK) { - LOG(ERROR) << "Failed to get team drive local id: " - << FileErrorToString(error); - return error; - } - error = resource_metadata_->GetResourceEntryById(local_id, &root); - if (error != FILE_ERROR_OK) { - LOG(ERROR) << "Failed to get team drive root entry: " - << FileErrorToString(error); - return error; - } - } else { - error = resource_metadata_->GetResourceEntryByPath(root_entry_path_, &root); - if (error != FILE_ERROR_OK) { - LOG(ERROR) << "Failed to get root entry: " << FileErrorToString(error); - return error; - } - } - // Only update if the root resource id has changed. This will happen for the - // default corpus on the first load, as we obtain the resource id lazily. - if (root_resource_id != root.resource_id()) { - root.set_resource_id(root_resource_id); - error = resource_metadata_->RefreshEntry(root); - if (error != FILE_ERROR_OK) { - LOG(ERROR) << "Failed to update root entry: " << FileErrorToString(error); - return error; - } - } - - ChangeListToEntryMapUMAStats uma_stats; - error = ApplyChangeListInternal(std::move(change_lists), new_start_page_token, - &root, &uma_stats); - if (error != FILE_ERROR_OK) - return error; - - // Update start_page_token in the metadata header. - error = SetStartPageToken(resource_metadata_, team_drive_id_, - new_start_page_token); - if (error != FILE_ERROR_OK) { - DLOG(ERROR) << "SetStartPageToken failed: " << FileErrorToString(error); - return error; - } - - // Shouldn't record histograms when processing delta update. - if (!is_delta_update) - uma_stats.UpdateFileCountUmaHistograms(); - - return FILE_ERROR_OK; -} - -FileError ChangeListProcessor::ApplyChangeListInternal( - std::vector<std::unique_ptr<ChangeList>> change_lists, - const std::string& start_page_token, - ResourceEntry* root, - ChangeListToEntryMapUMAStats* uma_stats) { - ConvertChangeListsToMap(std::move(change_lists), start_page_token, uma_stats); - FileError error = ApplyEntryMap(root->resource_id()); - if (error != FILE_ERROR_OK) { - DLOG(ERROR) << "ApplyEntryMap failed: " << FileErrorToString(error); - return error; - } - // Update start_page_token of the root entry. - root->mutable_directory_specific_info()->set_start_page_token( - start_page_token); - error = resource_metadata_->RefreshEntry(*root); - if (error != FILE_ERROR_OK) - DLOG(ERROR) << "RefreshEntry failed: " << FileErrorToString(error); - return error; -} - -void ChangeListProcessor::ConvertChangeListsToMap( - std::vector<std::unique_ptr<ChangeList>> change_lists, - const std::string& start_page_token, - ChangeListToEntryMapUMAStats* uma_stats) { - for (size_t i = 0; i < change_lists.size(); ++i) { - ChangeList* change_list = change_lists[i].get(); - - std::vector<ResourceEntry>* entries = change_list->mutable_entries(); - for (size_t i = 0; i < entries->size(); ++i) { - ResourceEntry* entry = &(*entries)[i]; - - // Count the number of files. - if (!entry->file_info().is_directory()) { - uma_stats->IncrementNumFiles( - entry->file_specific_info().is_hosted_document()); - } - parent_resource_id_map_[entry->resource_id()] = - change_list->parent_resource_ids()[i]; - entry_map_[entry->resource_id()].Swap(entry); - LOG_IF(WARNING, !entry->resource_id().empty()) - << "Found duplicated file: " << entry->base_name(); - } - } - - // Add the largest start_page_token for directories. - for (ResourceEntryMap::iterator it = entry_map_.begin(); - it != entry_map_.end(); ++it) { - if (it->second.file_info().is_directory()) { - it->second.mutable_directory_specific_info()->set_start_page_token( - start_page_token); - } - } -} - -FileError ChangeListProcessor::ApplyEntryMap( - const std::string& root_resource_id) { - // Gather the set of changes in the old path. - // Note that we want to notify the change in both old and new paths (suppose - // /a/b/c is moved to /x/y/c. We want to notify both "/a/b" and "/x/y".) - // The old paths must be calculated before we apply any actual changes. - // The new paths are calculated after each change is applied. It correctly - // sets the new path because we apply changes in such an order (see below). - for (ResourceEntryMap::iterator it = entry_map_.begin(); - it != entry_map_.end(); ++it) { - UpdateChangedDirs(it->second); - } - - // Apply all entries except deleted ones to the metadata. - std::vector<std::string> deleted_resource_ids; - while (!entry_map_.empty()) { - if (in_shutdown_ && in_shutdown_->IsSet()) - return FILE_ERROR_ABORT; - - ResourceEntryMap::iterator it = entry_map_.begin(); - - // Process deleted entries later to avoid deleting moved entries under it. - if (it->second.deleted()) { - deleted_resource_ids.push_back(it->first); - entry_map_.erase(it); - continue; - } - - // Start from entry_map_.begin() and traverse ancestors using the - // parent-child relationships in the result (after this apply) tree. - // Then apply the topmost change first. - // - // By doing this, assuming the result tree does not contain any cycles, we - // can guarantee that no cycle is made during this apply (i.e. no entry gets - // moved under any of its descendants) because the following conditions are - // always satisfied in any move: - // - The new parent entry is not a descendant of the moved entry. - // - The new parent and its ancestors will no longer move during this apply. - std::vector<ResourceEntryMap::iterator> entries; - for (ResourceEntryMap::iterator it = entry_map_.begin(); - it != entry_map_.end();) { - entries.push_back(it); - - DCHECK(parent_resource_id_map_.count(it->first)) << it->first; - const std::string& parent_resource_id = - parent_resource_id_map_[it->first]; - - if (parent_resource_id.empty()) // This entry has no parent. - break; - - ResourceEntryMap::iterator it_parent = - entry_map_.find(parent_resource_id); - if (it_parent == entry_map_.end()) { - // Current entry's parent is already updated or not going to be updated, - // get the parent from the local tree. - std::string parent_local_id; - FileError error = resource_metadata_->GetIdByResourceId( - parent_resource_id, &parent_local_id); - if (error != FILE_ERROR_OK) { - // See crbug.com/326043. In some complicated situations, parent folder - // for shared entries may be accessible (and hence its resource id is - // included), but not in the change/file list. - // In such a case, clear the parent and move it to drive/other. - if (error == FILE_ERROR_NOT_FOUND) { - parent_resource_id_map_[it->first] = ""; - } else { - LOG(ERROR) << "Failed to get local ID: " << parent_resource_id - << ", error = " << FileErrorToString(error); - } - break; - } - ResourceEntry parent_entry; - while (it_parent == entry_map_.end() && !parent_local_id.empty()) { - error = resource_metadata_->GetResourceEntryById( - parent_local_id, &parent_entry); - if (error != FILE_ERROR_OK) { - LOG(ERROR) << "Failed to get local entry: " - << FileErrorToString(error); - break; - } - it_parent = entry_map_.find(parent_entry.resource_id()); - parent_local_id = parent_entry.parent_local_id(); - } - } - it = it_parent; - } - - // Apply the parent first. - std::reverse(entries.begin(), entries.end()); - for (size_t i = 0; i < entries.size(); ++i) { - // Skip root entry in the change list. We don't expect servers to send - // root entry, but we should better be defensive (see crbug.com/297259). - ResourceEntryMap::iterator it = entries[i]; - if (it->first != root_resource_id) { - FileError error = ApplyEntry(it->second); - if (error != FILE_ERROR_OK) { - LOG(ERROR) << "ApplyEntry failed: " << FileErrorToString(error) - << ", title = " << it->second.title(); - return error; - } - } - entry_map_.erase(it); - } - } - - // Apply deleted entries. - for (size_t i = 0; i < deleted_resource_ids.size(); ++i) { - std::string local_id; - FileError error = resource_metadata_->GetIdByResourceId( - deleted_resource_ids[i], &local_id); - switch (error) { - case FILE_ERROR_OK: - error = resource_metadata_->RemoveEntry(local_id); - break; - case FILE_ERROR_NOT_FOUND: - error = FILE_ERROR_OK; - break; - default: - break; - } - if (error != FILE_ERROR_OK) { - LOG(ERROR) << "Failed to delete: " << FileErrorToString(error) - << ", resource_id = " << deleted_resource_ids[i]; - return error; - } - } - - return FILE_ERROR_OK; -} - -FileError ChangeListProcessor::ApplyEntry(const ResourceEntry& entry) { - DCHECK(!entry.deleted()); - DCHECK(!entry.resource_id().empty()); - DCHECK(parent_resource_id_map_.count(entry.resource_id())); - const std::string& parent_resource_id = - parent_resource_id_map_[entry.resource_id()]; - - ResourceEntry new_entry(entry); - FileError error = SetParentLocalIdOfEntry(resource_metadata_, &new_entry, - parent_resource_id); - if (error != FILE_ERROR_OK) - return error; - - // Lookup the entry. - std::string local_id; - error = resource_metadata_->GetIdByResourceId(entry.resource_id(), &local_id); - - ResourceEntry existing_entry; - if (error == FILE_ERROR_OK) - error = resource_metadata_->GetResourceEntryById(local_id, &existing_entry); - - switch (error) { - case FILE_ERROR_OK: - if (ShouldApplyChange(existing_entry, new_entry)) { - // Entry exists and needs to be refreshed. - new_entry.set_local_id(local_id); - // Keep the to-be-synced properties of the existing resource entry. - new_entry.mutable_new_properties()->CopyFrom( - existing_entry.new_properties()); - error = resource_metadata_->RefreshEntry(new_entry); - } else { - if (entry.file_info().is_directory()) { - // No need to refresh, but update the start_page_token. - new_entry = existing_entry; - new_entry.mutable_directory_specific_info()->set_start_page_token( - new_entry.directory_specific_info().start_page_token()); - error = resource_metadata_->RefreshEntry(new_entry); - } - DVLOG(1) << "Change was discarded for: " << entry.resource_id(); - } - break; - case FILE_ERROR_NOT_FOUND: { // Adding a new entry. - std::string local_id; - error = resource_metadata_->AddEntry(new_entry, &local_id); - break; - } - default: - return error; - } - if (error != FILE_ERROR_OK) - return error; - - UpdateChangedDirs(entry); - return FILE_ERROR_OK; -} - -// static -FileError ChangeListProcessor::RefreshDirectory( - ResourceMetadata* resource_metadata, - const DirectoryFetchInfo& directory_fetch_info, - std::unique_ptr<ChangeList> change_list, - std::vector<ResourceEntry>* out_refreshed_entries) { - DCHECK(!directory_fetch_info.empty()); - - ResourceEntry directory; - FileError error = resource_metadata->GetResourceEntryById( - directory_fetch_info.local_id(), &directory); - if (error != FILE_ERROR_OK) - return error; - - if (!directory.file_info().is_directory()) - return FILE_ERROR_NOT_A_DIRECTORY; - - std::vector<ResourceEntry>* entries = change_list->mutable_entries(); - for (size_t i = 0; i < entries->size(); ++i) { - ResourceEntry* entry = &(*entries)[i]; - const std::string& parent_resource_id = - change_list->parent_resource_ids()[i]; - - // Skip if the parent resource ID does not match. This is needed to - // handle entries with multiple parents. For such entries, the first - // parent is picked and other parents are ignored, hence some entries may - // have a parent resource ID which does not match the target directory's. - if (parent_resource_id != directory_fetch_info.resource_id()) { - DVLOG(1) << "Wrong-parent entry rejected: " << entry->resource_id(); - continue; - } - - entry->set_parent_local_id(directory_fetch_info.local_id()); - - std::string local_id; - error = resource_metadata->GetIdByResourceId(entry->resource_id(), - &local_id); - if (error == FILE_ERROR_OK) { - entry->set_local_id(local_id); - error = resource_metadata->RefreshEntry(*entry); - } - - if (error == FILE_ERROR_NOT_FOUND) { // If refreshing fails, try adding. - entry->clear_local_id(); - error = resource_metadata->AddEntry(*entry, &local_id); - } - - if (error != FILE_ERROR_OK) - return error; - - ResourceEntry result_entry; - error = resource_metadata->GetResourceEntryById(local_id, &result_entry); - if (error != FILE_ERROR_OK) - return error; - out_refreshed_entries->push_back(result_entry); - } - return FILE_ERROR_OK; -} - -// static -FileError ChangeListProcessor::SetParentLocalIdOfEntry( - ResourceMetadata* resource_metadata, - ResourceEntry* entry, - const std::string& parent_resource_id) { - if (entry->parent_local_id() == util::kDriveTeamDrivesDirLocalId) { - // When |entry| is a root directory of a Team Drive, the parent directory - // of it is "/team_drives", which doesn't have resource ID. - return FILE_ERROR_OK; - } - std::string parent_local_id; - if (parent_resource_id.empty()) { - // Entries without parents should go under "other" directory. - parent_local_id = util::kDriveOtherDirLocalId; - } else { - FileError error = resource_metadata->GetIdByResourceId( - parent_resource_id, &parent_local_id); - if (error != FILE_ERROR_OK) - return error; - } - entry->set_parent_local_id(parent_local_id); - return FILE_ERROR_OK; -} - -void ChangeListProcessor::UpdateChangedDirs(const ResourceEntry& entry) { - DCHECK(!entry.resource_id().empty()); - - std::string local_id; - base::FilePath file_path; - if (resource_metadata_->GetIdByResourceId( - entry.resource_id(), &local_id) == FILE_ERROR_OK) - resource_metadata_->GetFilePath(local_id, &file_path); - - if (!file_path.empty()) { - FileChange::ChangeType type = entry.deleted() - ? FileChange::CHANGE_TYPE_DELETE - : FileChange::CHANGE_TYPE_ADD_OR_UPDATE; - changed_files_->Update(file_path, entry, type); - - if (entry.file_info().is_team_drive_root()) { - changed_team_drives_->Update(file_path, entry, type); - } - } -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/chromeos/change_list_processor.h b/components/drive/chromeos/change_list_processor.h deleted file mode 100644 index 133315b..0000000 --- a/components/drive/chromeos/change_list_processor.h +++ /dev/null
@@ -1,221 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_CHROMEOS_CHANGE_LIST_PROCESSOR_H_ -#define COMPONENTS_DRIVE_CHROMEOS_CHANGE_LIST_PROCESSOR_H_ - -#include <stdint.h> - -#include <map> -#include <memory> -#include <set> -#include <string> -#include <vector> - -#include "base/files/file_path.h" -#include "base/macros.h" -#include "components/drive/file_errors.h" -#include "url/gurl.h" - -namespace base { -class AtomicFlag; -} // namespace base - -namespace google_apis { -class ChangeList; -class FileList; -class TeamDriveList; -} // namespace google_apis - -namespace drive { - -class FileChange; -class ResourceEntry; - -namespace internal { - -class ResourceMetadata; - -// Holds information needed to fetch contents of a directory. -// This object is copyable. -class DirectoryFetchInfo { - public: - DirectoryFetchInfo(); - ~DirectoryFetchInfo(); - - DirectoryFetchInfo(const std::string& local_id, - const std::string& resource_id, - const std::string& start_page_token, - const base::FilePath& root_entry_path, - const base::FilePath& directory_path); - - DirectoryFetchInfo(const DirectoryFetchInfo& other); - - // Returns true if the object is empty. - bool empty() const { return local_id_.empty(); } - - // Local ID of the directory. - const std::string& local_id() const { return local_id_; } - - // Resource ID of the directory. - const std::string& resource_id() const { return resource_id_; } - - // Start Page Token of the directory. The start page token is used to - // determine if the directory contents should be fetched. - const std::string& start_page_token() const { return start_page_token_; } - - // The root path of the directory being fetched. - const base::FilePath& root_entry_path() const { return root_entry_path_; } - - // The directory path that we are fetching. Used for logging. - const base::FilePath& directory_path() const { return directory_path_; } - - // Returns a string representation of this object. - std::string ToString() const; - - private: - const std::string local_id_; - const std::string resource_id_; - const std::string start_page_token_; - const base::FilePath root_entry_path_; - const base::FilePath directory_path_; -}; - -// Class to represent a change list. -class ChangeList { - public: - ChangeList(); // For tests. - explicit ChangeList(const google_apis::ChangeList& change_list); - explicit ChangeList(const google_apis::FileList& file_list); - explicit ChangeList(const google_apis::TeamDriveList& team_drive_list); - ~ChangeList(); - - const std::vector<ResourceEntry>& entries() const { return entries_; } - std::vector<ResourceEntry>* mutable_entries() { return &entries_; } - const std::vector<std::string>& parent_resource_ids() const { - return parent_resource_ids_; - } - std::vector<std::string>* mutable_parent_resource_ids() { - return &parent_resource_ids_; - } - const GURL& next_url() const { return next_url_; } - - const std::string& new_start_page_token() const { - return new_start_page_token_; - } - - void set_new_start_page_token(const std::string& start_page_token) { - new_start_page_token_ = start_page_token; - } - - private: - std::vector<ResourceEntry> entries_; - std::vector<std::string> parent_resource_ids_; - GURL next_url_; - std::string new_start_page_token_; - - DISALLOW_COPY_AND_ASSIGN(ChangeList); -}; - -// ChangeListProcessor is used to process change lists, or full resource -// lists from WAPI (codename for Documents List API) or Google Drive API, and -// updates the resource metadata stored locally. -class ChangeListProcessor { - public: - ChangeListProcessor(const std::string& team_drive_id, - const base::FilePath& root_entry_path, - ResourceMetadata* resource_metadata, - base::AtomicFlag* in_shutdown); - ~ChangeListProcessor(); - - // Applies user's change lists or full resource lists to - // |resource_metadata_|. - // - // |is_delta_update| determines the type of input data to process, whether - // it is full resource lists (false) or change lists (true). - // - // Must be run on the same task runner as |resource_metadata_| uses. - // |start_page_token| is the start page token used to retrieve the change - // list. - // |root_resource_id| is the resource id to lookup the root folder of the - // changeslists in resource metadata. - FileError ApplyUserChangeList( - const std::string& start_page_token, - const std::string& root_resource_id, - std::vector<std::unique_ptr<ChangeList>> change_lists, - bool is_delta_update); - - // The set of changed files as a result of change list processing. - const FileChange& changed_files() const { return *changed_files_; } - - // The set of team drives changes as a result of change list processing. - // Note that a team drive change will appear in both changed_files() and - // changed_team_drives() - const FileChange& changed_team_drives() const { - return *changed_team_drives_; - } - - // Adds or refreshes the child entries from |change_list| to the directory. - static FileError RefreshDirectory( - ResourceMetadata* resource_metadata, - const DirectoryFetchInfo& directory_fetch_info, - std::unique_ptr<ChangeList> change_list, - std::vector<ResourceEntry>* out_refreshed_entries); - - // Sets |entry|'s parent_local_id. - static FileError SetParentLocalIdOfEntry( - ResourceMetadata* resource_metadata, - ResourceEntry* entry, - const std::string& parent_resource_id); - - private: - class ChangeListToEntryMapUMAStats; - - typedef std::map<std::string /* resource_id */, ResourceEntry> - ResourceEntryMap; - typedef std::map<std::string /* resource_id */, - std::string /* parent_resource_id*/> ParentResourceIdMap; - - // Common logic between ApplyTeamDriveChangeList and ApplyUserChangeList. - // Applies the |change_lists| to |resource_metadta_|. - FileError ApplyChangeListInternal( - std::vector<std::unique_ptr<ChangeList>> change_lists, - const std::string& start_page_token, - ResourceEntry* root, - ChangeListToEntryMapUMAStats* uma_stats); - - // Converts the |change_lists| to |entry_map_| and |parent_resource_id_map_|, - // to be applied by ApplyEntryMap() later. - void ConvertChangeListsToMap( - std::vector<std::unique_ptr<ChangeList>> change_lists, - const std::string& start_page_token, - ChangeListToEntryMapUMAStats* uma_stats); - - // Applies the pre-processed metadata from entry_map_ onto the resource - // metadata. - FileError ApplyEntryMap(const std::string& root_resource_id); - - // Apply |entry| to resource_metadata_. - FileError ApplyEntry(const ResourceEntry& entry); - - // Adds the directories changed by the update on |entry| to |changed_dirs_|. - void UpdateChangedDirs(const ResourceEntry& entry); - - ResourceMetadata* resource_metadata_; // Not owned. - base::AtomicFlag* in_shutdown_; // Not owned. - - ResourceEntryMap entry_map_; - ParentResourceIdMap parent_resource_id_map_; - std::unique_ptr<FileChange> changed_files_; - std::unique_ptr<FileChange> changed_team_drives_; - const std::string team_drive_id_; - const base::FilePath& root_entry_path_; - - DISALLOW_COPY_AND_ASSIGN(ChangeListProcessor); -}; - -} // namespace internal -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_CHANGE_LIST_PROCESSOR_H_
diff --git a/components/drive/chromeos/drive_file_util.cc b/components/drive/chromeos/drive_file_util.cc deleted file mode 100644 index 96e1bb7..0000000 --- a/components/drive/chromeos/drive_file_util.cc +++ /dev/null
@@ -1,78 +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 "components/drive/chromeos/drive_file_util.h" - -#include <string> - -#include "components/drive/chromeos/resource_metadata.h" -#include "components/drive/drive.pb.h" -#include "components/drive/file_system_core_util.h" - -namespace drive { -namespace internal { - -FileError GetStartPageToken(internal::ResourceMetadata* resource_metadata, - const std::string& team_drive_id, - std::string* out_value) { - DCHECK(resource_metadata); - DCHECK(out_value); - - if (team_drive_id == util::kTeamDriveIdDefaultCorpus) { - return resource_metadata->GetStartPageToken(out_value); - } - - std::string local_id; - FileError error = - resource_metadata->GetIdByResourceId(team_drive_id, &local_id); - if (error != FILE_ERROR_OK) { - DLOG(ERROR) << "Failed to get team drive local id."; - return error; - } - - ResourceEntry entry; - error = resource_metadata->GetResourceEntryById(local_id, &entry); - if (error != FILE_ERROR_OK) { - DLOG(ERROR) << "Filed to get the team drive resource."; - return error; - } - - DCHECK(entry.file_info().is_directory()); - DCHECK_EQ(entry.parent_local_id(), util::kDriveTeamDrivesDirLocalId); - out_value->assign(entry.team_drive_root_specific_info().start_page_token()); - return FILE_ERROR_OK; -} - -FileError SetStartPageToken(internal::ResourceMetadata* resource_metadata, - const std::string& team_drive_id, - const std::string& value) { - DCHECK(resource_metadata); - - if (team_drive_id == util::kTeamDriveIdDefaultCorpus) { - return resource_metadata->SetStartPageToken(value); - } - - std::string local_id; - FileError error = - resource_metadata->GetIdByResourceId(team_drive_id, &local_id); - if (error != FILE_ERROR_OK) { - DLOG(ERROR) << "Failed to get team drive local id."; - return error; - } - - ResourceEntry entry; - error = resource_metadata->GetResourceEntryById(local_id, &entry); - if (error != FILE_ERROR_OK) { - DLOG(ERROR) << "Failed to get the team drive resource."; - return error; - } - - DCHECK(entry.file_info().is_directory()); - DCHECK_EQ(entry.parent_local_id(), util::kDriveTeamDrivesDirLocalId); - entry.mutable_team_drive_root_specific_info()->set_start_page_token(value); - return resource_metadata->RefreshEntry(entry); -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/chromeos/drive_file_util.h b/components/drive/chromeos/drive_file_util.h deleted file mode 100644 index e7986ab..0000000 --- a/components/drive/chromeos/drive_file_util.h +++ /dev/null
@@ -1,34 +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 COMPONENTS_DRIVE_CHROMEOS_DRIVE_FILE_UTIL_H_ -#define COMPONENTS_DRIVE_CHROMEOS_DRIVE_FILE_UTIL_H_ - -#include <string> - -#include "components/drive/file_errors.h" - -namespace drive { -namespace internal { - -class ResourceMetadata; - -// Obtains the start page token for the supplied |team_drive_id|. If the -// |team_drive_id| equals kTeamDriveIdDefaultCorpus then it will retrieve -// the start page token just for the users default corpus. -FileError GetStartPageToken(internal::ResourceMetadata* resource_metadata, - const std::string& team_drive_id, - std::string* out_value); - -// Sets the start page token for the supplied |team_drive_id|. If the -// |team_drive_id| equals kTeamDriveIdDefaultCorpus then it will set -// the start page token just for the users default corpus. -FileError SetStartPageToken(internal::ResourceMetadata* resource_metadata, - const std::string& team_drive_id, - const std::string& value); - -} // namespace internal -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_DRIVE_FILE_UTIL_H_
diff --git a/components/drive/chromeos/drive_operation_queue.h b/components/drive/chromeos/drive_operation_queue.h deleted file mode 100644 index 43d807c..0000000 --- a/components/drive/chromeos/drive_operation_queue.h +++ /dev/null
@@ -1,178 +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 COMPONENTS_DRIVE_CHROMEOS_DRIVE_OPERATION_QUEUE_H_ -#define COMPONENTS_DRIVE_CHROMEOS_DRIVE_OPERATION_QUEUE_H_ - -#include <utility> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/containers/queue.h" -#include "base/memory/weak_ptr.h" -#include "base/sequence_checker.h" -#include "base/threading/sequenced_task_runner_handle.h" -#include "base/time/default_tick_clock.h" -#include "base/time/tick_clock.h" -#include "base/time/time.h" -#include "base/timer/timer.h" -#include "components/drive/file_errors.h" - -namespace drive { -namespace internal { - -// A rate limited queue for making calls to the drive backend. This is a basic -// token based queue that will loosely rate limit requests to the qps specified -// on construction. When enquing operations to an empty queue, the queue will -// operate in burst mode and rapidly schedule up to |desired_qps| operations. -template <typename T> -class DriveBackgroundOperationQueue { - public: - // |tick_clock| can be injected for testing. - explicit DriveBackgroundOperationQueue( - int desired_qps, - const base::TickClock* tick_clock = base::DefaultTickClock::GetInstance()) - : tick_clock_(tick_clock), - token_count_(desired_qps), - per_token_time_delta_( - base::TimeDelta::FromMilliseconds(1000 / desired_qps)), - desired_qps_(desired_qps) {} - - ~DriveBackgroundOperationQueue() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - } - - // Add a new operation to the queue. When the operation is scheduled to be - // executed start_callback will be called. When the operation completes - // finish_callback will be with the result. - void AddOperation( - base::WeakPtr<T> target, - base::OnceCallback<void(const FileOperationCallback&)> start_callback, - FileOperationCallback finish_callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(start_callback); - DCHECK(finish_callback); - - drive_operation_queue_.emplace(std::move(target), std::move(start_callback), - std::move(finish_callback)); - - CheckAndMaybeStartTokenRefillTimer(); - CheckAndMaybeStartDriveOperation(); - } - - // Effectively disables the rate limiting for test purposes. - void DisableQueueForTesting() { - desired_qps_ = INT_MAX; - token_count_ = INT_MAX; - } - - private: - struct DriveOperation; - - using OperationQueue = base::queue<DriveOperation>; - using StartOperationCallback = - base::OnceCallback<void(const FileOperationCallback&)>; - using EndOperationCallback = FileOperationCallback; - - struct DriveOperation { - DriveOperation(base::WeakPtr<T> target, - StartOperationCallback start_callback, - EndOperationCallback finish) - : target(std::move(target)), - start_callback(std::move(start_callback)), - finish_callback(std::move(finish)) {} - - base::WeakPtr<T> target; - StartOperationCallback start_callback; - EndOperationCallback finish_callback; - }; - - void CheckAndMaybeStartDriveOperation() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - while (token_count_ > 0 && !drive_operation_queue_.empty()) { - auto next = std::move(drive_operation_queue_.front()); - drive_operation_queue_.pop(); - - if (!next.target) { - continue; - } - base::SequencedTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::BindOnce( - std::move(next.start_callback), - base::BindRepeating( - &DriveBackgroundOperationQueue<T>::OnDriveOperationComplete, - weak_ptr_factory_.GetWeakPtr(), - std::move(next.finish_callback)))); - --token_count_; - } - } - - void OnDriveOperationComplete(FileOperationCallback callback, - FileError error) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - callback.Run(error); - } - - void CheckAndMaybeStartTokenRefillTimer() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (token_refill_timer_.IsRunning()) { - return; - } - - base::TimeDelta elapsed_since_stopped = - tick_clock_->NowTicks() - last_timer_stop_ticks_; - int additional_tokens = elapsed_since_stopped / per_token_time_delta_; - - // Do not overflow when adding additional tokens. - if (desired_qps_ - token_count_ < additional_tokens) { - token_count_ = desired_qps_; - } else { - token_count_ += additional_tokens; - } - - token_refill_timer_.Start( - FROM_HERE, per_token_time_delta_, - base::BindRepeating(&DriveBackgroundOperationQueue<T>::RefillTokens, - weak_ptr_factory_.GetWeakPtr())); - } - - void RefillTokens() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - - if (token_count_ < desired_qps_) { - ++token_count_; - } - CheckAndMaybeStartDriveOperation(); - - if (drive_operation_queue_.empty()) { - token_refill_timer_.Stop(); - last_timer_stop_ticks_ = tick_clock_->NowTicks(); - } - } - - OperationQueue drive_operation_queue_; - - // Token Bucket timer, to refill tokens if required. - const base::TickClock* tick_clock_; // Not owned. - base::RepeatingTimer token_refill_timer_; - int token_count_; - const base::TimeDelta per_token_time_delta_; - int desired_qps_; - base::TimeTicks last_timer_stop_ticks_; - - SEQUENCE_CHECKER(sequence_checker_); - - base::WeakPtrFactory<DriveBackgroundOperationQueue> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(DriveBackgroundOperationQueue<T>); -}; - -} // namespace internal -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_DRIVE_OPERATION_QUEUE_H_
diff --git a/components/drive/chromeos/drive_test_util.cc b/components/drive/chromeos/drive_test_util.cc deleted file mode 100644 index 15134271..0000000 --- a/components/drive/chromeos/drive_test_util.cc +++ /dev/null
@@ -1,25 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/chromeos/drive_test_util.h" - -#include "components/drive/drive.pb.h" -#include "components/drive/drive_pref_names.h" -#include "components/prefs/pref_registry_simple.h" -#include "components/prefs/testing_pref_service.h" - -namespace drive { -namespace test_util { - -void RegisterDrivePrefs(PrefRegistrySimple* pref_registry) { - pref_registry->RegisterBooleanPref( - prefs::kDisableDrive, - false); - pref_registry->RegisterBooleanPref( - prefs::kDisableDriveOverCellular, - true); -} - -} // namespace test_util -} // namespace drive
diff --git a/components/drive/chromeos/drive_test_util.h b/components/drive/chromeos/drive_test_util.h deleted file mode 100644 index c65fff11..0000000 --- a/components/drive/chromeos/drive_test_util.h +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_CHROMEOS_DRIVE_TEST_UTIL_H_ -#define COMPONENTS_DRIVE_CHROMEOS_DRIVE_TEST_UTIL_H_ - -#include <stdint.h> - -#include <string> - -#include "components/drive/chromeos/file_cache.h" -#include "content/public/test/test_utils.h" -#include "google_apis/drive/test_util.h" -#include "net/base/io_buffer.h" -#include "net/base/test_completion_callback.h" - -class PrefRegistrySimple; - -namespace drive { - -namespace test_util { - -// Disk space size used by FakeFreeDiskSpaceGetter. -const int64_t kLotsOfSpace = drive::internal::kMinFreeSpaceInBytes * 10; - -// Helper to destroy objects which needs Destroy() to be called on destruction. -// Note: When using this helper, you should destruct objects before -// BrowserThread. -struct DestroyHelperForTests { - template<typename T> - void operator()(T* object) const { - if (object) { - object->Destroy(); - content::RunAllTasksUntilIdle(); // Finish destruction. - } - } -}; - -// Reads all the data from |reader| and copies to |content|. Returns net::Error -// code. -template<typename Reader> -int ReadAllData(Reader* reader, std::string* content) { - const int kBufferSize = 10; - scoped_refptr<net::IOBuffer> buffer = - base::MakeRefCounted<net::IOBuffer>(kBufferSize); - while (true) { - net::TestCompletionCallback callback; - int result = reader->Read(buffer.get(), kBufferSize, callback.callback()); - result = callback.GetResult(result); - if (result <= 0) { - // Found an error or EOF. Return it. Note: net::OK is 0. - return result; - } - content->append(buffer->data(), result); - } -} - -// Registers Drive related preferences in |pref_registry|. Drive related -// preferences should be registered as TestingPrefServiceSimple will crash if -// unregistered preference is referenced. -void RegisterDrivePrefs(PrefRegistrySimple* pref_registry); - -} // namespace test_util -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_DRIVE_TEST_UTIL_H_
diff --git a/components/drive/chromeos/fake_free_disk_space_getter.cc b/components/drive/chromeos/fake_free_disk_space_getter.cc deleted file mode 100644 index 11ee033..0000000 --- a/components/drive/chromeos/fake_free_disk_space_getter.cc +++ /dev/null
@@ -1,30 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/chromeos/fake_free_disk_space_getter.h" - -#include "components/drive/chromeos/drive_test_util.h" - -namespace drive { - -FakeFreeDiskSpaceGetter::FakeFreeDiskSpaceGetter() - : default_value_(test_util::kLotsOfSpace) { -} - -FakeFreeDiskSpaceGetter::~FakeFreeDiskSpaceGetter() = default; - -void FakeFreeDiskSpaceGetter::PushFakeValue(int64_t value) { - fake_values_.push_back(value); -} - -int64_t FakeFreeDiskSpaceGetter::AmountOfFreeDiskSpace() { - if (fake_values_.empty()) - return default_value_; - - const int64_t value = fake_values_.front(); - fake_values_.pop_front(); - return value; -} - -} // namespace drive
diff --git a/components/drive/chromeos/fake_free_disk_space_getter.h b/components/drive/chromeos/fake_free_disk_space_getter.h deleted file mode 100644 index 3a71b3c8..0000000 --- a/components/drive/chromeos/fake_free_disk_space_getter.h +++ /dev/null
@@ -1,46 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_CHROMEOS_FAKE_FREE_DISK_SPACE_GETTER_H_ -#define COMPONENTS_DRIVE_CHROMEOS_FAKE_FREE_DISK_SPACE_GETTER_H_ - -#include <stdint.h> - -#include <list> - -#include "base/macros.h" -#include "components/drive/chromeos/file_cache.h" - -namespace drive { - -// This class is used to report fake free disk space. In particular, this -// class can be used to simulate a case where disk is full, or nearly full. -class FakeFreeDiskSpaceGetter : public internal::FreeDiskSpaceGetterInterface { - public: - FakeFreeDiskSpaceGetter(); - ~FakeFreeDiskSpaceGetter() override; - - void set_default_value(int64_t value) { default_value_ = value; } - - // Pushes the given value to the back of the fake value list. - // - // If the fake value list is empty, AmountOfFreeDiskSpace() will return - // |default_value_| repeatedly. - // Otherwise, AmountOfFreeDiskSpace() will return the value at the front of - // the list and removes it from the list. - void PushFakeValue(int64_t value); - - // FreeDiskSpaceGetterInterface overrides. - int64_t AmountOfFreeDiskSpace() override; - - private: - std::list<int64_t> fake_values_; - int64_t default_value_; - - DISALLOW_COPY_AND_ASSIGN(FakeFreeDiskSpaceGetter); -}; - -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_FAKE_FREE_DISK_SPACE_GETTER_H_
diff --git a/components/drive/chromeos/file_cache.cc b/components/drive/chromeos/file_cache.cc deleted file mode 100644 index d8737a6..0000000 --- a/components/drive/chromeos/file_cache.cc +++ /dev/null
@@ -1,961 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/chromeos/file_cache.h" - -#include <linux/fs.h> -#include <sys/ioctl.h> -#include <sys/xattr.h> - -#include <memory> -#include <queue> -#include <vector> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/callback_helpers.h" -#include "base/files/file.h" -#include "base/files/file_enumerator.h" -#include "base/files/file_util.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/metrics/histogram_macros.h" -#include "base/stl_util.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/system/sys_info.h" -#include "build/build_config.h" -#include "components/drive/drive.pb.h" -#include "components/drive/drive_api_util.h" -#include "components/drive/file_system_core_util.h" -#include "components/drive/resource_metadata_storage.h" -#include "google_apis/drive/task_util.h" -#include "net/base/filename_util.h" -#include "net/base/mime_sniffer.h" -#include "net/base/mime_util.h" - -namespace drive { -namespace internal { -namespace { - -typedef std::pair<base::File::Info, ResourceEntry> CacheInfo; -typedef long FileAttributes; // NOLINT(runtime/int) - -// Returns ID extracted from the path. -std::string GetIdFromPath(const base::FilePath& path) { - return util::UnescapeCacheFileName(path.BaseName().AsUTF8Unsafe()); -} - -base::FilePath GetPathForId(const base::FilePath& cache_directory, - const std::string& id) { - return cache_directory.Append( - base::FilePath::FromUTF8Unsafe(util::EscapeCacheFileName(id))); -} - -// Returns if the filesystem backing |path| supports file attributes. -// This will return false if the filesystem is for example tmpfs, which is used -// for ephemeral mode. -bool IsFileAttributesSupported(const base::FilePath& path) { - if (getxattr(path.value().c_str(), "user.foo", nullptr, 0) >= 0) { - return true; - } - return errno != ENOTSUP; -} - -// Sets extended file attribute as |name| |value| pair. -bool SetExtendedFileAttributes(const base::FilePath& path, - const std::string& name, const std::string& value) { - if (setxattr(path.value().c_str(), name.c_str(), value.c_str(), - value.size() + 1, 0) != 0) { - PLOG(ERROR) << "setxattr: " << path.value(); - return false; - } - return true; -} - -// Remove extended file attribute with |name|. -bool UnsetExtendedFileAttributes(const base::FilePath& path, - const std::string& name) { - if (removexattr(path.value().c_str(), name.c_str()) != 0) { - PLOG_IF(ERROR, errno != ENODATA) << "removexattr: " << path.value(); - return false; - } - return true; -} - -// Changes attributes of the file with |flags|, e.g. FS_NODUMP_FL (cryptohome -// will remove Drive caches with this attribute). -// See linux/fs.h for available flags, and chattr(1) which does similar thing. -// Returns whether operation succeeded. -bool SetFileAttributes(const base::FilePath& path, FileAttributes flags) { - base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); - if (!file.IsValid()) { - PLOG(ERROR) << "Failed to open file: " << path.value(); - return false; - } - if (ioctl(file.GetPlatformFile(), FS_IOC_SETFLAGS, &flags) < 0) { - PLOG(ERROR) << "ioctl: " << path.value(); - return false; - } - return true; -} - -// Gets file attributes similarly to lsattr(1). Returns flags or -1 on error. -// See linux/fs.h for the definition of the returned flags e.g. FS_NODUMP_FL. -FileAttributes GetFileAttributes(const base::FilePath& path) { - base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); - if (!file.IsValid()) { - PLOG(ERROR) << "Failed to open file: " << path.value(); - return -1; - } - FileAttributes flags = 0; - if (ioctl(file.GetPlatformFile(), FS_IOC_GETFLAGS, &flags) < 0) { - PLOG(ERROR) << "ioctl: " << path.value(); - return -1; - } - return flags; -} - -// Marks the cache file to be removable by cryptohome, or do nothing if -// underlying filesystem doesn't support file attributes, as tmpfs for ephemeral -// mode. -bool SetRemovable(const base::FilePath& path) { - // For ephemeral mode. - if (!IsFileAttributesSupported(path)) { - return true; - } - FileAttributes flags = GetFileAttributes(path); - bool xattr = flags >= 0 && SetFileAttributes(path, flags | FS_NODUMP_FL); - bool fattr = SetExtendedFileAttributes( - path, FileCache::kGCacheRemovableAttribute, "1"); - return xattr || fattr; -} - -// Marks the cache file to be unremovable by cryptohome, or do nothing if -// underlying filesystem doesn't support file attributes, as tmpfs for ephemeral -// mode. -bool UnsetRemovable(const base::FilePath& path) { - // For ephemeral mode. - if (!IsFileAttributesSupported(path)) { - return true; - } - FileAttributes flags = GetFileAttributes(path); - bool xattr = flags >= 0 && SetFileAttributes(path, flags & ~FS_NODUMP_FL); - bool fattr = - UnsetExtendedFileAttributes(path, FileCache::kGCacheRemovableAttribute); - return xattr || fattr; -} - -// Marks |path| as drive cache dir, or do nothing if underlying filesystem -// doesn't support file attributes, as tmpfs for ephemeral mode. Returns if the -// operation succeeded. -bool MarkAsDriveCacheDir(const base::FilePath& path) { - // For ephemeral mode. - if (!IsFileAttributesSupported(path)) { - return true; - } - return SetRemovable(path) - && SetExtendedFileAttributes(path, FileCache::kGCacheFilesAttribute, ""); -} - -class CacheInfoLatestCompare { - public: - bool operator()(const CacheInfo& info_a, const CacheInfo& info_b) { - return info_a.first.last_accessed < info_b.first.last_accessed; - } -}; - -// Returns true if the cache file is present. -bool IsPresent(const ResourceEntry& entry) { - return entry.has_file_specific_info() && - entry.file_specific_info().has_cache_state() && - entry.file_specific_info().cache_state().is_present(); -} - -const size_t kMaxNumOfEvictedCacheFiles = 30000; - -} // namespace - -// static -const char FileCache::kGCacheFilesAttribute[] = "user.GCacheFiles"; -const char FileCache::kGCacheRemovableAttribute[] = "user.GCacheRemovable"; - -FileCache::FileCache(ResourceMetadataStorage* storage, - const base::FilePath& cache_file_directory, - base::SequencedTaskRunner* blocking_task_runner, - FreeDiskSpaceGetterInterface* free_disk_space_getter) - : cache_file_directory_(cache_file_directory), - blocking_task_runner_(blocking_task_runner), - storage_(storage), - free_disk_space_getter_(free_disk_space_getter), - max_num_of_evicted_cache_files_(kMaxNumOfEvictedCacheFiles) { - DCHECK(blocking_task_runner_.get()); -} - -FileCache::~FileCache() { - // Must be on the sequenced worker pool, as |metadata_| must be deleted on - // the sequenced worker pool. - AssertOnSequencedWorkerPool(); -} - -void FileCache::SetMaxNumOfEvictedCacheFilesForTest( - size_t max_num_of_evicted_cache_files) { - max_num_of_evicted_cache_files_ = max_num_of_evicted_cache_files; -} - -base::FilePath FileCache::GetCacheFilePath(const std::string& id) const { - return GetPathForId(cache_file_directory_, id); -} - -void FileCache::AssertOnSequencedWorkerPool() { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); -} - -bool FileCache::IsUnderFileCacheDirectory(const base::FilePath& path) const { - return cache_file_directory_.IsParent(path); -} - -bool FileCache::FreeDiskSpaceIfNeededFor(int64_t num_bytes) { - AssertOnSequencedWorkerPool(); - - // Do nothing and return if we have enough space. - if (GetAvailableSpace() >= num_bytes) - return true; - - // Otherwise, try to free up the disk space. - DVLOG(1) << "Freeing up disk space for " << num_bytes; - - // Remove all files which have no corresponding cache entries. - base::FileEnumerator enumerator(cache_file_directory_, - false, // not recursive - base::FileEnumerator::FILES); - ResourceEntry entry; - for (base::FilePath current = enumerator.Next(); !current.empty(); - current = enumerator.Next()) { - const std::string id = GetIdFromPath(current); - const FileError error = storage_->GetEntry(id, &entry); - - if (error == FILE_ERROR_NOT_FOUND) - base::DeleteFile(current, false /* recursive */); - else if (error != FILE_ERROR_OK) - return false; - } - - // Check available space again. If we have enough space here, do nothing. - const int64_t available_space = GetAvailableSpace(); - if (available_space >= num_bytes) - return true; - - const int64_t requested_space = num_bytes - available_space; - - // Put all entries in priority queue where latest entry becomes top. - std::priority_queue<CacheInfo, std::vector<CacheInfo>, CacheInfoLatestCompare> - cache_info_queue; - std::unique_ptr<ResourceMetadataStorage::Iterator> it = - storage_->GetIterator(); - for (; !it->IsAtEnd(); it->Advance()) { - if (IsEvictable(it->GetID(), it->GetValue())) { - const ResourceEntry& entry = it->GetValue(); - - const base::FilePath& cache_path = GetCacheFilePath(entry.local_id()); - base::File::Info info; - // If it fails to get file info of |cache_path|, use default value as its - // file info. i.e. the file becomes least recently used one. - base::GetFileInfo(cache_path, &info); - - CacheInfo cache_info = std::make_pair(info, entry); - - if (cache_info_queue.size() < max_num_of_evicted_cache_files_) { - cache_info_queue.push(cache_info); - } else if (cache_info_queue.size() >= max_num_of_evicted_cache_files_ && - cache_info.first.last_accessed < - cache_info_queue.top().first.last_accessed) { - // Do not enqueue more than max_num_of_evicted_cache_files_ not to use - // up memory with this queue. - cache_info_queue.pop(); - cache_info_queue.push(cache_info); - } - } - } - if (it->HasError()) - return false; - - // Copy entries to the vector. This becomes last-accessed desc order. - std::vector<CacheInfo> cache_info_list; - while (!cache_info_queue.empty()) { - cache_info_list.push_back(cache_info_queue.top()); - cache_info_queue.pop(); - } - - // Update DB and delete files with accessing to the vector in ascending order. - int64_t evicted_cache_size = 0; - auto iter = cache_info_list.rbegin(); - while (evicted_cache_size < requested_space && - iter != cache_info_list.rend()) { - const CacheInfo& cache_info = *iter; - - // Update DB. - ResourceEntry entry = cache_info.second; - entry.mutable_file_specific_info()->clear_cache_state(); - storage_->PutEntry(entry); - - // Delete cache file. - const base::FilePath& path = GetCacheFilePath(entry.local_id()); - - if (base::DeleteFile(path, false /* recursive */)) - evicted_cache_size += cache_info.first.size; - - ++iter; - } - - // Check the disk space again. - return GetAvailableSpace() >= num_bytes; -} - -int64_t FileCache::CalculateCacheSize() { - AssertOnSequencedWorkerPool(); - - int64_t total_cache_size = 0; - int64_t cache_size = 0; - - std::unique_ptr<ResourceMetadataStorage::Iterator> it = - storage_->GetIterator(); - for (; !it->IsAtEnd(); it->Advance()) { - if (IsPresent(it->GetValue()) && - base::GetFileSize(GetCacheFilePath(it->GetID()), &cache_size)) { - DCHECK_GE(cache_size, 0); - total_cache_size += cache_size; - } - } - - if (it->HasError()) - return 0; - - return total_cache_size; -} - -int64_t FileCache::CalculateEvictableCacheSize() { - AssertOnSequencedWorkerPool(); - - int64_t evictable_cache_size = 0; - int64_t cache_size = 0; - - std::unique_ptr<ResourceMetadataStorage::Iterator> it = - storage_->GetIterator(); - for (; !it->IsAtEnd(); it->Advance()) { - if (IsEvictable(it->GetID(), it->GetValue()) && - base::GetFileSize(GetCacheFilePath(it->GetID()), &cache_size)) { - DCHECK_GE(cache_size, 0); - evictable_cache_size += cache_size; - } - } - - if (it->HasError()) - return 0; - - return evictable_cache_size; -} - -FileError FileCache::GetFile(const std::string& id, - base::FilePath* cache_file_path) { - AssertOnSequencedWorkerPool(); - DCHECK(cache_file_path); - - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - if (!entry.file_specific_info().cache_state().is_present()) - return FILE_ERROR_NOT_FOUND; - - *cache_file_path = GetCacheFilePath(id); - return FILE_ERROR_OK; -} - -FileError FileCache::Store(const std::string& id, - const std::string& md5, - const base::FilePath& source_path, - FileOperationType file_operation_type) { - AssertOnSequencedWorkerPool(); - - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - - int64_t file_size = 0; - if (file_operation_type == FILE_OPERATION_COPY) { - if (!base::GetFileSize(source_path, &file_size)) { - LOG(WARNING) << "Couldn't get file size for: " << source_path.value(); - return FILE_ERROR_FAILED; - } - } - if (!FreeDiskSpaceIfNeededFor(file_size)) - return FILE_ERROR_NO_LOCAL_SPACE; - - // If file is mounted, return error. - if (mounted_files_.count(id)) - return FILE_ERROR_IN_USE; - - base::FilePath dest_path = GetCacheFilePath(id); - bool success = false; - switch (file_operation_type) { - case FILE_OPERATION_MOVE: - success = base::Move(source_path, dest_path); - break; - case FILE_OPERATION_COPY: - success = base::CopyFile(source_path, dest_path); - break; - default: - NOTREACHED(); - } - - if (!success) { - LOG(ERROR) << "Failed to store: " - << "source_path = " << source_path.value() << ", " - << "dest_path = " << dest_path.value() << ", " - << "file_operation_type = " << file_operation_type; - return FILE_ERROR_FAILED; - } - - // Now that file operations have completed, update metadata. - FileCacheEntry* cache_state = - entry.mutable_file_specific_info()->mutable_cache_state(); - cache_state->set_md5(md5); - cache_state->set_is_present(true); - if (md5.empty()) - cache_state->set_is_dirty(true); - - if (!cache_state->is_pinned() && !cache_state->is_dirty()) { - if (!SetRemovable(dest_path)) - return FILE_ERROR_FAILED; - } else { - if (!UnsetRemovable(dest_path)) - return FILE_ERROR_FAILED; - } - - return storage_->PutEntry(entry); -} - -FileError FileCache::Pin(const std::string& id) { - AssertOnSequencedWorkerPool(); - - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - - entry.mutable_file_specific_info()->mutable_cache_state()->set_is_pinned( - true); - - base::FilePath file_path = GetCacheFilePath(entry.local_id()); - // Cache file can be created later. - if (entry.file_specific_info().cache_state().is_present()) { - if (!UnsetRemovable(file_path)) - return FILE_ERROR_FAILED; - } - - return storage_->PutEntry(entry); -} - -FileError FileCache::Unpin(const std::string& id) { - AssertOnSequencedWorkerPool(); - - // Unpinning a file means its entry must exist in cache. - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - - // Now that file operations have completed, update metadata. - if (entry.file_specific_info().cache_state().is_present()) { - entry.mutable_file_specific_info()->mutable_cache_state()->set_is_pinned( - false); - if (!entry.file_specific_info().cache_state().is_dirty()) { - if (!SetRemovable(GetCacheFilePath(entry.local_id()))) - return FILE_ERROR_FAILED; - } - } else { - // Remove the existing entry if we are unpinning a non-present file. - entry.mutable_file_specific_info()->clear_cache_state(); - } - error = storage_->PutEntry(entry); - if (error != FILE_ERROR_OK) - return error; - - // Now it's a chance to free up space if needed. - FreeDiskSpaceIfNeededFor(0); - - return FILE_ERROR_OK; -} - -bool FileCache::IsMarkedAsMounted(const std::string& id) { - AssertOnSequencedWorkerPool(); - return mounted_files_.count(id); -} - -FileError FileCache::MarkAsMounted(const std::string& id, - base::FilePath* cache_file_path) { - AssertOnSequencedWorkerPool(); - DCHECK(cache_file_path); - - // Get cache entry associated with the id and md5 - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - if (!entry.file_specific_info().cache_state().is_present()) - return FILE_ERROR_NOT_FOUND; - - if (mounted_files_.count(id)) - return FILE_ERROR_INVALID_OPERATION; - - base::FilePath path = GetCacheFilePath(id); - -#if defined(OS_CHROMEOS) - // Ensure the file is readable to cros_disks. See crbug.com/236994. - if (!base::SetPosixFilePermissions( - path, - base::FILE_PERMISSION_READ_BY_USER | - base::FILE_PERMISSION_WRITE_BY_USER | - base::FILE_PERMISSION_READ_BY_GROUP | - base::FILE_PERMISSION_READ_BY_OTHERS)) - return FILE_ERROR_FAILED; -#endif - - mounted_files_.insert(id); - - *cache_file_path = path; - return FILE_ERROR_OK; -} - -FileError FileCache::OpenForWrite( - const std::string& id, - std::unique_ptr<base::ScopedClosureRunner>* file_closer) { - AssertOnSequencedWorkerPool(); - - // Marking a file dirty means its entry and actual file blob must exist in - // cache. - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - if (!entry.file_specific_info().cache_state().is_present()) { - LOG(WARNING) << "Can't mark dirty a file that wasn't cached: " << id; - return FILE_ERROR_NOT_FOUND; - } - - entry.mutable_file_specific_info()->mutable_cache_state()->set_is_dirty(true); - if (!UnsetRemovable(GetCacheFilePath(entry.local_id()))) - return FILE_ERROR_FAILED; - - entry.mutable_file_specific_info()->mutable_cache_state()->clear_md5(); - error = storage_->PutEntry(entry); - if (error != FILE_ERROR_OK) - return error; - - write_opened_files_[id]++; - *file_closer = std::make_unique<base::ScopedClosureRunner>( - base::Bind(&google_apis::RunTaskWithTaskRunner, blocking_task_runner_, - base::Bind(&FileCache::CloseForWrite, - weak_ptr_factory_.GetWeakPtr(), id))); - return FILE_ERROR_OK; -} - -bool FileCache::IsOpenedForWrite(const std::string& id) { - AssertOnSequencedWorkerPool(); - return write_opened_files_.count(id) != 0; -} - -FileError FileCache::UpdateMd5(const std::string& id) { - AssertOnSequencedWorkerPool(); - - if (IsOpenedForWrite(id)) - return FILE_ERROR_IN_USE; - - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - if (!entry.file_specific_info().cache_state().is_present()) - return FILE_ERROR_NOT_FOUND; - - const std::string& md5 = - util::GetMd5Digest(GetCacheFilePath(id), &in_shutdown_); - if (in_shutdown_.IsSet()) - return FILE_ERROR_ABORT; - if (md5.empty()) - return FILE_ERROR_NOT_FOUND; - - entry.mutable_file_specific_info()->mutable_cache_state()->set_md5(md5); - return storage_->PutEntry(entry); -} - -FileError FileCache::ClearDirty(const std::string& id) { - AssertOnSequencedWorkerPool(); - - if (IsOpenedForWrite(id)) - return FILE_ERROR_IN_USE; - - // Clearing a dirty file means its entry and actual file blob must exist in - // cache. - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - if (!entry.file_specific_info().cache_state().is_present()) { - LOG(WARNING) << "Can't clear dirty state of a file that wasn't cached: " - << id; - return FILE_ERROR_NOT_FOUND; - } - - // If a file is not dirty (it should have been marked dirty via OpenForWrite), - // clearing its dirty state is an invalid operation. - if (!entry.file_specific_info().cache_state().is_dirty()) { - LOG(WARNING) << "Can't clear dirty state of a non-dirty file: " << id; - return FILE_ERROR_INVALID_OPERATION; - } - - entry.mutable_file_specific_info()->mutable_cache_state()->set_is_dirty( - false); - if (!entry.file_specific_info().cache_state().is_pinned()) { - if (!SetRemovable(GetCacheFilePath(entry.local_id()))) - return FILE_ERROR_FAILED; - } - - return storage_->PutEntry(entry); -} - -FileError FileCache::Remove(const std::string& id) { - AssertOnSequencedWorkerPool(); - - ResourceEntry entry; - - // If entry doesn't exist, nothing to do. - FileError error = storage_->GetEntry(id, &entry); - if (error == FILE_ERROR_NOT_FOUND) - return FILE_ERROR_OK; - if (error != FILE_ERROR_OK) - return error; - if (!entry.file_specific_info().has_cache_state()) - return FILE_ERROR_OK; - - // Cannot delete a mounted file. - if (mounted_files_.count(id)) - return FILE_ERROR_IN_USE; - - // Delete the file. - base::FilePath path = GetCacheFilePath(id); - if (!base::DeleteFile(path, false /* recursive */)) - return FILE_ERROR_FAILED; - - // Now that all file operations have completed, remove from metadata. - entry.mutable_file_specific_info()->clear_cache_state(); - return storage_->PutEntry(entry); -} - -bool FileCache::ClearAll() { - AssertOnSequencedWorkerPool(); - - // Remove files. - base::FileEnumerator enumerator(cache_file_directory_, - false, // not recursive - base::FileEnumerator::FILES); - for (base::FilePath file = enumerator.Next(); !file.empty(); - file = enumerator.Next()) - base::DeleteFile(file, false /* recursive */); - - return true; -} - -bool FileCache::Initialize() { - AssertOnSequencedWorkerPool(); - - // Older versions do not clear MD5 when marking entries dirty. - // Clear MD5 of all dirty entries to deal with old data. - std::unique_ptr<ResourceMetadataStorage::Iterator> it = - storage_->GetIterator(); - for (; !it->IsAtEnd(); it->Advance()) { - if (it->GetValue().file_specific_info().cache_state().is_dirty()) { - ResourceEntry new_entry(it->GetValue()); - new_entry.mutable_file_specific_info()->mutable_cache_state()-> - clear_md5(); - if (storage_->PutEntry(new_entry) != FILE_ERROR_OK) - return false; - } - } - if (it->HasError()) - return false; - - if (!RenameCacheFilesToNewFormat()) - return false; - - // Run this every time to resolve inconsistency between metadata - // and file attributes which possibly occurs on abrupt power failure. - if (!FixMetadataAndFileAttributes()) { - return false; - } - - return true; -} - -void FileCache::Destroy() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - in_shutdown_.Set(); - - // Destroy myself on the blocking pool. - // Note that base::DeletePointer<> cannot be used as the destructor of this - // class is private. - blocking_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&FileCache::DestroyOnBlockingPool, - base::Unretained(this))); -} - -void FileCache::DestroyOnBlockingPool() { - AssertOnSequencedWorkerPool(); - delete this; -} - -bool FileCache::RecoverFilesFromCacheDirectory( - const base::FilePath& dest_directory, - const ResourceMetadataStorage::RecoveredCacheInfoMap& - recovered_cache_info) { - int file_number = 1; - - base::FileEnumerator enumerator(cache_file_directory_, - false, // not recursive - base::FileEnumerator::FILES); - for (base::FilePath current = enumerator.Next(); !current.empty(); - current = enumerator.Next()) { - const std::string& id = GetIdFromPath(current); - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK && error != FILE_ERROR_NOT_FOUND) - return false; - if (error == FILE_ERROR_OK && - entry.file_specific_info().cache_state().is_present()) { - // This file is managed by FileCache, no need to recover it. - continue; - } - - // If a cache entry which is non-dirty and has matching MD5 is found in - // |recovered_cache_entries|, it means the current file is already uploaded - // to the server. Just delete it instead of recovering it. - ResourceMetadataStorage::RecoveredCacheInfoMap::const_iterator it = - recovered_cache_info.find(id); - if (it != recovered_cache_info.end()) { - // Due to the DB corruption, cache info might be recovered from old - // revision. Perform MD5 check even when is_dirty is false just in case. - if (!it->second.is_dirty && - it->second.md5 == util::GetMd5Digest(current, &in_shutdown_)) { - base::DeleteFile(current, false /* recursive */); - continue; - } - } - - // Read file contents to sniff mime type. - std::vector<char> content(net::kMaxBytesToSniff); - const int read_result = - base::ReadFile(current, &content[0], content.size()); - if (read_result < 0) { - LOG(WARNING) << "Cannot read: " << current.value(); - return false; - } - if (read_result == 0) // Skip empty files. - continue; - - // Use recovered file name if available, otherwise decide file name with - // sniffed mime type. - base::FilePath dest_base_name(FILE_PATH_LITERAL("file")); - std::string mime_type; - if (it != recovered_cache_info.end() && !it->second.title.empty()) { - // We can use a file name recovered from the trashed DB. - dest_base_name = base::FilePath::FromUTF8Unsafe(it->second.title); - } else if (net::SniffMimeType( - &content[0], read_result, net::FilePathToFileURL(current), - std::string(), net::ForceSniffFileUrlsForHtml::kDisabled, - &mime_type) || - net::SniffMimeTypeFromLocalData(&content[0], read_result, - &mime_type)) { - // Change base name for common mime types. - if (net::MatchesMimeType("image/*", mime_type)) { - dest_base_name = base::FilePath(FILE_PATH_LITERAL("image")); - } else if (net::MatchesMimeType("video/*", mime_type)) { - dest_base_name = base::FilePath(FILE_PATH_LITERAL("video")); - } else if (net::MatchesMimeType("audio/*", mime_type)) { - dest_base_name = base::FilePath(FILE_PATH_LITERAL("audio")); - } - - // Estimate extension from mime type. - std::vector<base::FilePath::StringType> extensions; - base::FilePath::StringType extension; - if (net::GetPreferredExtensionForMimeType(mime_type, &extension)) - extensions.push_back(extension); - else - net::GetExtensionsForMimeType(mime_type, &extensions); - - // Add extension if possible. - if (!extensions.empty()) - dest_base_name = dest_base_name.AddExtension(extensions[0]); - } - - // Add file number to the file name and move. - const base::FilePath& dest_path = dest_directory.Append(dest_base_name) - .InsertBeforeExtensionASCII(base::StringPrintf("%08d", file_number++)); - if (!base::CreateDirectory(dest_directory) || - !base::Move(current, dest_path)) { - LOG(WARNING) << "Failed to move: " << current.value() - << " to " << dest_path.value(); - return false; - } - } - UMA_HISTOGRAM_COUNTS_1M("Drive.NumberOfCacheFilesRecoveredAfterDBCorruption", - file_number - 1); - return true; -} - -FileError FileCache::MarkAsUnmounted(const base::FilePath& file_path) { - AssertOnSequencedWorkerPool(); - DCHECK(IsUnderFileCacheDirectory(file_path)); - - std::string id = GetIdFromPath(file_path); - - // Get the entry associated with the id. - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - - std::set<std::string>::iterator it = mounted_files_.find(id); - if (it == mounted_files_.end()) - return FILE_ERROR_INVALID_OPERATION; - - mounted_files_.erase(it); - return FILE_ERROR_OK; -} - -int64_t FileCache::GetAvailableSpace() { - int64_t free_space = 0; - if (free_disk_space_getter_) - free_space = free_disk_space_getter_->AmountOfFreeDiskSpace(); - else - free_space = base::SysInfo::AmountOfFreeDiskSpace(cache_file_directory_); - - // Subtract this as if this portion does not exist. - free_space -= drive::internal::kMinFreeSpaceInBytes; - return free_space; -} - -bool FileCache::RenameCacheFilesToNewFormat() { - base::FileEnumerator enumerator(cache_file_directory_, - false, // not recursive - base::FileEnumerator::FILES); - for (base::FilePath current = enumerator.Next(); !current.empty(); - current = enumerator.Next()) { - base::FilePath new_path = current.RemoveExtension(); - if (!new_path.Extension().empty()) { - // Delete files with multiple extensions. - if (!base::DeleteFile(current, false /* recursive */)) - return false; - continue; - } - const std::string& id = GetIdFromPath(new_path); - new_path = GetCacheFilePath(util::CanonicalizeResourceId(id)); - if (new_path != current && !base::Move(current, new_path)) - return false; - } - return true; -} - -bool FileCache::FixMetadataAndFileAttributes() { - std::unique_ptr<ResourceMetadataStorage::Iterator> it = - storage_->GetIterator(); - - for (; !it->IsAtEnd(); it->Advance()) { - ResourceEntry entry = it->GetValue(); - FileCacheEntry* file_cache_entry = - entry.mutable_file_specific_info()->mutable_cache_state(); - - const base::FilePath filepath = GetPathForId(cache_file_directory_, - entry.local_id()); - - if (base::PathExists(filepath)) { - if (file_cache_entry->is_present()) { - // Update file attribues for cryptohome. - if (file_cache_entry->is_pinned() || file_cache_entry->is_dirty()) { - if (!UnsetRemovable(filepath)) return false; - } else { - if (!SetRemovable(filepath)) return false; - } - } else { - // Delete file if the file is present but metadata says not. - // It happens only on abrupt shutdown. - LOG(WARNING) - << "File is present but metadata's state was inconsistent."; - - if (!base::DeleteFile(filepath, false /* recursive */)) - return false; - } - } else { - // Update metatadata if there is no file but metadata says there is. - // It happens when cryptohome removed the file. - // We don't clear is_pinned here, so that file download is restarted on - // the following scenario: - // 1. The file was pinned but not present. - // 2. Then the file was downloaded and became present. - // 3. Unclean shutdown happens, metadata update was saved to the disk, - // but the file move was not. - if (file_cache_entry->is_present()) { - file_cache_entry->set_is_present(false); - file_cache_entry->set_is_dirty(false); - file_cache_entry->clear_md5(); - if (storage_->PutEntry(entry) != FILE_ERROR_OK) - return false; - } - } - } - - return MarkAsDriveCacheDir(cache_file_directory_); -} - -void FileCache::CloseForWrite(const std::string& id) { - AssertOnSequencedWorkerPool(); - - std::map<std::string, int>::iterator it = write_opened_files_.find(id); - if (it == write_opened_files_.end()) - return; - - DCHECK_LT(0, it->second); - --it->second; - if (it->second == 0) - write_opened_files_.erase(it); - - // Update last modified date. - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) { - LOG(ERROR) << "Failed to get entry: " << id << ", " - << FileErrorToString(error); - return; - } - int64_t now = base::Time::Now().ToInternalValue(); - entry.mutable_file_info()->set_last_modified(now); - entry.set_last_modified_by_me(now); - error = storage_->PutEntry(entry); - if (error != FILE_ERROR_OK) { - LOG(ERROR) << "Failed to put entry: " << id << ", " - << FileErrorToString(error); - } -} - -bool FileCache::IsEvictable(const std::string& id, const ResourceEntry& entry) { - return IsPresent(entry) && - !entry.file_specific_info().cache_state().is_pinned() && - !entry.file_specific_info().cache_state().is_dirty() && - !mounted_files_.count(id); -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/chromeos/file_cache.h b/components/drive/chromeos/file_cache.h deleted file mode 100644 index 8269719d..0000000 --- a/components/drive/chromeos/file_cache.h +++ /dev/null
@@ -1,243 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_CHROMEOS_FILE_CACHE_H_ -#define COMPONENTS_DRIVE_CHROMEOS_FILE_CACHE_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <memory> -#include <set> -#include <string> - -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "base/synchronization/atomic_flag.h" -#include "base/threading/thread_checker.h" -#include "build/build_config.h" -#include "components/drive/file_errors.h" -#include "components/drive/resource_metadata_storage.h" -#if defined(OS_CHROMEOS) -#include "third_party/cros_system_api/constants/cryptohome.h" -#endif - -namespace base { -class ScopedClosureRunner; -class SequencedTaskRunner; -} // namespace base - -namespace drive { - -namespace internal { - -#if defined(OS_CHROMEOS) -const int64_t kMinFreeSpaceInBytes = cryptohome::kMinFreeSpaceInBytes; -#else -const int64_t kMinFreeSpaceInBytes = 512ull * 1024ull * 1024ull; // 512MB -#endif - -// Interface class used for getting the free disk space. Tests can inject an -// implementation that reports fake free disk space. -class FreeDiskSpaceGetterInterface { - public: - virtual ~FreeDiskSpaceGetterInterface() = default; - virtual int64_t AmountOfFreeDiskSpace() = 0; -}; - -// FileCache is used to maintain cache states of FileSystem. -// -// All non-static public member functions, unless mentioned otherwise (see -// GetCacheFilePath() for example), should be run with |blocking_task_runner|. -class FileCache { - public: - // The file extended attribute assigned to Drive cache directory. - static const char kGCacheFilesAttribute[]; - // The file extended attribute assigned to files that can be removed. - static const char kGCacheRemovableAttribute[]; - - // Enum defining type of file operation e.g. copy or move, etc. - enum FileOperationType { - FILE_OPERATION_MOVE = 0, - FILE_OPERATION_COPY, - }; - - // |cache_file_directory| stores cached files. - // - // |blocking_task_runner| indicates the blocking worker pool for cache - // operations. All operations on this FileCache must be run on this runner. - // Must not be null. - // - // |free_disk_space_getter| is used to inject a custom free disk space - // getter for testing. NULL must be passed for production code. - // - // Must be called on the UI thread. - FileCache(ResourceMetadataStorage* storage, - const base::FilePath& cache_file_directory, - base::SequencedTaskRunner* blocking_task_runner, - FreeDiskSpaceGetterInterface* free_disk_space_getter); - - // Sets maximum number of evicted cache files for test. - void SetMaxNumOfEvictedCacheFilesForTest( - size_t max_num_of_evicted_cache_files); - - // Returns true if the given path is under drive cache directory, i.e. - // <user_profile_dir>/GCache/v1 - // - // Can be called on any thread. - bool IsUnderFileCacheDirectory(const base::FilePath& path) const; - - // Frees up disk space to store a file with |num_bytes| size content, while - // keeping drive::internal::kMinFreeSpaceInBytes bytes on the disk, if needed. - // Returns true if we successfully manage to have enough space, otherwise - // false. - bool FreeDiskSpaceIfNeededFor(int64_t num_bytes); - - // Calculates and returns cache size. In error case, this returns 0. - int64_t CalculateCacheSize(); - - // Calculates and returns evictable cache size. In error case, this returns 0. - int64_t CalculateEvictableCacheSize(); - - // Checks if file corresponding to |id| exists in cache, and returns - // FILE_ERROR_OK with |cache_file_path| storing the path to the file. - // |cache_file_path| must not be null. - FileError GetFile(const std::string& id, base::FilePath* cache_file_path); - - // Stores |source_path| as a cache of the remote content of the file - // with |id| and |md5|. - // Pass an empty string as MD5 to mark the entry as dirty. - FileError Store(const std::string& id, - const std::string& md5, - const base::FilePath& source_path, - FileOperationType file_operation_type); - - // Pins the specified entry. - FileError Pin(const std::string& id); - - // Unpins the specified entry. - FileError Unpin(const std::string& id); - - // Sets the state of the cache entry corresponding to |id| as mounted. - FileError MarkAsMounted(const std::string& id, - base::FilePath* cache_file_path); - - // Returns if a file corresponding to |id| is marked as mounted. - bool IsMarkedAsMounted(const std::string& id); - - // Sets the state of the cache entry corresponding to file_path as unmounted. - FileError MarkAsUnmounted(const base::FilePath& file_path); - - // Opens the cache file corresponding to |id| for write. |file_closer| should - // be kept alive until writing finishes. - // This method must be called before writing to cache files. - FileError OpenForWrite( - const std::string& id, - std::unique_ptr<base::ScopedClosureRunner>* file_closer); - - // Returns true if the cache file corresponding to |id| is write-opened. - bool IsOpenedForWrite(const std::string& id); - - // Calculates MD5 of the cache file and updates the stored value. - FileError UpdateMd5(const std::string& id); - - // Clears dirty state of the specified entry. - FileError ClearDirty(const std::string& id); - - // Removes the specified cache entry and delete cache files if available. - FileError Remove(const std::string& id); - - // Removes all the files in the cache directory. - bool ClearAll(); - - // Initializes the cache. Returns true on success. - bool Initialize(); - - // Destroys this cache. This function posts a task to the blocking task - // runner to safely delete the object. - // Must be called on the UI thread. - void Destroy(); - - // Moves files in the cache directory which are not managed by FileCache to - // |dest_directory|. - // |recovered_cache_info| should contain cache info recovered from the trashed - // metadata DB. It is used to ignore non-dirty files. - bool RecoverFilesFromCacheDirectory( - const base::FilePath& dest_directory, - const ResourceMetadataStorage::RecoveredCacheInfoMap& - recovered_cache_info); - - private: - friend class FileCacheTest; - - ~FileCache(); - - // Returns absolute path of the file if it were cached or to be cached. - // - // Can be called on any thread. - base::FilePath GetCacheFilePath(const std::string& id) const; - - // Checks whether the current thread is on the right sequenced worker pool - // with the right sequence ID. If not, DCHECK will fail. - void AssertOnSequencedWorkerPool(); - - // Destroys the cache on the blocking pool. - void DestroyOnBlockingPool(); - - // Returns available space, while keeping - // drive::internal::kMinFreeSpaceInBytes bytes on the disk. - int64_t GetAvailableSpace(); - - // Renames cache files from old "prefix:id.md5" format to the new format. - // TODO(hashimoto): Remove this method at some point. - bool RenameCacheFilesToNewFormat(); - - // Adds appropriate file attributes to the Drive cache directory and files in - // it for crbug.com/533750. Returns true on success. - // This also resolves inconsistency between cache files and metadata which can - // be produced when cryptohome removed cache files or on abrupt shutdown. - bool FixMetadataAndFileAttributes(); - - // This method must be called after writing to a cache file. - // Used to implement OpenForWrite(). - void CloseForWrite(const std::string& id); - - // Returns true if the cache entry can be evicted. - bool IsEvictable(const std::string& id, const ResourceEntry& entry); - - const base::FilePath cache_file_directory_; - - scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; - - base::AtomicFlag in_shutdown_; - - ResourceMetadataStorage* storage_; - - FreeDiskSpaceGetterInterface* free_disk_space_getter_; // Not owned. - - // Maximum number of cache files which can be evicted by a single call of - // FreeDiskSpaceIfNeededFor. That method takes O(n) memory space, we need to - // set this value not to use up memory. - size_t max_num_of_evicted_cache_files_; - - // IDs of files being write-opened. - std::map<std::string, int> write_opened_files_; - - // IDs of files marked mounted. - std::set<std::string> mounted_files_; - - THREAD_CHECKER(thread_checker_); - - // Note: This should remain the last member so it'll be destroyed and - // invalidate its weak pointers before any other members are destroyed. - // This object should be accessed only on |blocking_task_runner_|. - base::WeakPtrFactory<FileCache> weak_ptr_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(FileCache); -}; - -} // namespace internal -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_FILE_CACHE_H_
diff --git a/components/drive/chromeos/file_cache_unittest.cc b/components/drive/chromeos/file_cache_unittest.cc deleted file mode 100644 index cbefa22..0000000 --- a/components/drive/chromeos/file_cache_unittest.cc +++ /dev/null
@@ -1,902 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/chromeos/file_cache.h" - -#include <linux/fs.h> -#include <stddef.h> -#include <stdint.h> -#include <sys/ioctl.h> -#include <sys/xattr.h> - -#include <memory> -#include <string> -#include <vector> - -#include "base/callback_helpers.h" -#include "base/files/file.h" -#include "base/files/file_enumerator.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/hash/md5.h" -#include "base/path_service.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/stl_util.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" -#include "base/time/time.h" -#include "components/drive/chromeos/drive_test_util.h" -#include "components/drive/chromeos/fake_free_disk_space_getter.h" -#include "components/drive/drive.pb.h" -#include "components/drive/file_system_core_util.h" -#include "components/drive/resource_metadata_storage.h" -#include "content/public/test/browser_task_environment.h" -#include "google_apis/drive/test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { -namespace internal { -namespace { - -typedef long FileAttributes; // NOLINT(runtime/int) - -const base::FilePath::CharType kCacheFileDirectory[] = - FILE_PATH_LITERAL("files"); - -const int kTemporaryFileSizeInBytes = 10; - -FileAttributes GetFileAttributes(const base::FilePath& file_path) { - base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ); - if (!file.IsValid()) { - ADD_FAILURE() << "Failed to open file: " << file_path.value(); - return -1; - } - FileAttributes flags = 0; - if (ioctl(file.GetPlatformFile(), FS_IOC_GETFLAGS, &flags) < 0) { - ADD_FAILURE() << "Failed to get attributes: " << file_path.value(); - return -1; - } - return flags; -} - -bool HasRemovableFlag(const base::FilePath& file_path) { - return (GetFileAttributes(file_path) & FS_NODUMP_FL) == FS_NODUMP_FL; -} - -bool HasRemovableAttribute(const base::FilePath& file_path) { - return getxattr(file_path.value().c_str(), - FileCache::kGCacheRemovableAttribute, nullptr, 0) >= 0; -} - -bool IsMarkedAsRemovable(const base::FilePath& path) { - return HasRemovableFlag(path) && HasRemovableAttribute(path); -} - -} // namespace - -// Tests FileCache methods working with the blocking task runner. -class FileCacheTest : public testing::Test { - protected: - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - const base::FilePath metadata_dir = temp_dir_.GetPath().AppendASCII("meta"); - cache_files_dir_ = temp_dir_.GetPath().Append(kCacheFileDirectory); - - ASSERT_TRUE(base::CreateDirectory(metadata_dir)); - ASSERT_TRUE(base::CreateDirectory(cache_files_dir_)); - - fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>(); - - metadata_storage_.reset(new ResourceMetadataStorage( - metadata_dir, - base::ThreadTaskRunnerHandle::Get().get())); - ASSERT_TRUE(metadata_storage_->Initialize()); - - cache_.reset(new FileCache(metadata_storage_.get(), cache_files_dir_, - base::ThreadTaskRunnerHandle::Get().get(), - fake_free_disk_space_getter_.get())); - ASSERT_TRUE(cache_->Initialize()); - } - - static bool RenameCacheFilesToNewFormat(FileCache* cache) { - return cache->RenameCacheFilesToNewFormat(); - } - - base::FilePath GetCacheFilePath(const std::string& id) { - return cache_->GetCacheFilePath(id); - } - - base::FilePath AddTestEntry(const std::string id, - const std::string md5, - const time_t last_accessed, - const base::FilePath& src_file) { - ResourceEntry entry; - entry.set_local_id(id); - entry.mutable_file_info()->set_last_accessed(last_accessed); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - EXPECT_EQ(FILE_ERROR_OK, - cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY)); - - base::FilePath path; - EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &path)); - - // Update last modified and accessed time. - base::Time time = base::Time::FromTimeT(last_accessed); - EXPECT_TRUE(base::TouchFile(path, time, time)); - - return path; - } - - content::BrowserTaskEnvironment task_environment_; - base::ScopedTempDir temp_dir_; - base::FilePath cache_files_dir_; - - std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests> - metadata_storage_; - std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_; - std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_; -}; - -TEST_F(FileCacheTest, RecoverFilesFromCacheDirectory) { - base::FilePath dir_source_root; - EXPECT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &dir_source_root)); - const base::FilePath src_path = - dir_source_root.AppendASCII("chrome/test/data/chromeos/drive/image.png"); - - // Store files. This file should not be moved. - ResourceEntry entry; - entry.set_local_id("id_foo"); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - EXPECT_EQ(FILE_ERROR_OK, cache_->Store("id_foo", "md5", src_path, - FileCache::FILE_OPERATION_COPY)); - - // Set up files in the cache directory. These files should be moved. - const base::FilePath file_directory = - temp_dir_.GetPath().Append(kCacheFileDirectory); - ASSERT_TRUE(base::CopyFile(src_path, file_directory.AppendASCII("id_bar"))); - ASSERT_TRUE(base::CopyFile(src_path, file_directory.AppendASCII("id_baz"))); - - // Insert a dirty entry with "id_baz" to |recovered_cache_info|. - // This should not prevent the file from being recovered. - ResourceMetadataStorage::RecoveredCacheInfoMap recovered_cache_info; - recovered_cache_info["id_baz"].is_dirty = true; - recovered_cache_info["id_baz"].title = "baz.png"; - - // Recover files. - const base::FilePath dest_directory = temp_dir_.GetPath().AppendASCII("dest"); - EXPECT_TRUE(cache_->RecoverFilesFromCacheDirectory(dest_directory, - recovered_cache_info)); - - // Only two files should be recovered. - EXPECT_TRUE(base::PathExists(dest_directory)); - // base::FileEnumerator does not guarantee the order. - if (base::PathExists(dest_directory.AppendASCII("baz00000001.png"))) { - EXPECT_TRUE(base::ContentsEqual( - src_path, - dest_directory.AppendASCII("baz00000001.png"))); - EXPECT_TRUE(base::ContentsEqual( - src_path, - dest_directory.AppendASCII("image00000002.png"))); - } else { - EXPECT_TRUE(base::ContentsEqual( - src_path, - dest_directory.AppendASCII("image00000001.png"))); - EXPECT_TRUE(base::ContentsEqual( - src_path, - dest_directory.AppendASCII("baz00000002.png"))); - } - EXPECT_FALSE(base::PathExists( - dest_directory.AppendASCII("image00000003.png"))); -} - -TEST_F(FileCacheTest, FreeDiskSpaceIfNeededFor) { - base::FilePath src_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file)); - - // Store a file as a 'temporary' file and remember the path. - const std::string id_tmp = "id_tmp", md5_tmp = "md5_tmp"; - const time_t last_accessed_tmp = 1; - const base::FilePath& tmp_path = - AddTestEntry(id_tmp, md5_tmp, last_accessed_tmp, src_file); - - // Store a file as a pinned file and remember the path. - const std::string id_pinned = "id_pinned", md5_pinned = "md5_pinned"; - const time_t last_accessed_pinned = 1; - const base::FilePath& pinned_path = - AddTestEntry(id_pinned, md5_pinned, last_accessed_pinned, src_file); - ASSERT_EQ(FILE_ERROR_OK, cache_->Pin(id_pinned)); - - // Call FreeDiskSpaceIfNeededFor(). - fake_free_disk_space_getter_->set_default_value(test_util::kLotsOfSpace); - fake_free_disk_space_getter_->PushFakeValue(0); - fake_free_disk_space_getter_->PushFakeValue(0); - const int64_t kNeededBytes = 1; - EXPECT_TRUE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes)); - - // Only 'temporary' file gets removed. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_tmp, &entry)); - EXPECT_FALSE(entry.file_specific_info().cache_state().is_present()); - EXPECT_FALSE(base::PathExists(tmp_path)); - - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_pinned, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); - EXPECT_TRUE(base::PathExists(pinned_path)); - - // Returns false when disk space cannot be freed. - fake_free_disk_space_getter_->set_default_value(0); - EXPECT_FALSE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes)); -} - -TEST_F(FileCacheTest, EvictDriveCacheInLRU) { - // Create temporary file. - base::FilePath src_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file)); - ASSERT_EQ(kTemporaryFileSizeInBytes, - base::WriteFile(src_file, "abcdefghij", kTemporaryFileSizeInBytes)); - - // Add entries. - const std::string id_a = "id_a", md5_a = "md5_a"; - const time_t last_accessed_a = 1; - const base::FilePath& a_path = - AddTestEntry(id_a, md5_a, last_accessed_a, src_file); - - const std::string id_pinned = "id_pinned", md5_pinned = "md5_pinned"; - const time_t last_accessed_pinned = 2; - const base::FilePath& pinned_path = - AddTestEntry(id_pinned, md5_pinned, last_accessed_pinned, src_file); - ASSERT_EQ(FILE_ERROR_OK, cache_->Pin(id_pinned)); - - const std::string id_b = "id_b", md5_b = "md5_b"; - const time_t last_accessed_b = 3; - const base::FilePath& b_path = - AddTestEntry(id_b, md5_b, last_accessed_b, src_file); - - const std::string id_c = "id_c", md5_c = "md5_c"; - const time_t last_accessed_c = 4; - const base::FilePath& c_path = - AddTestEntry(id_c, md5_c, last_accessed_c, src_file); - - // Call FreeDiskSpaceIfNeededFor. - fake_free_disk_space_getter_->set_default_value(test_util::kLotsOfSpace); - fake_free_disk_space_getter_->PushFakeValue(kMinFreeSpaceInBytes); - fake_free_disk_space_getter_->PushFakeValue(kMinFreeSpaceInBytes); - const int64_t kNeededBytes = kTemporaryFileSizeInBytes * 3 / 2; - EXPECT_TRUE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes)); - - // Entry A is evicted. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_a, &entry)); - EXPECT_FALSE(entry.file_specific_info().cache_state().is_present()); - EXPECT_FALSE(base::PathExists(a_path)); - - // Pinned entry should not be evicted. - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_pinned, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); - EXPECT_TRUE(base::PathExists(pinned_path)); - - // Entry B is evicted. - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_b, &entry)); - EXPECT_FALSE(entry.file_specific_info().cache_state().is_present()); - EXPECT_FALSE(base::PathExists(b_path)); - - // Entry C should not be evicted. - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_c, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); - EXPECT_TRUE(base::PathExists(c_path)); -} - -// Test case for deleting invalid cache files which don't have corresponding -// metadata. -TEST_F(FileCacheTest, EvictInvalidCacheFile) { - base::FilePath src_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file)); - - // Add entries. - const std::string id_a = "id_a", md5_a = "md5_a"; - const time_t last_accessed_a = 1; - const base::FilePath& a_path = - AddTestEntry(id_a, md5_a, last_accessed_a, src_file); - - const std::string id_b = "id_b", md5_b = "md5_b"; - const time_t last_accessed_b = 2; - const base::FilePath& b_path = - AddTestEntry(id_b, md5_b, last_accessed_b, src_file); - - // Remove metadata of entry B. - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->RemoveEntry(id_b)); - - // Confirm cache file of entry B exists. - ASSERT_TRUE(base::PathExists(b_path)); - - // Run FreeDiskSpaceIfNeededFor. - fake_free_disk_space_getter_->set_default_value(test_util::kLotsOfSpace); - fake_free_disk_space_getter_->PushFakeValue(kMinFreeSpaceInBytes); - const int64_t kNeededBytes = 1; - EXPECT_TRUE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes)); - - // Entry A is not evicted. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_a, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); - EXPECT_TRUE(base::PathExists(a_path)); - - // Entry B is evicted. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, metadata_storage_->GetEntry(id_b, &entry)); - EXPECT_FALSE(base::PathExists(b_path)); -} - -TEST_F(FileCacheTest, TooManyCacheFiles) { - const size_t kMaxNumOfEvictedCacheFiles = 50; - cache_->SetMaxNumOfEvictedCacheFilesForTest(kMaxNumOfEvictedCacheFiles); - - // Create temporary file. - base::FilePath src_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file)); - ASSERT_EQ(kTemporaryFileSizeInBytes, - base::WriteFile(src_file, "abcdefghij", kTemporaryFileSizeInBytes)); - - // Add kNumOfTestFiles=kMaxNumOfEvictedCacheFiles*2 entries. - std::vector<base::FilePath> paths; - const int32_t kNumOfTestFiles = kMaxNumOfEvictedCacheFiles * 2; - for (int i = 0; i < kNumOfTestFiles; ++i) { - // Set last accessed in reverse order to the file name. i.e. If you sort - // files in name-asc order, they will be last access desc order. - paths.push_back(AddTestEntry( - base::StringPrintf("id_%02d", i), base::StringPrintf("md5_%02d", i), - kNumOfTestFiles - i /* last accessed */, src_file)); - } - - // Confirm cache files of kNumOfTestFiles actually exist. - for (const auto& path : paths) { - ASSERT_TRUE(base::PathExists(path)) << path.value(); - } - - // Try to free kMaxNumOfEvictedCacheFiles * 3 / 2. - fake_free_disk_space_getter_->set_default_value(test_util::kLotsOfSpace); - fake_free_disk_space_getter_->PushFakeValue(kMinFreeSpaceInBytes); - fake_free_disk_space_getter_->PushFakeValue(kMinFreeSpaceInBytes); - fake_free_disk_space_getter_->PushFakeValue( - kMinFreeSpaceInBytes + - (kMaxNumOfEvictedCacheFiles * kTemporaryFileSizeInBytes)); - const int64_t kNeededBytes = - (kMaxNumOfEvictedCacheFiles * 3 / 2) * kTemporaryFileSizeInBytes; - EXPECT_FALSE(cache_->FreeDiskSpaceIfNeededFor(kNeededBytes)); - - for (uint32_t i = 0; i < kNumOfTestFiles; ++i) { - // Assert that only first kMaxNumOfEvictedCacheFiles exist. - ASSERT_EQ(i < kMaxNumOfEvictedCacheFiles, base::PathExists(paths[i])); - } -} - -TEST_F(FileCacheTest, GetFile) { - const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat"); - const std::string src_contents = "test"; - EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, - src_contents)); - std::string id("id1"); - std::string md5(base::MD5String(src_contents)); - - const base::FilePath cache_file_directory = - temp_dir_.GetPath().Append(kCacheFileDirectory); - - // Try to get an existing file from cache. - ResourceEntry entry; - entry.set_local_id(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, md5, src_file_path, - FileCache::FILE_OPERATION_COPY)); - base::FilePath cache_file_path; - EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); - EXPECT_EQ( - cache_file_directory.AppendASCII(util::EscapeCacheFileName(id)).value(), - cache_file_path.value()); - - std::string contents; - EXPECT_TRUE(base::ReadFileToString(cache_file_path, &contents)); - EXPECT_EQ(src_contents, contents); - - // Get file from cache with different id. - id = "id2"; - entry.Clear(); - entry.set_local_id(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->GetFile(id, &cache_file_path)); - - // Pin a non-existent file. - EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id)); - - // Get the non-existent pinned file from cache. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->GetFile(id, &cache_file_path)); - - // Get a previously pinned and stored file from cache. - EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, md5, src_file_path, - FileCache::FILE_OPERATION_COPY)); - - EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); - EXPECT_EQ( - cache_file_directory.AppendASCII(util::EscapeCacheFileName(id)).value(), - cache_file_path.value()); - - contents.clear(); - EXPECT_TRUE(base::ReadFileToString(cache_file_path, &contents)); - EXPECT_EQ(src_contents, contents); -} - -TEST_F(FileCacheTest, Store) { - const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat"); - const std::string src_contents = "test"; - EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, - src_contents)); - std::string id("id"); - std::string md5(base::MD5String(src_contents)); - - // Store a file. - ResourceEntry entry; - entry.set_local_id(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - EXPECT_EQ(FILE_ERROR_OK, cache_->Store( - id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); - - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); - EXPECT_EQ(md5, entry.file_specific_info().cache_state().md5()); - - base::FilePath cache_file_path; - EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); - EXPECT_TRUE(base::ContentsEqual(src_file_path, cache_file_path)); - - base::FilePath dest_file_path = GetCacheFilePath(id); - EXPECT_TRUE(IsMarkedAsRemovable(dest_file_path)); - - // Store a non-existent file. - EXPECT_EQ(FILE_ERROR_FAILED, cache_->Store( - id, md5, base::FilePath::FromUTF8Unsafe("non_existent_file"), - FileCache::FILE_OPERATION_COPY)); - - // Passing empty MD5 marks the entry as dirty. - EXPECT_EQ(FILE_ERROR_OK, cache_->Store( - id, std::string(), src_file_path, FileCache::FILE_OPERATION_COPY)); - - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); - EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty()); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); - EXPECT_FALSE(IsMarkedAsRemovable(dest_file_path)); - - // No free space available. - fake_free_disk_space_getter_->set_default_value(0); - - EXPECT_EQ(FILE_ERROR_NO_LOCAL_SPACE, cache_->Store( - id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); -} - -TEST_F(FileCacheTest, PinAndUnpin) { - const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat"); - const std::string src_contents = "test"; - EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, - src_contents)); - std::string id("id_present"); - std::string md5(base::MD5String(src_contents)); - - // Store a file. - ResourceEntry entry; - entry.set_local_id(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - EXPECT_EQ(FILE_ERROR_OK, cache_->Store( - id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); - - const base::FilePath dest_file_path = GetCacheFilePath(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned()); - EXPECT_TRUE(IsMarkedAsRemovable(dest_file_path)); - - // Pin the existing file. - EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id)); - - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned()); - EXPECT_FALSE(IsMarkedAsRemovable(dest_file_path)); - - // Unpin the file. - EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id)); - - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned()); - EXPECT_TRUE(IsMarkedAsRemovable(dest_file_path)); - - // Pin a non-present file. - std::string id_non_present = "id_non_present"; - entry.Clear(); - entry.set_local_id(id_non_present); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(id_non_present)); - - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned()); - - // Unpin the previously pinned non-existent file. - EXPECT_EQ(FILE_ERROR_OK, cache_->Unpin(id_non_present)); - - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_non_present, &entry)); - EXPECT_FALSE(entry.file_specific_info().has_cache_state()); - - // Unpin a file that doesn't exist in cache and is not pinned. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, cache_->Unpin("id_non_existent")); -} - -TEST_F(FileCacheTest, MountUnmount) { - const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat"); - const std::string src_contents = "test"; - EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, - src_contents)); - std::string id("id_present"); - std::string md5(base::MD5String(src_contents)); - - // Store a file. - ResourceEntry entry; - entry.set_local_id(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - EXPECT_EQ(FILE_ERROR_OK, cache_->Store( - id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); - - // Mark the file mounted. - base::FilePath cache_file_path; - EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsMounted(id, &cache_file_path)); - - EXPECT_TRUE(cache_->IsMarkedAsMounted(id)); - - // Try to remove it. - EXPECT_EQ(FILE_ERROR_IN_USE, cache_->Remove(id)); - - // Clear mounted state of the file. - EXPECT_EQ(FILE_ERROR_OK, cache_->MarkAsUnmounted(cache_file_path)); - - EXPECT_FALSE(cache_->IsMarkedAsMounted(id)); - - // Try to remove again. - EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id)); -} - -TEST_F(FileCacheTest, OpenForWrite) { - // Prepare a file. - base::FilePath src_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file)); - - const std::string id = "id"; - ResourceEntry entry; - entry.set_local_id(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file, - FileCache::FILE_OPERATION_COPY)); - EXPECT_EQ(0, entry.file_info().last_modified()); - EXPECT_EQ(0, entry.last_modified_by_me()); - - // Entry is not dirty nor opened. - EXPECT_FALSE(cache_->IsOpenedForWrite(id)); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty()); - - const base::FilePath dest_file = GetCacheFilePath(id); - EXPECT_TRUE(IsMarkedAsRemovable(dest_file)); - - // Open (1). - std::unique_ptr<base::ScopedClosureRunner> file_closer1; - EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer1)); - EXPECT_TRUE(cache_->IsOpenedForWrite(id)); - - // Entry is dirty. - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); - EXPECT_FALSE(IsMarkedAsRemovable((dest_file))); - - // Open (2). - std::unique_ptr<base::ScopedClosureRunner> file_closer2; - EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer2)); - EXPECT_TRUE(cache_->IsOpenedForWrite(id)); - - // Close (1). - file_closer1.reset(); - base::RunLoop().RunUntilIdle(); - EXPECT_TRUE(cache_->IsOpenedForWrite(id)); - - // last_modified and last_modified_by_me are updated. - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_NE(0, entry.file_info().last_modified()); - EXPECT_NE(0, entry.last_modified_by_me()); - EXPECT_EQ(entry.file_info().last_modified(), entry.last_modified_by_me()); - - // Close (2). - file_closer2.reset(); - base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(cache_->IsOpenedForWrite(id)); - - // Try to open non-existent file. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, - cache_->OpenForWrite("nonexistent_id", &file_closer1)); -} - -TEST_F(FileCacheTest, UpdateMd5) { - // Store test data. - const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat"); - const std::string contents_before = "before"; - EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, - contents_before)); - std::string id("id1"); - ResourceEntry entry; - entry.set_local_id(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - EXPECT_EQ(FILE_ERROR_OK, cache_->Store(id, base::MD5String(contents_before), - src_file_path, - FileCache::FILE_OPERATION_COPY)); - - // Modify the cache file. - std::unique_ptr<base::ScopedClosureRunner> file_closer; - EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer)); - base::FilePath cache_file_path; - EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); - const std::string contents_after = "after"; - EXPECT_TRUE(google_apis::test_util::WriteStringToFile(cache_file_path, - contents_after)); - - // Cannot update MD5 of an opend file. - EXPECT_EQ(FILE_ERROR_IN_USE, cache_->UpdateMd5(id)); - - // Close file. - file_closer.reset(); - base::RunLoop().RunUntilIdle(); - - // MD5 was cleared by OpenForWrite(). - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty()); - - // Update MD5. - EXPECT_EQ(FILE_ERROR_OK, cache_->UpdateMd5(id)); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_EQ(base::MD5String(contents_after), - entry.file_specific_info().cache_state().md5()); -} - -TEST_F(FileCacheTest, ClearDirty) { - // Prepare a file. - base::FilePath src_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file)); - - const std::string id = "id"; - ResourceEntry entry; - entry.set_local_id(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - ASSERT_EQ(FILE_ERROR_OK, cache_->Store(id, "md5", src_file, - FileCache::FILE_OPERATION_COPY)); - - const base::FilePath dest_file = GetCacheFilePath(id); - EXPECT_TRUE(IsMarkedAsRemovable(dest_file)); - - // Open the file. - std::unique_ptr<base::ScopedClosureRunner> file_closer; - EXPECT_EQ(FILE_ERROR_OK, cache_->OpenForWrite(id, &file_closer)); - - // Entry is dirty. - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty()); - EXPECT_FALSE(IsMarkedAsRemovable(dest_file)); - - // Cannot clear the dirty bit of an opened entry. - EXPECT_EQ(FILE_ERROR_IN_USE, cache_->ClearDirty(id)); - EXPECT_FALSE(IsMarkedAsRemovable(dest_file)); - - // Close the file and clear the dirty bit. - file_closer.reset(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, cache_->ClearDirty(id)); - - // Entry is not dirty. - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id, &entry)); - EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty()); - EXPECT_TRUE(IsMarkedAsRemovable(dest_file)); -} - -TEST_F(FileCacheTest, Remove) { - const base::FilePath src_file_path = temp_dir_.GetPath().Append("test.dat"); - const std::string src_contents = "test"; - EXPECT_TRUE(google_apis::test_util::WriteStringToFile(src_file_path, - src_contents)); - std::string id("id"); - std::string md5(base::MD5String(src_contents)); - - // First store a file to cache. - ResourceEntry entry; - entry.set_local_id(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - base::FilePath src_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file)); - EXPECT_EQ(FILE_ERROR_OK, cache_->Store( - id, md5, src_file_path, FileCache::FILE_OPERATION_COPY)); - - base::FilePath cache_file_path; - EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(id, &cache_file_path)); - - // Then try to remove existing file from cache. - EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(id)); - EXPECT_FALSE(base::PathExists(cache_file_path)); -} - -TEST_F(FileCacheTest, RenameCacheFilesToNewFormat) { - const base::FilePath file_directory = - temp_dir_.GetPath().Append(kCacheFileDirectory); - - // File with an old style "<prefix>:<ID>.<MD5>" name. - ASSERT_TRUE(google_apis::test_util::WriteStringToFile( - file_directory.AppendASCII("file:id_koo.md5"), "koo")); - - // File with multiple extensions should be removed. - ASSERT_TRUE(google_apis::test_util::WriteStringToFile( - file_directory.AppendASCII("id_kyu.md5.mounted"), "kyu (mounted)")); - ASSERT_TRUE(google_apis::test_util::WriteStringToFile( - file_directory.AppendASCII("id_kyu.md5"), "kyu")); - - // Rename and verify the result. - EXPECT_TRUE(RenameCacheFilesToNewFormat(cache_.get())); - std::string contents; - EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"), - &contents)); - EXPECT_EQ("koo", contents); - contents.clear(); - EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"), - &contents)); - EXPECT_EQ("kyu", contents); - - // Rename again. - EXPECT_TRUE(RenameCacheFilesToNewFormat(cache_.get())); - - // Files with new style names are not affected. - contents.clear(); - EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_koo"), - &contents)); - EXPECT_EQ("koo", contents); - contents.clear(); - EXPECT_TRUE(base::ReadFileToString(file_directory.AppendASCII("id_kyu"), - &contents)); - EXPECT_EQ("kyu", contents); -} - -TEST_F(FileCacheTest, FixMetadataAndFileAttributes) { - // Create test files and metadata. - base::FilePath temp_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file)); - - // Entry A: pinned cache file. - const std::string id_a = "id_a"; - ResourceEntry entry_a; - entry_a.set_local_id(id_a); - FileCacheEntry* file_cache_entry_a = - entry_a.mutable_file_specific_info()->mutable_cache_state(); - file_cache_entry_a->set_is_present(true); - file_cache_entry_a->set_is_pinned(true); - file_cache_entry_a->set_is_dirty(false); - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_a)); - const base::FilePath file_path_a = GetCacheFilePath(id_a); - ASSERT_TRUE(base::CopyFile(temp_file, file_path_a)); - - // Entry B: dirty cache file. - const std::string id_b = "id_b"; - ResourceEntry entry_b; - entry_b.set_local_id(id_b); - FileCacheEntry* file_cache_entry_b = - entry_b.mutable_file_specific_info()->mutable_cache_state(); - file_cache_entry_b->set_is_present(true); - file_cache_entry_b->set_is_pinned(false); - file_cache_entry_b->set_is_dirty(true); - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_b)); - const base::FilePath file_path_b = GetCacheFilePath(id_b); - ASSERT_TRUE(base::CopyFile(temp_file, file_path_b)); - - // Entry C: not pinned nor dirty cache file. - const std::string id_c = "id_c"; - ResourceEntry entry_c; - entry_c.set_local_id(id_c); - FileCacheEntry* file_cache_entry_c = - entry_c.mutable_file_specific_info()->mutable_cache_state(); - file_cache_entry_c->set_is_present(true); - file_cache_entry_c->set_is_pinned(false); - file_cache_entry_c->set_is_dirty(false); - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_c)); - const base::FilePath file_path_c = GetCacheFilePath(id_c); - ASSERT_TRUE(base::CopyFile(temp_file, file_path_c)); - - // Entry D: pinned cache file somehow having removable flag. - const std::string id_d = "id_d"; - ResourceEntry entry_d; - entry_d.set_local_id(id_d); - FileCacheEntry* file_cache_entry_d = - entry_d.mutable_file_specific_info()->mutable_cache_state(); - file_cache_entry_d->set_is_present(true); - file_cache_entry_d->set_is_pinned(true); - file_cache_entry_d->set_is_dirty(false); - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_d)); - const base::FilePath file_path_d = GetCacheFilePath(id_d); - ASSERT_TRUE(base::CopyFile(temp_file, file_path_d)); - - // Set removable flag. - FileAttributes flags = GetFileAttributes(file_path_d); - ASSERT_GE(flags, 0); - flags |= FS_NODUMP_FL; - base::File file_d(file_path_d, base::File::FLAG_OPEN | base::File::FLAG_READ); - ASSERT_EQ(ioctl(file_d.GetPlatformFile(), FS_IOC_SETFLAGS, &flags), 0); - - // Entry E: there is no file; removed by cryptohome. - const std::string id_e = "id_e"; - ResourceEntry entry_e; - entry_e.set_local_id(id_e); - FileCacheEntry* file_cache_entry_e = - entry_e.mutable_file_specific_info()->mutable_cache_state(); - file_cache_entry_e->set_is_present(true); - file_cache_entry_e->set_is_pinned(false); - file_cache_entry_e->set_is_dirty(false); - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_e)); - const base::FilePath file_path_e = GetCacheFilePath(id_e); - - // Entry F: there is a file, but metadata says not. - const std::string id_f = "id_f"; - ResourceEntry entry_f; - entry_f.set_local_id(id_f); - entry_f.mutable_file_specific_info()->mutable_cache_state()->set_is_present( - false); - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_f)); - const base::FilePath file_path_f = GetCacheFilePath(id_f); - ASSERT_TRUE(base::CopyFile(temp_file, file_path_f)); - - // Entry G: no file nor metadata. - const std::string id_g = "id_g"; - ResourceEntry entry_g; - entry_g.set_local_id(id_g); - entry_f.mutable_file_specific_info()->mutable_cache_state()->set_is_present( - false); - ASSERT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry_f)); - - // Initialize fixes inconsistency between metadata and cache file attributes - // as well as adding specific file attributes to the cache directory. - ASSERT_TRUE(cache_->Initialize()); - - // Check result. - EXPECT_FALSE(IsMarkedAsRemovable(file_path_a)); - EXPECT_FALSE(IsMarkedAsRemovable(file_path_b)); - EXPECT_TRUE(IsMarkedAsRemovable(file_path_c)); - EXPECT_FALSE(IsMarkedAsRemovable(file_path_d)); - EXPECT_FALSE(base::PathExists(file_path_f)); - - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_e, &entry_e)); - EXPECT_FALSE(entry_e.file_specific_info().cache_state().is_present()); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->GetEntry(id_f, &entry_f)); - EXPECT_FALSE(entry_f.file_specific_info().cache_state().is_present()); - - // Check the cache dir has appropriate attributes. - EXPECT_TRUE(HasRemovableFlag(cache_files_dir_)); - EXPECT_GE(getxattr(cache_files_dir_.value().c_str(), - FileCache::kGCacheFilesAttribute, nullptr, 0), 0); -} - -TEST_F(FileCacheTest, ClearAll) { - const std::string id("1a2b"); - const std::string md5("abcdef0123456789"); - - // Store an existing file. - ResourceEntry entry; - entry.set_local_id(id); - EXPECT_EQ(FILE_ERROR_OK, metadata_storage_->PutEntry(entry)); - base::FilePath src_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &src_file)); - ASSERT_EQ(FILE_ERROR_OK, - cache_->Store(id, md5, src_file, FileCache::FILE_OPERATION_COPY)); - - // Clear cache. - EXPECT_TRUE(cache_->ClearAll()); - - // Verify that the cache is removed. - EXPECT_TRUE(base::IsDirectoryEmpty(cache_files_dir_)); -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/chromeos/file_system_interface.cc b/components/drive/chromeos/file_system_interface.cc deleted file mode 100644 index 242538a..0000000 --- a/components/drive/chromeos/file_system_interface.cc +++ /dev/null
@@ -1,23 +0,0 @@ -// Copyright 2015 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/drive/chromeos/file_system_interface.h" - -namespace drive { - -MetadataSearchResult::MetadataSearchResult( - const base::FilePath& path, - bool is_directory, - const std::string& highlighted_base_name, - const std::string& md5) - : path(path), - is_directory(is_directory), - highlighted_base_name(highlighted_base_name), - md5(md5) { -} - -MetadataSearchResult::MetadataSearchResult(const MetadataSearchResult& other) = - default; - -} // namespace drive
diff --git a/components/drive/chromeos/file_system_interface.h b/components/drive/chromeos/file_system_interface.h deleted file mode 100644 index 30976c6..0000000 --- a/components/drive/chromeos/file_system_interface.h +++ /dev/null
@@ -1,500 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_INTERFACE_H_ -#define COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_INTERFACE_H_ - -#include <stdint.h> - -#include <map> -#include <memory> -#include <set> -#include <string> -#include <vector> - -#include "components/drive/chromeos/resource_metadata.h" -#include "components/drive/drive.pb.h" -#include "components/drive/file_system_metadata.h" -#include "google_apis/drive/base_requests.h" -#include "google_apis/drive/drive_api_requests.h" - -namespace drive { - -class FileSystemObserver; - -// Information about search result returned by Search Async callback. -// This is data needed to create a file system entry that will be used by file -// browser. -struct SearchResultInfo { - SearchResultInfo(const base::FilePath& path, bool is_directory) - : path(path), is_directory(is_directory) {} - - base::FilePath path; - bool is_directory; -}; - -// File path and its MD5 hash obtained from drive API. -struct HashAndFilePath { - std::string hash; - base::FilePath path; -}; - -// Specifies the order in which SearchMetadata() results are sorted. -enum class MetadataSearchOrder { - // Most recently accessed file comes first. - LAST_ACCESSED = 0, - - // Most recently modified file comes first. - LAST_MODIFIED = 1, -}; - -// Struct to represent a search result for SearchMetadata(). -struct MetadataSearchResult { - MetadataSearchResult(const base::FilePath& path, - bool is_directory, - const std::string& highlighted_base_name, - const std::string& md5); - MetadataSearchResult(const MetadataSearchResult& other); - - // The two members are used to create FileEntry object. - base::FilePath path; - bool is_directory; - - // The base name to be displayed in the UI. The parts matched the search - // query are highlighted with <b> tag. Meta characters are escaped like < - // - // Why HTML? we could instead provide matched ranges using pairs of - // integers, but this is fragile as we'll eventually converting strings - // from UTF-8 (StringValue in base/values.h uses std::string) to UTF-16 - // when sending strings from C++ to JavaScript. - // - // Why <b> instead of <strong>? Because <b> is shorter. - std::string highlighted_base_name; - - // MD5 hash of the file. - std::string md5; -}; - -typedef std::vector<MetadataSearchResult> MetadataSearchResultVector; - -// Used to get a resource entry from the file system. -// If |error| is not FILE_ERROR_OK, |entry_info| is set to NULL. -typedef base::OnceCallback<void(FileError error, - std::unique_ptr<ResourceEntry> entry)> - GetResourceEntryCallback; - -// Used to get files from the file system. -typedef base::OnceCallback<void(FileError error, - const base::FilePath& file_path, - std::unique_ptr<ResourceEntry> entry)> - GetFileCallback; - -// Used to get file content from the file system. -// If the file content is available in local cache, |local_file| is filled with -// the path to the cache file. If the file content starts to be downloaded from -// the server, |local_file| is empty. -typedef base::OnceCallback<void(FileError error, - const base::FilePath& local_file, - std::unique_ptr<ResourceEntry> entry)> - GetFileContentInitializedCallback; - -// Used to get list of entries under a directory. -typedef base::OnceCallback<void(std::unique_ptr<ResourceEntryVector> entries)> - ReadDirectoryEntriesCallback; - -// Used to get drive content search results. -// If |error| is not FILE_ERROR_OK, |result_paths| is empty. -typedef base::OnceCallback<void( - FileError error, - const GURL& next_link, - std::unique_ptr<std::vector<SearchResultInfo>> result_paths)> - SearchCallback; - -// Callback for SearchMetadata(). On success, |error| is FILE_ERROR_OK, and -// |result| contains the search result. -typedef base::OnceCallback< - void(FileError error, std::unique_ptr<MetadataSearchResultVector> result)> - SearchMetadataCallback; - -// Callback for SearchByHashesCallback. On success, vector contains hash and -// corresponding files. The vector can include multiple entries for one hash. -typedef base::OnceCallback<void(FileError, const std::vector<HashAndFilePath>&)> - SearchByHashesCallback; - -// Used to open files from the file system. |file_path| is the path on the local -// file system for the opened file. -// If |close_callback| is not null, it must be called when the -// modification to the cache is done. Otherwise, Drive file system does not -// pick up the file for uploading. -// |close_callback| must not be called more than once. -typedef base::OnceCallback<void(FileError error, - const base::FilePath& file_path, - const base::RepeatingClosure& close_callback)> - OpenFileCallback; - -// Used to get available space for the account from Drive. -typedef base::OnceCallback< - void(FileError error, int64_t bytes_total, int64_t bytes_used)> - GetAvailableSpaceCallback; - -// Used to get filesystem metadata. -typedef base::OnceCallback<void( - const FileSystemMetadata&, - const std::map<std::string, FileSystemMetadata>&)> - GetFilesystemMetadataCallback; - -// Used to mark cached files mounted. -typedef base::OnceCallback<void(FileError error, - const base::FilePath& file_path)> - MarkMountedCallback; - -// Used to check if a cached file is mounted. -typedef base::OnceCallback<void(FileError error, bool is_mounted)> - IsMountedCallback; - -// Used to get file path. -typedef base::Callback<void(FileError error, const base::FilePath& file_path)> - GetFilePathCallback; - -// Used to free space. -typedef base::Callback<void(bool)> FreeDiskSpaceCallback; - -// Used for returning result of calculated cache size. -typedef base::Callback<void(int64_t)> CacheSizeCallback; - -// The mode of opening a file. -enum OpenMode { - // Open the file if exists. If not, failed. - OPEN_FILE, - - // Create a new file if not exists, and then open it. If exists, failed. - CREATE_FILE, - - // Open the file if exists. If not, create a new file and then open it. - OPEN_OR_CREATE_FILE, -}; - -// Option enum to control eligible entries for SearchMetadata(). -// SEARCH_METADATA_ALL is the default to investigate all the entries. -// SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS excludes the hosted documents. -// SEARCH_METADATA_EXCLUDE_DIRECTORIES excludes the directories from the result. -// SEARCH_METADATA_SHARED_WITH_ME targets only "shared-with-me" entries. -// SEARCH_METADATA_OFFLINE targets only "offline" entries. This option can not -// be used with other options. -enum SearchMetadataOptions { - SEARCH_METADATA_ALL = 0, - SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS = 1, - SEARCH_METADATA_EXCLUDE_DIRECTORIES = 1 << 1, - SEARCH_METADATA_SHARED_WITH_ME = 1 << 2, - SEARCH_METADATA_OFFLINE = 1 << 3, -}; - -// Drive file system abstraction layer. -// The interface is defined to make FileSystem mockable. -class FileSystemInterface { - public: - virtual ~FileSystemInterface() = default; - - // Adds and removes the observer. - virtual void AddObserver(FileSystemObserver* observer) = 0; - virtual void RemoveObserver(FileSystemObserver* observer) = 0; - - // Checks for updates on the server, in response to a timer expiring - most - // likely when we are not connected to push notifications. - virtual void CheckForUpdates() = 0; - - // Check for updates on the server, for the given ids. The ids are either - // team drive ids, or an empty string for the users default corpus. - virtual void CheckForUpdates(const std::set<std::string>& ids) = 0; - - // Initiates transfer of |local_src_file_path| to |remote_dest_file_path|. - // |local_src_file_path| must be a file from the local file system. - // |remote_dest_file_path| is the virtual destination path within Drive file - // system. - // - // |callback| must not be null. - virtual void TransferFileFromLocalToRemote( - const base::FilePath& local_src_file_path, - const base::FilePath& remote_dest_file_path, - const FileOperationCallback& callback) = 0; - - // Retrieves a file at the virtual path |file_path| on the Drive file system - // onto the cache, and mark it dirty. The local path to the cache file is - // returned to |callback|. After opening the file, both read and write - // on the file can be done with normal local file operations. - // If |mime_type| is set and the file is newly created, the mime type is - // set to the specified value. If |mime_type| is empty, it is guessed from - // |file_path|. - // - // |callback| must not be null. - virtual void OpenFile(const base::FilePath& file_path, - OpenMode open_mode, - const std::string& mime_type, - OpenFileCallback callback) = 0; - - // Copies |src_file_path| to |dest_file_path| on the file system. - // |src_file_path| can be a hosted document (see limitations below). - // |dest_file_path| is expected to be of the same type of |src_file_path| - // (i.e. if |src_file_path| is a file, |dest_file_path| will be created as - // a file). - // If |preserve_last_modified| is set to true, the last modified time will be - // preserved. This feature is only supported on Drive API v2 protocol because - // GData WAPI doesn't support updating modification time. - // - // This method also has the following assumptions/limitations that may be - // relaxed or addressed later: - // - |src_file_path| cannot be a regular file (i.e. non-hosted document) - // or a directory. - // - |dest_file_path| must not exist. - // - The parent of |dest_file_path| must already exist. - // - // The file entries represented by |src_file_path| and the parent directory - // of |dest_file_path| need to be present in the in-memory representation - // of the file system. - // - // |callback| must not be null. - virtual void Copy(const base::FilePath& src_file_path, - const base::FilePath& dest_file_path, - bool preserve_last_modified, - const FileOperationCallback& callback) = 0; - - // Moves |src_file_path| to |dest_file_path| on the file system. - // |src_file_path| can be a file (regular or hosted document) or a directory. - // |dest_file_path| is expected to be of the same type of |src_file_path| - // (i.e. if |src_file_path| is a file, |dest_file_path| will be created as - // a file). - // - // This method also has the following assumptions/limitations that may be - // relaxed or addressed later: - // - |dest_file_path| must not exist. - // - The parent of |dest_file_path| must already exist. - // - // The file entries represented by |src_file_path| and the parent directory - // of |dest_file_path| need to be present in the in-memory representation - // of the file system. - // - // |callback| must not be null. - virtual void Move(const base::FilePath& src_file_path, - const base::FilePath& dest_file_path, - const FileOperationCallback& callback) = 0; - - // Removes |file_path| from the file system. If |is_recursive| is set and - // |file_path| represents a directory, we will also delete all of its - // contained children elements. The file entry represented by |file_path| - // needs to be present in in-memory representation of the file system that - // in order to be removed. - // - // |callback| must not be null. - virtual void Remove(const base::FilePath& file_path, - bool is_recursive, - const FileOperationCallback& callback) = 0; - - // Creates new directory under |directory_path|. If |is_exclusive| is true, - // an error is raised in case a directory is already present at the - // |directory_path|. If |is_recursive| is true, the call creates parent - // directories as needed just like mkdir -p does. - // - // |callback| must not be null. - virtual void CreateDirectory(const base::FilePath& directory_path, - bool is_exclusive, - bool is_recursive, - const FileOperationCallback& callback) = 0; - - // Creates a file at |file_path|. If the flag |is_exclusive| is true, an - // error is raised when a file already exists at the path. It is - // an error if a directory or a hosted document is already present at the - // path, or the parent directory of the path is not present yet. - // If |mime_type| is set and the file is newly created, the mime type is - // set to the specified value. If |mime_type| is empty, it is guessed from - // |file_path|. - // - // |callback| must not be null. - virtual void CreateFile(const base::FilePath& file_path, - bool is_exclusive, - const std::string& mime_type, - const FileOperationCallback& callback) = 0; - - // Touches the file at |file_path| by updating the timestamp to - // |last_access_time| and |last_modified_time|. - // Upon completion, invokes |callback|. - // Note that, differently from unix touch command, this doesn't create a file - // if the target file doesn't exist. - // - // |last_access_time|, |last_modified_time| and |callback| must not be null. - virtual void TouchFile(const base::FilePath& file_path, - const base::Time& last_access_time, - const base::Time& last_modified_time, - const FileOperationCallback& callback) = 0; - - // Truncates the file content at |file_path| to the |length|. - // - // |callback| must not be null. - virtual void TruncateFile(const base::FilePath& file_path, - int64_t length, - const FileOperationCallback& callback) = 0; - - // Pins a file at |file_path|. - // - // |callback| must not be null. - virtual void Pin(const base::FilePath& file_path, - const FileOperationCallback& callback) = 0; - - // Unpins a file at |file_path|. - // - // |callback| must not be null. - virtual void Unpin(const base::FilePath& file_path, - const FileOperationCallback& callback) = 0; - - // Makes sure that |file_path| in the file system is available in the local - // cache. If the file is not cached, the file will be downloaded. The entry - // needs to be present in the file system. - // - // Returns the cache path and entry info to |callback|. It must not be null. - virtual void GetFile(const base::FilePath& file_path, - GetFileCallback callback) = 0; - - // Makes sure that |file_path| in the file system is available in the local - // cache, and mark it as dirty. The next modification to the cache file is - // watched and is automatically uploaded to the server. If the entry is not - // present in the file system, it is created. - // - // Returns the cache path and entry info to |callback|. It must not be null. - virtual void GetFileForSaving(const base::FilePath& file_path, - GetFileCallback callback) = 0; - - // Gets a file by the given |file_path| and returns a closure to cancel the - // task. - // Calls |initialized_callback| when either: - // 1) The cached file (or JSON file for hosted file) is found, or - // 2) Starting to download the file from drive server. - // In case of 2), the given FilePath is empty, and |get_content_callback| is - // called repeatedly with downloaded content following the - // |initialized_callback| invocation. - // |completion_callback| is invoked if an error is found, or the operation - // is successfully done. - // |initialized_callback|, |get_content_callback| and |completion_callback| - // must not be null. - virtual base::Closure GetFileContent( - const base::FilePath& file_path, - GetFileContentInitializedCallback initialized_callback, - const google_apis::GetContentCallback& get_content_callback, - const FileOperationCallback& completion_callback) = 0; - - // Finds an entry (a file or a directory) by |file_path|. This call will also - // retrieve and refresh file system content from server and disk cache. - // - // |callback| must not be null. - virtual void GetResourceEntry(const base::FilePath& file_path, - GetResourceEntryCallback callback) = 0; - - // Finds and reads a directory by |file_path|. This call will also retrieve - // and refresh file system content from server and disk cache. - // |entries_callback| can be a null callback when not interested in entries. - // - // |completion_callback| must not be null. - virtual void ReadDirectory( - const base::FilePath& file_path, - ReadDirectoryEntriesCallback entries_callback, - const FileOperationCallback& completion_callback) = 0; - - // Does server side content search for |search_query|. - // If |next_link| is set, this is the search result url that will be - // fetched. Search results will be returned as a list of results' - // |SearchResultInfo| structs, which contains file's path and is_directory - // flag. - // - // |callback| must not be null. - virtual void Search(const std::string& search_query, - const GURL& next_link, - SearchCallback callback) = 0; - - // Searches the local resource metadata, and returns the entries - // |at_most_num_matches| that contain |query| in their base names. Search is - // done in a case-insensitive fashion. The eligible entries are selected based - // on the given |options|, which is a bit-wise OR of SearchMetadataOptions. - // SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS will be automatically added based - // on the preference. |callback| must not be null. Must be called on UI - // thread. Empty |query| matches any base name. i.e. returns everything. - virtual void SearchMetadata(const std::string& query, - int options, - int at_most_num_matches, - MetadataSearchOrder order, - SearchMetadataCallback callback) = 0; - - // Searches the local resource metadata, and returns the entries that have the - // given |hashes|. The list of resource entries are passed to |callback|. The - // item of the list can be null if the corresponding file is not found. - // |callback| must not be null. - virtual void SearchByHashes(const std::set<std::string>& hashes, - SearchByHashesCallback callback) = 0; - - // Fetches the user's Account Metadata to find out current quota information - // and returns it to the callback. - virtual void GetAvailableSpace(GetAvailableSpaceCallback callback) = 0; - - // Returns miscellaneous metadata of the file system like the largest - // timestamp. Used in chrome:drive-internals. |callback| must not be null. - virtual void GetMetadata(GetFilesystemMetadataCallback callback) = 0; - - // Marks the cached file as mounted, and runs |callback| upon completion. - // If succeeded, the cached file path will be passed to the |callback|. - // |callback| must not be null. - virtual void MarkCacheFileAsMounted(const base::FilePath& drive_file_path, - MarkMountedCallback callback) = 0; - - // Checks if the cached file is marked as mounted, and passes the result to - // |callback| upon completion. If the file was not found in the cache, the - // result is false. |callback| must not be null. - virtual void IsCacheFileMarkedAsMounted(const base::FilePath& drive_file_path, - IsMountedCallback callback) = 0; - - // Marks the cached file as unmounted, and runs |callback| upon completion. - // Note that this method expects that the |cached_file_path| is the path - // returned by MarkCacheFileAsMounted(). - // |callback| must not be null. - virtual void MarkCacheFileAsUnmounted( - const base::FilePath& cache_file_path, - const FileOperationCallback& callback) = 0; - - // Adds permission as |role| to |email| for the entry at |drive_file_path|. - // |callback| must not be null. - virtual void AddPermission(const base::FilePath& drive_file_path, - const std::string& email, - google_apis::drive::PermissionRole role, - const FileOperationCallback& callback) = 0; - - // Sets the |key| property on the file or directory at |drive_file_path| with - // the specified |visibility|. If already exists, then it will be overwritten. - virtual void SetProperty(const base::FilePath& drive_file_path, - google_apis::drive::Property::Visibility visibility, - const std::string& key, - const std::string& value, - const FileOperationCallback& callback) = 0; - - // Resets local data. - virtual void Reset(const FileOperationCallback& callback) = 0; - - // Finds a path of an entry (a file or a directory) by |resource_id|. - virtual void GetPathFromResourceId(const std::string& resource_id, - const GetFilePathCallback& callback) = 0; - - // Free drive caches if needed to secure given available spaces. |callback| - // takes whether given bytes are available or not. - virtual void FreeDiskSpaceIfNeededFor( - int64_t num_bytes, - const FreeDiskSpaceCallback& callback) = 0; - - // Calculates total cache size. - // |callback| must not be null. - virtual void CalculateCacheSize(const CacheSizeCallback& callback) = 0; - - // Calculates evictable cache size. - // |callback| must not be null. - virtual void CalculateEvictableCacheSize( - const CacheSizeCallback& callback) = 0; -}; - -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_INTERFACE_H_
diff --git a/components/drive/chromeos/file_system_observer.h b/components/drive/chromeos/file_system_observer.h deleted file mode 100644 index 90a5bfe..0000000 --- a/components/drive/chromeos/file_system_observer.h +++ /dev/null
@@ -1,52 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_OBSERVER_H_ -#define COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_OBSERVER_H_ - -#include <set> -#include <string> - -#include "components/drive/chromeos/file_system/operation_delegate.h" -#include "components/drive/file_errors.h" - -namespace base { -class FilePath; -} - -namespace drive { - -class FileChange; - -// Interface for classes that need to observe events from classes implementing -// FileSystemInterface. -// All events are notified on UI thread. -class FileSystemObserver { - public: - // Triggered when a content of a directory has been changed. - // |directory_path| is a virtual directory path (/drive/...) representing - // changed directory. - virtual void OnDirectoryChanged(const base::FilePath& directory_path) {} - virtual void OnFileChanged(const FileChange& file_change) {} - - // Triggered when a specific drive error occurred. - // |type| is a type of the error. |file_name| is a virtual path of the entry. - virtual void OnDriveSyncError(file_system::DriveSyncErrorType type, - const base::FilePath& file_path) {} - - // Triggered when the list of team drives that the user has access to - // changes. On first load all team drives will be passed via - // |added_team_drive_ids|, subsequent calls will just be the delta additions - // and removals. - virtual void OnTeamDrivesUpdated( - const std::set<std::string>& added_team_drive_ids, - const std::set<std::string>& removed_team_drive_ids) {} - - protected: - virtual ~FileSystemObserver() = default; -}; - -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_FILE_SYSTEM_OBSERVER_H_
diff --git a/components/drive/chromeos/remove_stale_cache_files.cc b/components/drive/chromeos/remove_stale_cache_files.cc deleted file mode 100644 index 082d7a2..0000000 --- a/components/drive/chromeos/remove_stale_cache_files.cc +++ /dev/null
@@ -1,35 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/chromeos/remove_stale_cache_files.h" - -#include "base/logging.h" -#include "components/drive/chromeos/file_cache.h" -#include "components/drive/chromeos/resource_metadata.h" -#include "components/drive/drive.pb.h" - -namespace drive { -namespace internal { - -void RemoveStaleCacheFiles(FileCache* cache, - ResourceMetadata* resource_metadata) { - std::unique_ptr<ResourceMetadata::Iterator> it = - resource_metadata->GetIterator(); - for (; !it->IsAtEnd(); it->Advance()) { - const ResourceEntry& entry = it->GetValue(); - const FileCacheEntry& cache_state = - entry.file_specific_info().cache_state(); - // Stale = not dirty but the MD5 does not match. - if (!cache_state.is_dirty() && - cache_state.md5() != entry.file_specific_info().md5()) { - FileError error = cache->Remove(it->GetID()); - LOG_IF(WARNING, error != FILE_ERROR_OK) - << "Failed to remove a stale cache file. resource_id: " - << it->GetID(); - } - } -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/chromeos/remove_stale_cache_files.h b/components/drive/chromeos/remove_stale_cache_files.h deleted file mode 100644 index c7cf9bb..0000000 --- a/components/drive/chromeos/remove_stale_cache_files.h +++ /dev/null
@@ -1,22 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_CHROMEOS_REMOVE_STALE_CACHE_FILES_H_ -#define COMPONENTS_DRIVE_CHROMEOS_REMOVE_STALE_CACHE_FILES_H_ - -namespace drive{ -namespace internal { - -class FileCache; -class ResourceMetadata; - -// Removes files from |cache| which are not dirty but the MD5 is obsolete. -// Must be run on the same task runner as |cache| and |resource_metadata| use. -void RemoveStaleCacheFiles(FileCache* cache, - ResourceMetadata* resource_metadata); - -} // namespace internal -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_REMOVE_STALE_CACHE_FILES_H_
diff --git a/components/drive/chromeos/resource_metadata.cc b/components/drive/chromeos/resource_metadata.cc deleted file mode 100644 index 1bea02a..0000000 --- a/components/drive/chromeos/resource_metadata.cc +++ /dev/null
@@ -1,645 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/chromeos/resource_metadata.h" - -#include <limits.h> -#include <stddef.h> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/guid.h" -#include "base/location.h" -#include "base/rand_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "base/system/sys_info.h" -#include "components/drive/chromeos/file_cache.h" -#include "components/drive/drive.pb.h" -#include "components/drive/file_system_core_util.h" -#include "components/drive/resource_metadata_storage.h" - -namespace drive { -namespace internal { -namespace { - -// Returns true if enough disk space is available for DB operation. -// TODO(hashimoto): Merge this with FileCache's FreeDiskSpaceGetterInterface. -bool EnoughDiskSpaceIsAvailableForDBOperation(const base::FilePath& path) { - const int64_t kRequiredDiskSpaceInMB = - 128; // 128 MB seems to be large enough. - return base::SysInfo::AmountOfFreeDiskSpace(path) >= - kRequiredDiskSpaceInMB * (1 << 20); -} - -// Returns a file name with a uniquifier appended. (e.g. "File (1).txt") -std::string GetUniquifiedName(const std::string& name, int uniquifier) { - base::FilePath name_path = base::FilePath::FromUTF8Unsafe(name); - name_path = name_path.InsertBeforeExtensionASCII( - base::StringPrintf(" (%d)", uniquifier)); - return name_path.AsUTF8Unsafe(); -} - -// Returns true when there is no entry with the specified name under the parent -// other than the specified entry. -FileError EntryCanUseName(ResourceMetadataStorage* storage, - const std::string& parent_local_id, - const std::string& local_id, - const std::string& base_name, - bool* result) { - std::string existing_entry_id; - FileError error = storage->GetChild(parent_local_id, base_name, - &existing_entry_id); - if (error == FILE_ERROR_OK) - *result = existing_entry_id == local_id; - else if (error == FILE_ERROR_NOT_FOUND) - *result = true; - else - return error; - return FILE_ERROR_OK; -} - -// Returns true when the ID is used by an immutable entry. -bool IsImmutableEntry(const std::string& id) { - return id == util::kDriveGrandRootLocalId || - id == util::kDriveOtherDirLocalId || - id == util::kDriveTrashDirLocalId; -} - -} // namespace - -ResourceMetadata::ResourceMetadata( - ResourceMetadataStorage* storage, - FileCache* cache, - scoped_refptr<base::SequencedTaskRunner> blocking_task_runner) - : blocking_task_runner_(blocking_task_runner), - storage_(storage), - cache_(cache) { -} - -FileError ResourceMetadata::Initialize() { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - return SetUpDefaultEntries(); -} - -void ResourceMetadata::Destroy() { - DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); - - blocking_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&ResourceMetadata::DestroyOnBlockingPool, - base::Unretained(this))); -} - -FileError ResourceMetadata::Reset() { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - - if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path())) - return FILE_ERROR_NO_LOCAL_SPACE; - - FileError error = storage_->SetLargestChangestamp(0); - if (error != FILE_ERROR_OK) - return error; - - error = storage_->SetStartPageToken(std::string()); - if (error != FILE_ERROR_OK) - return error; - - // Remove all root entries. - std::unique_ptr<Iterator> it = GetIterator(); - for (; !it->IsAtEnd(); it->Advance()) { - if (it->GetValue().parent_local_id().empty()) { - error = RemoveEntryRecursively(it->GetID()); - if (error != FILE_ERROR_OK) - return error; - } - } - if (it->HasError()) - return FILE_ERROR_FAILED; - - return SetUpDefaultEntries(); -} - -ResourceMetadata::~ResourceMetadata() { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); -} - -FileError ResourceMetadata::SetUpDefaultEntries() { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - - // Initialize "/drive". - ResourceEntry entry; - FileError error = storage_->GetEntry(util::kDriveGrandRootLocalId, &entry); - if (error == FILE_ERROR_NOT_FOUND) { - ResourceEntry root; - root.mutable_file_info()->set_is_directory(true); - root.set_local_id(util::kDriveGrandRootLocalId); - root.set_title(util::kDriveGrandRootDirName); - root.set_base_name(util::kDriveGrandRootDirName); - error = storage_->PutEntry(root); - if (error != FILE_ERROR_OK) - return error; - } else if (error == FILE_ERROR_OK) { - if (!entry.resource_id().empty()) { - // Old implementations used kDriveGrandRootLocalId as a resource ID. - entry.clear_resource_id(); - error = storage_->PutEntry(entry); - if (error != FILE_ERROR_OK) - return error; - } - } else { - return error; - } - - // Initialize "/drive/other". - error = storage_->GetEntry(util::kDriveOtherDirLocalId, &entry); - if (error == FILE_ERROR_NOT_FOUND) { - ResourceEntry other_dir; - other_dir.mutable_file_info()->set_is_directory(true); - other_dir.set_local_id(util::kDriveOtherDirLocalId); - other_dir.set_parent_local_id(util::kDriveGrandRootLocalId); - other_dir.set_title(util::kDriveOtherDirName); - error = PutEntryUnderDirectory(other_dir); - if (error != FILE_ERROR_OK) - return error; - } else if (error == FILE_ERROR_OK) { - if (!entry.resource_id().empty()) { - // Old implementations used kDriveOtherDirLocalId as a resource ID. - entry.clear_resource_id(); - error = storage_->PutEntry(entry); - if (error != FILE_ERROR_OK) - return error; - } - } else { - return error; - } - - // Initialize "drive/trash". - error = storage_->GetEntry(util::kDriveTrashDirLocalId, &entry); - if (error == FILE_ERROR_NOT_FOUND) { - ResourceEntry trash_dir; - trash_dir.mutable_file_info()->set_is_directory(true); - trash_dir.set_local_id(util::kDriveTrashDirLocalId); - trash_dir.set_parent_local_id(util::kDriveGrandRootLocalId); - trash_dir.set_title(util::kDriveTrashDirName); - error = PutEntryUnderDirectory(trash_dir); - if (error != FILE_ERROR_OK) - return error; - } else if (error != FILE_ERROR_OK) { - return error; - } - - // Initialize "drive/root". - std::string child_id; - error = storage_->GetChild( - util::kDriveGrandRootLocalId, util::kDriveMyDriveRootDirName, &child_id); - if (error == FILE_ERROR_NOT_FOUND) { - ResourceEntry mydrive; - mydrive.mutable_file_info()->set_is_directory(true); - mydrive.set_parent_local_id(util::kDriveGrandRootLocalId); - mydrive.set_title(util::kDriveMyDriveRootDirName); - - std::string local_id; - error = AddEntry(mydrive, &local_id); - if (error != FILE_ERROR_OK) - return error; - } else if (error != FILE_ERROR_OK) { - return error; - } - - // Initialize "/drive/team_drives". - error = storage_->GetEntry(util::kDriveTeamDrivesDirLocalId, &entry); - if (error == FILE_ERROR_NOT_FOUND) { - ResourceEntry team_drives_dir; - team_drives_dir.mutable_file_info()->set_is_directory(true); - team_drives_dir.set_local_id(util::kDriveTeamDrivesDirLocalId); - team_drives_dir.set_parent_local_id(util::kDriveGrandRootLocalId); - team_drives_dir.set_title(util::kDriveTeamDrivesDirName); - error = PutEntryUnderDirectory(team_drives_dir); - if (error != FILE_ERROR_OK) - return error; - } else if (error != FILE_ERROR_OK) { - return error; - } - - // Initialize "/drive/Computers". - error = storage_->GetEntry(util::kDriveComputersDirLocalId, &entry); - if (error == FILE_ERROR_NOT_FOUND) { - ResourceEntry computers_dir; - computers_dir.mutable_file_info()->set_is_directory(true); - computers_dir.set_local_id(util::kDriveComputersDirLocalId); - computers_dir.set_parent_local_id(util::kDriveGrandRootLocalId); - computers_dir.set_title(util::kDriveComputersDirName); - error = PutEntryUnderDirectory(computers_dir); - if (error != FILE_ERROR_OK) - return error; - } else if (error != FILE_ERROR_OK) { - return error; - } - - return FILE_ERROR_OK; -} - -void ResourceMetadata::DestroyOnBlockingPool() { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - delete this; -} - -FileError ResourceMetadata::GetStartPageToken(std::string* out_value) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - return storage_->GetStartPageToken(out_value); -} - -FileError ResourceMetadata::SetStartPageToken(const std::string& value) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - - if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path())) - return FILE_ERROR_NO_LOCAL_SPACE; - - return storage_->SetStartPageToken(value); -} - -FileError ResourceMetadata::AddEntry(const ResourceEntry& entry, - std::string* out_id) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(entry.local_id().empty()); - - if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path())) - return FILE_ERROR_NO_LOCAL_SPACE; - - ResourceEntry parent; - FileError error = storage_->GetEntry(entry.parent_local_id(), &parent); - if (error != FILE_ERROR_OK) - return error; - if (!parent.file_info().is_directory()) - return FILE_ERROR_NOT_A_DIRECTORY; - - // Multiple entries with the same resource ID should not be present. - std::string local_id; - ResourceEntry existing_entry; - if (!entry.resource_id().empty()) { - error = storage_->GetIdByResourceId(entry.resource_id(), &local_id); - if (error == FILE_ERROR_OK) - error = storage_->GetEntry(local_id, &existing_entry); - - if (error == FILE_ERROR_OK) - return FILE_ERROR_EXISTS; - if (error != FILE_ERROR_NOT_FOUND) - return error; - } - - // Generate unique local ID when needed. - // We don't check for ID collisions as its probability is extremely low. - if (local_id.empty()) - local_id = base::GenerateGUID(); - - ResourceEntry new_entry(entry); - new_entry.set_local_id(local_id); - - error = PutEntryUnderDirectory(new_entry); - if (error != FILE_ERROR_OK) - return error; - - *out_id = local_id; - return FILE_ERROR_OK; -} - -FileError ResourceMetadata::RemoveEntry(const std::string& id) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - - if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path())) - return FILE_ERROR_NO_LOCAL_SPACE; - - // Disallow deletion of default entries. - if (IsImmutableEntry(id)) - return FILE_ERROR_ACCESS_DENIED; - - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - - return RemoveEntryRecursively(id); -} - -FileError ResourceMetadata::GetResourceEntryById(const std::string& id, - ResourceEntry* out_entry) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(!id.empty()); - DCHECK(out_entry); - - return storage_->GetEntry(id, out_entry); -} - -FileError ResourceMetadata::GetResourceEntryByPath(const base::FilePath& path, - ResourceEntry* out_entry) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(out_entry); - - std::string id; - FileError error = GetIdByPath(path, &id); - if (error != FILE_ERROR_OK) - return error; - - return GetResourceEntryById(id, out_entry); -} - -FileError ResourceMetadata::ReadDirectoryByPath( - const base::FilePath& path, - ResourceEntryVector* out_entries) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(out_entries); - - std::string id; - FileError error = GetIdByPath(path, &id); - if (error != FILE_ERROR_OK) - return error; - return ReadDirectoryById(id, out_entries); -} - -FileError ResourceMetadata::ReadDirectoryById( - const std::string& id, - ResourceEntryVector* out_entries) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(out_entries); - - ResourceEntry entry; - FileError error = GetResourceEntryById(id, &entry); - if (error != FILE_ERROR_OK) - return error; - - if (!entry.file_info().is_directory()) - return FILE_ERROR_NOT_A_DIRECTORY; - - std::vector<std::string> children; - error = storage_->GetChildren(id, &children); - if (error != FILE_ERROR_OK) - return error; - - ResourceEntryVector entries(children.size()); - for (size_t i = 0; i < children.size(); ++i) { - error = storage_->GetEntry(children[i], &entries[i]); - if (error != FILE_ERROR_OK) - return error; - } - out_entries->swap(entries); - return FILE_ERROR_OK; -} - -FileError ResourceMetadata::RefreshEntry(const ResourceEntry& entry) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - - if (!EnoughDiskSpaceIsAvailableForDBOperation(storage_->directory_path())) - return FILE_ERROR_NO_LOCAL_SPACE; - - ResourceEntry old_entry; - FileError error = storage_->GetEntry(entry.local_id(), &old_entry); - if (error != FILE_ERROR_OK) - return error; - - if (IsImmutableEntry(entry.local_id()) || - old_entry.file_info().is_directory() != // Reject incompatible input. - entry.file_info().is_directory()) - return FILE_ERROR_INVALID_OPERATION; - - if (!entry.resource_id().empty()) { - // Multiple entries cannot share the same resource ID. - std::string local_id; - FileError error = GetIdByResourceId(entry.resource_id(), &local_id); - switch (error) { - case FILE_ERROR_OK: - if (local_id != entry.local_id()) - return FILE_ERROR_INVALID_OPERATION; - break; - - case FILE_ERROR_NOT_FOUND: - break; - - default: - return error; - } - } - - // Make sure that the new parent exists and it is a directory. - ResourceEntry new_parent; - error = storage_->GetEntry(entry.parent_local_id(), &new_parent); - if (error != FILE_ERROR_OK) - return error; - - if (!new_parent.file_info().is_directory()) - return FILE_ERROR_NOT_A_DIRECTORY; - - // Do not overwrite cache states. - // Cache state should be changed via FileCache. - ResourceEntry updated_entry(entry); - if (old_entry.file_specific_info().has_cache_state()) { - *updated_entry.mutable_file_specific_info()->mutable_cache_state() = - old_entry.file_specific_info().cache_state(); - } else if (updated_entry.file_specific_info().has_cache_state()) { - updated_entry.mutable_file_specific_info()->clear_cache_state(); - } - // Remove from the old parent and add it to the new parent with the new data. - return PutEntryUnderDirectory(updated_entry); -} - -FileError ResourceMetadata::GetSubDirectoriesRecursively( - const std::string& id, - std::set<base::FilePath>* sub_directories) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - - std::vector<std::string> children; - FileError error = storage_->GetChildren(id, &children); - if (error != FILE_ERROR_OK) - return error; - for (size_t i = 0; i < children.size(); ++i) { - ResourceEntry entry; - error = storage_->GetEntry(children[i], &entry); - if (error != FILE_ERROR_OK) - return error; - if (entry.file_info().is_directory()) { - base::FilePath path; - error = GetFilePath(children[i], &path); - if (error != FILE_ERROR_OK) - return error; - sub_directories->insert(path); - GetSubDirectoriesRecursively(children[i], sub_directories); - } - } - return FILE_ERROR_OK; -} - -FileError ResourceMetadata::GetChildId(const std::string& parent_local_id, - const std::string& base_name, - std::string* out_child_id) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - return storage_->GetChild(parent_local_id, base_name, out_child_id); -} - -std::unique_ptr<ResourceMetadata::Iterator> ResourceMetadata::GetIterator() { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - - return storage_->GetIterator(); -} - -FileError ResourceMetadata::GetFilePath(const std::string& id, - base::FilePath* out_file_path) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - - base::FilePath path; - if (!entry.parent_local_id().empty()) { - error = GetFilePath(entry.parent_local_id(), &path); - if (error != FILE_ERROR_OK) - return error; - } else if (entry.local_id() != util::kDriveGrandRootLocalId) { - DVLOG(1) << "Entries not under the grand root don't have paths."; - return FILE_ERROR_NOT_FOUND; - } - path = path.Append(base::FilePath::FromUTF8Unsafe(entry.base_name())); - *out_file_path = path; - return FILE_ERROR_OK; -} - -FileError ResourceMetadata::GetIdByPath(const base::FilePath& file_path, - std::string* out_id) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - - // Start from the root. - std::vector<base::FilePath::StringType> components; - file_path.GetComponents(&components); - if (components.empty() || - components[0] != util::GetDriveGrandRootPath().value()) - return FILE_ERROR_NOT_FOUND; - - // Iterate over the remaining components. - std::string id = util::kDriveGrandRootLocalId; - for (size_t i = 1; i < components.size(); ++i) { - const std::string component = base::FilePath(components[i]).AsUTF8Unsafe(); - std::string child_id; - FileError error = storage_->GetChild(id, component, &child_id); - if (error != FILE_ERROR_OK) - return error; - id = child_id; - } - *out_id = id; - return FILE_ERROR_OK; -} - -FileError ResourceMetadata::GetIdByResourceId(const std::string& resource_id, - std::string* out_local_id) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - return storage_->GetIdByResourceId(resource_id, out_local_id); -} - -FileError ResourceMetadata::PutEntryUnderDirectory(const ResourceEntry& entry) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(!entry.local_id().empty()); - DCHECK(!entry.parent_local_id().empty()); - - std::string base_name; - FileError error = GetDeduplicatedBaseName(entry, &base_name); - if (error != FILE_ERROR_OK) - return error; - ResourceEntry updated_entry(entry); - updated_entry.set_base_name(base_name); - return storage_->PutEntry(updated_entry); -} - -FileError ResourceMetadata::GetDeduplicatedBaseName( - const ResourceEntry& entry, - std::string* base_name) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - DCHECK(!entry.parent_local_id().empty()); - DCHECK(!entry.title().empty()); - - // The entry name may have been changed due to prior name de-duplication. - // We need to first restore the file name based on the title before going - // through name de-duplication again when it is added to another directory. - *base_name = entry.title(); - if (entry.has_file_specific_info() && - entry.file_specific_info().is_hosted_document()) { - *base_name += entry.file_specific_info().document_extension(); - } - *base_name = util::NormalizeFileName(*base_name); - - // If |base_name| is not used, just return it. - bool can_use_name = false; - FileError error = EntryCanUseName(storage_, entry.parent_local_id(), - entry.local_id(), *base_name, - &can_use_name); - if (error != FILE_ERROR_OK || can_use_name) - return error; - - // Find an unused number with binary search. - int smallest_known_unused_modifier = 1; - while (true) { - error = EntryCanUseName(storage_, entry.parent_local_id(), entry.local_id(), - GetUniquifiedName(*base_name, - smallest_known_unused_modifier), - &can_use_name); - if (error != FILE_ERROR_OK) - return error; - if (can_use_name) - break; - - const int delta = base::RandInt(1, smallest_known_unused_modifier); - if (smallest_known_unused_modifier <= INT_MAX - delta) { - smallest_known_unused_modifier += delta; - } else { // No luck finding an unused number. Try again. - smallest_known_unused_modifier = 1; - } - } - - int largest_known_used_modifier = 1; - while (smallest_known_unused_modifier - largest_known_used_modifier > 1) { - const int modifier = largest_known_used_modifier + - (smallest_known_unused_modifier - largest_known_used_modifier) / 2; - - error = EntryCanUseName(storage_, entry.parent_local_id(), entry.local_id(), - GetUniquifiedName(*base_name, modifier), - &can_use_name); - if (error != FILE_ERROR_OK) - return error; - if (can_use_name) { - smallest_known_unused_modifier = modifier; - } else { - largest_known_used_modifier = modifier; - } - } - *base_name = GetUniquifiedName(*base_name, smallest_known_unused_modifier); - return FILE_ERROR_OK; -} - -FileError ResourceMetadata::RemoveEntryRecursively(const std::string& id) { - DCHECK(blocking_task_runner_->RunsTasksInCurrentSequence()); - - ResourceEntry entry; - FileError error = storage_->GetEntry(id, &entry); - if (error != FILE_ERROR_OK) - return error; - - if (entry.file_info().is_directory()) { - std::vector<std::string> children; - error = storage_->GetChildren(id, &children); - if (error != FILE_ERROR_OK) - return error; - for (size_t i = 0; i < children.size(); ++i) { - error = RemoveEntryRecursively(children[i]); - if (error != FILE_ERROR_OK) - return error; - } - } - - error = cache_->Remove(id); - if (error != FILE_ERROR_OK) - return error; - - return storage_->RemoveEntry(id); -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/chromeos/resource_metadata.h b/components/drive/chromeos/resource_metadata.h deleted file mode 100644 index d4d29de..0000000 --- a/components/drive/chromeos/resource_metadata.h +++ /dev/null
@@ -1,151 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_CHROMEOS_RESOURCE_METADATA_H_ -#define COMPONENTS_DRIVE_CHROMEOS_RESOURCE_METADATA_H_ - -#include <stdint.h> - -#include <memory> -#include <set> -#include <string> -#include <vector> - -#include "base/files/file_path.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/sequenced_task_runner.h" -#include "base/threading/thread_checker.h" -#include "components/drive/file_errors.h" -#include "components/drive/resource_metadata_storage.h" - -namespace base { -class SequencedTaskRunner; -} - -namespace drive { - -typedef std::vector<ResourceEntry> ResourceEntryVector; - -namespace internal { - -class FileCache; - -// Storage for Drive Metadata. -// All methods except the constructor and Destroy() function must be run with -// |blocking_task_runner| unless otherwise noted. -class ResourceMetadata { - public: - typedef ResourceMetadataStorage::Iterator Iterator; - - ResourceMetadata( - ResourceMetadataStorage* storage, - FileCache* cache, - scoped_refptr<base::SequencedTaskRunner> blocking_task_runner); - - // Initializes this object. - // This method should be called before any other methods. - FileError Initialize() WARN_UNUSED_RESULT; - - // Destroys this object. This method posts a task to |blocking_task_runner_| - // to safely delete this object. - // Must be called on the UI thread. - void Destroy(); - - // Resets this object. - FileError Reset(); - - // Returns the start page token for the users default corpus. - FileError GetStartPageToken(std::string* out_value); - - // Sets the start page token for the users default corpus. - FileError SetStartPageToken(const std::string& value); - - // Adds |entry| to the metadata tree based on its parent_local_id. - FileError AddEntry(const ResourceEntry& entry, std::string* out_id); - - // Removes entry with |id| from its parent. - FileError RemoveEntry(const std::string& id); - - // Finds an entry (a file or a directory) by |id|. - FileError GetResourceEntryById(const std::string& id, - ResourceEntry* out_entry); - - // Synchronous version of GetResourceEntryByPathOnUIThread(). - FileError GetResourceEntryByPath(const base::FilePath& file_path, - ResourceEntry* out_entry); - - // Finds and reads a directory by |file_path|. - FileError ReadDirectoryByPath(const base::FilePath& file_path, - ResourceEntryVector* out_entries); - - // Finds and reads a directory by |id|. - FileError ReadDirectoryById(const std::string& id, - ResourceEntryVector* out_entries); - - // Replaces an existing entry with the same local ID as |entry|. - FileError RefreshEntry(const ResourceEntry& entry); - - // Recursively gets directories under the entry pointed to by |id|. - FileError GetSubDirectoriesRecursively( - const std::string& id, - std::set<base::FilePath>* sub_directories); - - // Returns the id of the resource named |base_name| directly under - // the directory with |parent_local_id|. - // If not found, empty string will be returned. - FileError GetChildId(const std::string& parent_local_id, - const std::string& base_name, - std::string* out_child_id); - - // Returns an object to iterate over entries. - std::unique_ptr<Iterator> GetIterator(); - - // Returns virtual file path of the entry. - FileError GetFilePath(const std::string& id, base::FilePath* out_file_path); - - // Returns ID of the entry at the given path. - FileError GetIdByPath(const base::FilePath& file_path, std::string* out_id); - - // Returns the local ID associated with the given resource ID. - FileError GetIdByResourceId(const std::string& resource_id, - std::string* out_local_id); - - private: - // Note: Use Destroy() to delete this object. - ~ResourceMetadata(); - - // Sets up entries which should be present by default. - FileError SetUpDefaultEntries(); - - // Used to implement Destroy(). - void DestroyOnBlockingPool(); - - // Puts an entry under its parent directory. Removes the child from the old - // parent if there is. This method will also do name de-duplication to ensure - // that the exposed presentation path does not have naming conflicts. Two - // files with the same name "Foo" will be renamed to "Foo (1)" and "Foo (2)". - FileError PutEntryUnderDirectory(const ResourceEntry& entry); - - // Returns an unused base name for |entry|. - FileError GetDeduplicatedBaseName(const ResourceEntry& entry, - std::string* base_name); - - // Removes the entry and its descendants. - FileError RemoveEntryRecursively(const std::string& id); - - scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; - - ResourceMetadataStorage* storage_; - FileCache* cache_; - - THREAD_CHECKER(thread_checker_); - - DISALLOW_COPY_AND_ASSIGN(ResourceMetadata); -}; - -} // namespace internal -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_RESOURCE_METADATA_H_
diff --git a/components/drive/chromeos/search_metadata.cc b/components/drive/chromeos/search_metadata.cc index 99e9b115..c0584d7 100644 --- a/components/drive/chromeos/search_metadata.cc +++ b/components/drive/chromeos/search_metadata.cc
@@ -5,15 +5,8 @@ #include "components/drive/chromeos/search_metadata.h" #include <algorithm> -#include <map> -#include <queue> -#include <utility> -#include "base/bind.h" #include "base/i18n/string_search.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/string_piece.h" -#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" @@ -26,240 +19,6 @@ namespace { -struct ResultCandidate { - ResultCandidate(const std::string& local_id, - const ResourceEntry& entry, - const std::string& highlighted_base_name) - : local_id(local_id), - entry(entry), - highlighted_base_name(highlighted_base_name) { - } - - std::string local_id; - ResourceEntry entry; - std::string highlighted_base_name; -}; - -// Used to sort the result candidates per the last accessed/modified time. The -// recently accessed/modified files come first. -bool CompareByTimestamp(const ResourceEntry& a, - const ResourceEntry& b, - MetadataSearchOrder order) { - const PlatformFileInfoProto& a_file_info = a.file_info(); - const PlatformFileInfoProto& b_file_info = b.file_info(); - - switch (order) { - case MetadataSearchOrder::LAST_ACCESSED: - if (a_file_info.last_accessed() != b_file_info.last_accessed()) - return a_file_info.last_accessed() > b_file_info.last_accessed(); - - // When the entries have the same last access time (which happens quite - // often because Drive server doesn't set the field until an entry is - /// viewed via drive.google.com), we use last modified time as the tie - // breaker. - return a_file_info.last_modified() > b_file_info.last_modified(); - case MetadataSearchOrder::LAST_MODIFIED: - return a_file_info.last_modified() > b_file_info.last_modified(); - } -} - -struct ResultCandidateComparator { - explicit ResultCandidateComparator(MetadataSearchOrder order) - : order_(order) {} - bool operator()(const std::unique_ptr<ResultCandidate>& a, - const std::unique_ptr<ResultCandidate>& b) const { - return CompareByTimestamp(a->entry, b->entry, order_); - } - - private: - const MetadataSearchOrder order_; -}; - -typedef std::priority_queue<std::unique_ptr<ResultCandidate>, - std::vector<std::unique_ptr<ResultCandidate>>, - ResultCandidateComparator> - ResultCandidateQueue; - -// Classifies the given entry as hidden if it's not under specific directories. -class HiddenEntryClassifier { - public: - HiddenEntryClassifier(ResourceMetadata* metadata, - const std::string& mydrive_local_id) - : metadata_(metadata) { - // Only things under My Drive, drive/other and drive/team_drives are not - // hidden. - is_hiding_child_[mydrive_local_id] = false; - is_hiding_child_[util::kDriveOtherDirLocalId] = false; - is_hiding_child_[util::kDriveTeamDrivesDirLocalId] = false; - - // Everything else is hidden, including the directories mentioned above - // themselves. - is_hiding_child_[""] = true; - } - - // |result| is set to true if |entry| is hidden. - FileError IsHidden(const ResourceEntry& entry, bool* result) { - // Look up for parents recursively. - std::vector<std::string> undetermined_ids; - undetermined_ids.push_back(entry.parent_local_id()); - - std::map<std::string, bool>::iterator it = - is_hiding_child_.find(undetermined_ids.back()); - for (; it == is_hiding_child_.end(); - it = is_hiding_child_.find(undetermined_ids.back())) { - ResourceEntry parent; - FileError error = - metadata_->GetResourceEntryById(undetermined_ids.back(), &parent); - if (error != FILE_ERROR_OK) - return error; - undetermined_ids.push_back(parent.parent_local_id()); - } - - // Cache the result. - undetermined_ids.pop_back(); // The last one is already in the map. - for (size_t i = 0; i < undetermined_ids.size(); ++i) - is_hiding_child_[undetermined_ids[i]] = it->second; - - *result = it->second; - return FILE_ERROR_OK; - } - - private: - ResourceMetadata* metadata_; - - // local ID to is_hidden map. - std::map<std::string, bool> is_hiding_child_; -}; - -// Used to implement SearchMetadata. -// Adds entry to the result when appropriate. -// In particular, if size of |queries| is larger than 0, only adds files with -// the name matching the query. -FileError MaybeAddEntryToResult( - ResourceMetadata* resource_metadata, - ResourceMetadata::Iterator* it, - const std::vector<std::unique_ptr< - base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>>& queries, - const SearchMetadataPredicate& predicate, - size_t at_most_num_matches, - MetadataSearchOrder order, - HiddenEntryClassifier* hidden_entry_classifier, - ResultCandidateQueue* result_candidates) { - DCHECK_GE(at_most_num_matches, result_candidates->size()); - - const ResourceEntry& entry = it->GetValue(); - - // If the candidate set is already full, and this |entry| is old, do nothing. - // We perform this check first in order to avoid the costly find-and-highlight - // or FilePath lookup as much as possible. - if (result_candidates->size() == at_most_num_matches && - !CompareByTimestamp(entry, result_candidates->top()->entry, order)) - return FILE_ERROR_OK; - - // Add |entry| to the result if the entry is eligible for the given - // |options| and matches the query. The base name of the entry must - // contain |query| to match the query. - std::string highlighted; - if (!predicate.Run(entry) || - !FindAndHighlight(entry.base_name(), queries, &highlighted)) - return FILE_ERROR_OK; - - // Hidden entry should not be returned. - bool hidden = false; - FileError error = hidden_entry_classifier->IsHidden(entry, &hidden); - if (error != FILE_ERROR_OK || hidden) - return error; - - // Make space for |entry| when appropriate. - if (result_candidates->size() == at_most_num_matches) - result_candidates->pop(); - result_candidates->push( - std::make_unique<ResultCandidate>(it->GetID(), entry, highlighted)); - return FILE_ERROR_OK; -} - -// Implements SearchMetadata(). -FileError SearchMetadataOnBlockingPool(ResourceMetadata* resource_metadata, - const std::string& query_text, - const SearchMetadataPredicate& predicate, - int at_most_num_matches, - MetadataSearchOrder order, - MetadataSearchResultVector* results) { - ResultCandidateQueue result_candidates((ResultCandidateComparator(order))); - - // Prepare data structure for searching. - std::vector<base::string16> keywords = - base::SplitString(base::UTF8ToUTF16(query_text), - base::StringPiece16(base::kWhitespaceUTF16), - base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY); - - std::vector<std::unique_ptr< - base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>> - queries; - for (const auto& keyword : keywords) { - queries.push_back( - std::make_unique< - base::i18n::FixedPatternStringSearchIgnoringCaseAndAccents>( - keyword)); - } - - // Prepare an object to filter out hidden entries. - ResourceEntry mydrive; - FileError error = resource_metadata->GetResourceEntryByPath( - util::GetDriveMyDriveRootPath(), &mydrive); - if (error != FILE_ERROR_OK) - return error; - HiddenEntryClassifier hidden_entry_classifier(resource_metadata, - mydrive.local_id()); - - // Iterate over entries. - std::unique_ptr<ResourceMetadata::Iterator> it = - resource_metadata->GetIterator(); - for (; !it->IsAtEnd(); it->Advance()) { - FileError error = MaybeAddEntryToResult( - resource_metadata, it.get(), queries, predicate, at_most_num_matches, - order, &hidden_entry_classifier, &result_candidates); - if (error != FILE_ERROR_OK) - return error; - } - - // Prepare the result. - for (; !result_candidates.empty(); result_candidates.pop()) { - const ResultCandidate& candidate = *result_candidates.top(); - // The path field of entries in result_candidates are empty at this point, - // because we don't want to run the expensive metadata DB look up except for - // the final results. Hence, here we fill the part. - base::FilePath path; - error = resource_metadata->GetFilePath(candidate.local_id, &path); - if (error != FILE_ERROR_OK) - return error; - bool is_directory = candidate.entry.file_info().is_directory(); - results->push_back(MetadataSearchResult( - path, is_directory, candidate.highlighted_base_name, - candidate.entry.file_specific_info().md5())); - } - - // Reverse the order here because |result_candidates| puts the most - // uninteresting candidate at the top. - std::reverse(results->begin(), results->end()); - - return FILE_ERROR_OK; -} - -// Runs the SearchMetadataCallback and updates the histogram. -void RunSearchMetadataCallback( - SearchMetadataCallback callback, - const base::TimeTicks& start_time, - std::unique_ptr<MetadataSearchResultVector> results, - FileError error) { - if (error != FILE_ERROR_OK) - results.reset(); - std::move(callback).Run(error, std::move(results)); - - UMA_HISTOGRAM_TIMES("Drive.SearchMetadataTime", - base::TimeTicks::Now() - start_time); -} - // Appends substring of |original_text| to |highlighted_text| with highlight. void AppendStringWithHighlight(const base::string16& original_text, size_t start, @@ -278,57 +37,6 @@ } // namespace -void SearchMetadata( - scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, - ResourceMetadata* resource_metadata, - const std::string& query, - const SearchMetadataPredicate& predicate, - size_t at_most_num_matches, - MetadataSearchOrder order, - SearchMetadataCallback callback) { - DCHECK(callback); - - const base::TimeTicks start_time = base::TimeTicks::Now(); - - std::unique_ptr<MetadataSearchResultVector> results( - new MetadataSearchResultVector); - MetadataSearchResultVector* results_ptr = results.get(); - base::PostTaskAndReplyWithResult( - blocking_task_runner.get(), FROM_HERE, - base::BindOnce(&SearchMetadataOnBlockingPool, resource_metadata, query, - predicate, at_most_num_matches, order, results_ptr), - base::BindOnce(&RunSearchMetadataCallback, std::move(callback), - start_time, std::move(results))); -} - -bool MatchesType(int options, const ResourceEntry& entry) { - if ((options & SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS) && - entry.file_specific_info().is_hosted_document()) - return false; - - if ((options & SEARCH_METADATA_EXCLUDE_DIRECTORIES) && - entry.file_info().is_directory()) - return false; - - if (options & SEARCH_METADATA_SHARED_WITH_ME) - return entry.shared_with_me(); - - if (options & SEARCH_METADATA_OFFLINE) { - if (entry.file_specific_info().is_hosted_document()) { - // Not all hosted documents are cached by Drive offline app. - // https://support.google.com/drive/answer/2375012 - std::string mime_type = entry.file_specific_info().content_mime_type(); - return mime_type == drive::util::kGoogleDocumentMimeType || - mime_type == drive::util::kGoogleSpreadsheetMimeType || - mime_type == drive::util::kGooglePresentationMimeType || - mime_type == drive::util::kGoogleDrawingMimeType; - } - return entry.file_specific_info().cache_state().is_present(); - } - - return true; -} - bool FindAndHighlight( const std::string& text, const std::vector<std::unique_ptr<
diff --git a/components/drive/chromeos/search_metadata.h b/components/drive/chromeos/search_metadata.h index f515c2d..b0976852 100644 --- a/components/drive/chromeos/search_metadata.h +++ b/components/drive/chromeos/search_metadata.h
@@ -5,15 +5,9 @@ #ifndef COMPONENTS_DRIVE_CHROMEOS_SEARCH_METADATA_H_ #define COMPONENTS_DRIVE_CHROMEOS_SEARCH_METADATA_H_ -#include <stddef.h> - -#include <memory> #include <string> #include <vector> -#include "base/sequenced_task_runner.h" -#include "components/drive/chromeos/file_system_interface.h" - namespace base { namespace i18n { class FixedPatternStringSearchIgnoringCaseAndAccents; @@ -23,38 +17,6 @@ namespace drive { namespace internal { -class ResourceMetadata; - -typedef base::RepeatingCallback<bool(const ResourceEntry&)> - SearchMetadataPredicate; - -// Searches the local resource metadata, and returns the entries -// |at_most_num_matches| that contain |query| in their base names. Search is -// done in a case-insensitive fashion. |query| is splitted into keywords by -// whitespace. All keywords are considered as AND condition. The eligible -// entries are selected based on the given |options|, which is a bit-wise OR of -// SearchMetadataOptions. |callback| must not be null. Must be called on UI -// thread. Empty |query| matches any base name. i.e. returns everything. -// |blocking_task_runner| must be the same one as |resource_metadata| uses. -void SearchMetadata( - scoped_refptr<base::SequencedTaskRunner> blocking_task_runner, - ResourceMetadata* resource_metadata, - const std::string& query, - const SearchMetadataPredicate& predicate, - size_t at_most_num_matches, - MetadataSearchOrder order, - SearchMetadataCallback callback); - -// Returns true if |entry| is eligible for the search |options| and should be -// tested for the match with the query. If -// SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS is requested, the hosted documents -// are skipped. If SEARCH_METADATA_EXCLUDE_DIRECTORIES is requested, the -// directories are skipped. If SEARCH_METADATA_SHARED_WITH_ME is requested, only -// the entries with shared-with-me label will be tested. If -// SEARCH_METADATA_OFFLINE is requested, only hosted documents and cached files -// match with the query. This option can not be used with other options. -bool MatchesType(int options, const ResourceEntry& entry); - // Finds |queries| in |text| while ignoring cases or accents. Cases of non-ASCII // characters are also ignored; they are compared in the 'Primary Level' of // http://userguide.icu-project.org/collation/concepts.
diff --git a/components/drive/chromeos/team_drive.cc b/components/drive/chromeos/team_drive.cc deleted file mode 100644 index f162f104..0000000 --- a/components/drive/chromeos/team_drive.cc +++ /dev/null
@@ -1,23 +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 "components/drive/chromeos/team_drive.h" - -namespace drive { -namespace internal { - -TeamDrive::TeamDrive(const std::string& team_drive_id) - : team_drive_id_(team_drive_id) {} - -TeamDrive::TeamDrive(const std::string& team_drive_id, - const std::string& team_drive_name, - const base::FilePath& team_drive_path) - : team_drive_id_(team_drive_id), - team_drive_name_(team_drive_name), - team_drive_path_(team_drive_path) {} - -TeamDrive::~TeamDrive() = default; - -} // namespace internal -} // namespace drive
diff --git a/components/drive/chromeos/team_drive.h b/components/drive/chromeos/team_drive.h deleted file mode 100644 index 7567a6b5..0000000 --- a/components/drive/chromeos/team_drive.h +++ /dev/null
@@ -1,49 +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 COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_H_ -#define COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_H_ - -#include <string> - -#include "base/files/file_path.h" -#include "base/macros.h" - -namespace drive { -namespace internal { - -// Represents a team drive object that can be passed to observers of team drive -// changes, for example when loading the list of team drives, or removing/adding -// a team drive when processing the users change list. -class TeamDrive { - public: - TeamDrive(const std::string& team_drive_id); - - TeamDrive(const std::string& team_drive_id, - const std::string& team_drive_name, - const base::FilePath& team_drive_path); - ~TeamDrive(); - - // The team drive ID returned from the server. - // https://developers.google.com/drive/api/v2/reference/teamdrives#resource - const std::string& team_drive_id() const { return team_drive_id_; } - - // The team drive name returned from the server. May be empty when deleting - // a team drive, which will be based on the id() and not the name. - const std::string& team_drive_name() const { return team_drive_name_; } - - // The path where the team drive is mounted in the file system. May be - // empty when deleting the team drive. - const base::FilePath& team_drive_path() const { return team_drive_path_; } - - private: - std::string team_drive_id_; - std::string team_drive_name_; - base::FilePath team_drive_path_; -}; - -} // namespace internal -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_H_
diff --git a/components/drive/chromeos/team_drive_list_observer.h b/components/drive/chromeos/team_drive_list_observer.h deleted file mode 100644 index a6109e2..0000000 --- a/components/drive/chromeos/team_drive_list_observer.h +++ /dev/null
@@ -1,40 +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 COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_LIST_OBSERVER_H_ -#define COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_LIST_OBSERVER_H_ - -#include <vector> - -#include "components/drive/chromeos/team_drive.h" - -namespace drive { -namespace internal { - -// Interface for classes that need to observe events from the -// TeamDriveListLoader. -// TODO(slangley): Consider merging with ChangeListLoaderObserver. -class TeamDriveListObserver { - public: - // Called every time that the complete list of team drives has been retrieved - // from the server. - // - |team_drives_list| is the entire list of team drives the user has - // access to. - // - |added_team_drives| is the list of team drives that have been added - // as part of loading the team drives. - // - |removed_team_drives| will be the list of team drives that have been - // removed as part of loading the team drives. - virtual void OnTeamDriveListLoaded( - const std::vector<TeamDrive>& team_drives_list, - const std::vector<TeamDrive>& added_team_drives, - const std::vector<TeamDrive>& removed_team_drives) = 0; - - protected: - virtual ~TeamDriveListObserver() = default; -}; - -} // namespace internal -} // namespace drive - -#endif // COMPONENTS_DRIVE_CHROMEOS_TEAM_DRIVE_LIST_LOADER_OBSERVER_H_
diff --git a/components/drive/drive_api_util.cc b/components/drive/drive_api_util.cc index 05376bd1..6c57cf9 100644 --- a/components/drive/drive_api_util.cc +++ b/components/drive/drive_api_util.cc
@@ -4,25 +4,17 @@ #include "components/drive/drive_api_util.h" -#include <stddef.h> -#include <stdint.h> - #include <string> #include "base/files/file.h" #include "base/hash/md5.h" -#include "base/logging.h" #include "base/stl_util.h" #include "base/strings/string16.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" #include "base/synchronization/atomic_flag.h" -#include "base/task_runner_util.h" -#include "base/values.h" -#include "google_apis/drive/drive_api_parser.h" #include "third_party/re2/src/re2/re2.h" -#include "url/gurl.h" namespace drive { namespace util { @@ -173,14 +165,6 @@ return base::MD5DigestToBase16(digest); } -std::string GetHostedDocumentExtension(const std::string& mime_type) { - for (size_t i = 0; i < base::size(kHostedDocumentKinds); ++i) { - if (mime_type == kHostedDocumentKinds[i].mime_type) - return kHostedDocumentKinds[i].extension; - } - return kUnknownHostedDocumentExtension; -} - bool IsKnownHostedDocumentMimeType(const std::string& mime_type) { for (size_t i = 0; i < base::size(kHostedDocumentKinds); ++i) { if (mime_type == kHostedDocumentKinds[i].mime_type) @@ -198,13 +182,6 @@ return extension == kUnknownHostedDocumentExtension; } -void RunAsyncTask(base::TaskRunner* task_runner, - const base::Location& from_here, - base::OnceCallback<FileError()> task, - base::OnceCallback<void(FileError)> reply) { - PostTaskAndReplyWithResult(task_runner, from_here, std::move(task), - std::move(reply)); -} } // namespace util } // namespace drive
diff --git a/components/drive/drive_api_util.h b/components/drive/drive_api_util.h index cc94229..39afcf4 100644 --- a/components/drive/drive_api_util.h +++ b/components/drive/drive_api_util.h
@@ -5,19 +5,11 @@ #ifndef COMPONENTS_DRIVE_DRIVE_API_UTIL_H_ #define COMPONENTS_DRIVE_DRIVE_API_UTIL_H_ -#include <memory> #include <string> -#include "base/callback.h" -#include "components/drive/file_errors.h" -#include "google_apis/drive/drive_api_error_codes.h" -#include "google_apis/drive/drive_common_callbacks.h" - namespace base { class AtomicFlag; -class Location; class FilePath; -class TaskRunner; } // namespace base namespace drive { @@ -60,10 +52,6 @@ std::string GetMd5Digest(const base::FilePath& file_path, const base::AtomicFlag* cancellation_flag); -// Returns preferred file extension for hosted documents which have given mime -// type. -std::string GetHostedDocumentExtension(const std::string& mime_type); - // Returns true if the given mime type is corresponding to one of known hosted // document types. bool IsKnownHostedDocumentMimeType(const std::string& mime_type); @@ -72,13 +60,6 @@ // hosted document types. bool HasHostedDocumentExtension(const base::FilePath& path); -// Runs |task| on |task_runner|, then runs |reply| on the original thread with -// the resulting error code. -void RunAsyncTask(base::TaskRunner* task_runner, - const base::Location& from_here, - base::OnceCallback<FileError()> task, - base::OnceCallback<void(FileError)> reply); - } // namespace util } // namespace drive
diff --git a/components/drive/drive_file_util_unittest.cc b/components/drive/drive_file_util_unittest.cc deleted file mode 100644 index b7f269c7..0000000 --- a/components/drive/drive_file_util_unittest.cc +++ /dev/null
@@ -1,122 +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 <memory> -#include <string> - -#include "base/files/scoped_temp_dir.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/drive/chromeos/drive_file_util.h" -#include "components/drive/chromeos/drive_test_util.h" -#include "components/drive/chromeos/fake_free_disk_space_getter.h" -#include "components/drive/chromeos/file_cache.h" -#include "components/drive/chromeos/resource_metadata.h" -#include "components/drive/drive.pb.h" -#include "components/drive/file_system_core_util.h" -#include "content/public/test/browser_task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { -namespace internal { -namespace { - -// The start page token of the resource metadata used in DriveFileUtilTest. -constexpr char kTestStartPageToken[] = "123456"; - -// Creates a ResourceEntry for a directory with explicitly set resource_id. -ResourceEntry CreateDirectoryEntryWithResourceId( - const std::string& title, - const std::string& resource_id, - const std::string& parent_local_id) { - ResourceEntry entry; - entry.set_title(title); - entry.set_resource_id(resource_id); - entry.set_parent_local_id(parent_local_id); - entry.mutable_file_info()->set_is_directory(true); - entry.mutable_directory_specific_info()->set_start_page_token( - kTestStartPageToken); - return entry; -} - -void AddTeamDriveRootEntry(ResourceMetadata* resource_metadata, - const std::string& team_drive_id, - const std::string& team_drive_name) { - std::string local_id; - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->GetIdByPath( - util::GetDriveTeamDrivesRootPath(), &local_id)); - - std::string root_local_id = local_id; - ASSERT_EQ(FILE_ERROR_OK, - resource_metadata->AddEntry( - CreateDirectoryEntryWithResourceId( - team_drive_name, team_drive_id, root_local_id), - &local_id)); -} - -} // namespace - -// Tests for methods running on the blocking task runner. -class DriveFileUtilTest : public testing::Test { - protected: - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - - metadata_storage_.reset(new ResourceMetadataStorage( - temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); - ASSERT_TRUE(metadata_storage_->Initialize()); - - fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>(); - cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(), - base::ThreadTaskRunnerHandle::Get().get(), - fake_free_disk_space_getter_.get())); - ASSERT_TRUE(cache_->Initialize()); - - resource_metadata_.reset( - new ResourceMetadata(metadata_storage_.get(), cache_.get(), - base::ThreadTaskRunnerHandle::Get())); - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize()); - } - - base::ScopedTempDir temp_dir_; - content::BrowserTaskEnvironment task_environment_; - std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests> - metadata_storage_; - std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_; - std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_; - std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> - resource_metadata_; -}; - -TEST_F(DriveFileUtilTest, TeamDriveStartPageToken) { - constexpr char kTeamDriveId[] = "team_drive_id_1"; - constexpr char kTeamDriveName[] = "My Team Drive"; - constexpr char kStartPageToken[] = "123456"; - - AddTeamDriveRootEntry(resource_metadata_.get(), kTeamDriveId, kTeamDriveName); - - EXPECT_EQ(FILE_ERROR_OK, SetStartPageToken(resource_metadata_.get(), - kTeamDriveId, kStartPageToken)); - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, GetStartPageToken(resource_metadata_.get(), - kTeamDriveId, &start_page_token)); - EXPECT_EQ(kStartPageToken, start_page_token); -} - -TEST_F(DriveFileUtilTest, TeamDriveStartPageToken_NoEntry) { - constexpr char kTeamDriveId[] = "team_drive_id_1"; - constexpr char kStartPageToken[] = "123456"; - - EXPECT_EQ(FILE_ERROR_NOT_FOUND, - SetStartPageToken(resource_metadata_.get(), kTeamDriveId, - kStartPageToken)); - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_NOT_FOUND, - GetStartPageToken(resource_metadata_.get(), kTeamDriveId, - &start_page_token)); -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/drive_operation_queue_unittest.cc b/components/drive/drive_operation_queue_unittest.cc deleted file mode 100644 index 68ea39b6..0000000 --- a/components/drive/drive_operation_queue_unittest.cc +++ /dev/null
@@ -1,300 +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 "components/drive/chromeos/drive_operation_queue.h" -#include "base/bind.h" -#include "base/memory/weak_ptr.h" -#include "base/test/bind_test_util.h" -#include "base/test/test_mock_time_task_runner.h" -#include "components/drive/file_errors.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { -namespace internal { - -namespace { - -constexpr int kDesiredQPS = 5; -constexpr base::TimeDelta kTokenRefreshRate = - base::TimeDelta::FromSeconds(1) / kDesiredQPS; - -class FakeDriveOperation { - public: - FakeDriveOperation() {} - - base::WeakPtr<FakeDriveOperation> GetWeakPtr() { - return weak_ptr_factory_.GetWeakPtr(); - } - - void FakeOperation(const FileOperationCallback& callback) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK(!task_has_executed); - - task_has_executed = true; - callback.Run(FILE_ERROR_OK); - } - - bool HasTaskExecuted() const { return task_has_executed; } - - private: - bool task_has_executed = false; - SEQUENCE_CHECKER(sequence_checker_); - - base::WeakPtrFactory<FakeDriveOperation> weak_ptr_factory_{this}; - - DISALLOW_COPY_AND_ASSIGN(FakeDriveOperation); -}; - -} // namespace - -class DriveOperationQueueTest : public testing::Test { - protected: - using OperationQueue = DriveBackgroundOperationQueue<FakeDriveOperation>; - - void SetUp() override { - task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>( - base::TestMockTimeTaskRunner::Type::kBoundToThread); - operation_queue_ = - std::make_unique<DriveBackgroundOperationQueue<FakeDriveOperation>>( - kDesiredQPS, task_runner_->GetMockTickClock()); - } - - scoped_refptr<base::TestMockTimeTaskRunner> task_runner_; - std::unique_ptr<OperationQueue> operation_queue_; -}; - -// Put up to |kDesiredQPS| entries in queue, all should run without the timer -// needing to advance. -TEST_F(DriveOperationQueueTest, BurstMode) { - std::vector<std::unique_ptr<FakeDriveOperation>> operations; - - for (int i = 0; i < kDesiredQPS; ++i) { - operations.emplace_back(std::make_unique<FakeDriveOperation>()); - } - - int callbacks_run = 0; - - for (auto& operation : operations) { - operation_queue_->AddOperation( - operation->GetWeakPtr(), - base::BindOnce(&FakeDriveOperation::FakeOperation, - operation->GetWeakPtr()), - base::BindLambdaForTesting( - [&callbacks_run](drive::FileError error) { ++callbacks_run; })); - } - - // Execute all pending tasks without advancing virtual time. - task_runner_->RunUntilIdle(); - - ASSERT_EQ(callbacks_run, kDesiredQPS); - - for (auto& operation : operations) { - ASSERT_TRUE(operation->HasTaskExecuted()); - } -} - -// Ensure that tokens are refilled as the timer advances. -TEST_F(DriveOperationQueueTest, RefillTokens) { - constexpr int kAdditionalTasks = 5; - constexpr int kTasksToQueue = kDesiredQPS + kAdditionalTasks; - - std::vector<std::unique_ptr<FakeDriveOperation>> operations; - - for (int i = 0; i < kTasksToQueue; ++i) { - operations.emplace_back(std::make_unique<FakeDriveOperation>()); - } - - int callbacks_run = 0; - - for (int i = 0; i < kTasksToQueue; ++i) { - operation_queue_->AddOperation( - operations[i]->GetWeakPtr(), - base::BindOnce(&FakeDriveOperation::FakeOperation, - operations[i]->GetWeakPtr()), - base::BindLambdaForTesting( - [&callbacks_run](drive::FileError) { ++callbacks_run; })); - } - - // Execute all pending tasks without advancing virtual time. - task_runner_->RunUntilIdle(); - - // We should only have advanced through the burst mode tasks. - ASSERT_EQ(callbacks_run, kDesiredQPS); - - // Move time forward, should cause a token to be refreshed and an operation to - // run. - int last_callbacks_run = callbacks_run; - for (int i = kDesiredQPS; i < kTasksToQueue; ++i) { - ASSERT_FALSE(operations[i]->HasTaskExecuted()); - - task_runner_->FastForwardBy(kTokenRefreshRate); - - ASSERT_EQ(callbacks_run, last_callbacks_run + 1); - ASSERT_TRUE(operations[i]->HasTaskExecuted()); - last_callbacks_run = callbacks_run; - } - - ASSERT_EQ(kTasksToQueue, callbacks_run); -} - -// Ensure that invalidated tasks are not run, but also do not block the queue. -TEST_F(DriveOperationQueueTest, InvalidateTasks) { - constexpr int kTasksToInvalidate = kDesiredQPS * 2; - constexpr int kAdditionalTasks = 5; - constexpr int kTasksToQueue = - kDesiredQPS + kAdditionalTasks + kTasksToInvalidate; - - std::vector<std::unique_ptr<FakeDriveOperation>> operations; - - for (int i = 0; i < kTasksToQueue; ++i) { - operations.emplace_back(std::make_unique<FakeDriveOperation>()); - } - - int callbacks_run = 0; - - for (int i = 0; i < kTasksToQueue; ++i) { - operation_queue_->AddOperation( - operations[i]->GetWeakPtr(), - base::BindOnce(&FakeDriveOperation::FakeOperation, - operations[i]->GetWeakPtr()), - base::BindLambdaForTesting( - [&callbacks_run](drive::FileError) { ++callbacks_run; })); - } - - // Execute all pending tasks without advancing virtual time. - task_runner_->RunUntilIdle(); - - // We should only have advanced through the burst mode tasks. - ASSERT_EQ(callbacks_run, kDesiredQPS); - - // Erase tasks from the queue, which will invalidate their weak ptrs and - // prevent callbacks from being run. - operations.erase(operations.begin(), - operations.begin() + callbacks_run + kTasksToInvalidate); - - // Fast forward until all tasks have been executed. - int last_callbacks_run = callbacks_run; - task_runner_->FastForwardUntilNoTasksRemain(); - - // All expected tasks should now have been run. - ASSERT_EQ(last_callbacks_run + kAdditionalTasks, callbacks_run); -} - -// Ensure that tasks added after burst mode has finished are only executed -// at the desired QPS. -TEST_F(DriveOperationQueueTest, DoNotRepeatBurstMode) { - constexpr int kTasksToCreate = kDesiredQPS * 2; - - std::vector<std::unique_ptr<FakeDriveOperation>> operations; - - for (int i = 0; i < kTasksToCreate; ++i) { - operations.emplace_back(std::make_unique<FakeDriveOperation>()); - } - - int callbacks_run = 0; - - // Only run the burst mode tasks. - for (int i = 0; i < kDesiredQPS; ++i) { - operation_queue_->AddOperation( - operations[i]->GetWeakPtr(), - base::BindOnce(&FakeDriveOperation::FakeOperation, - operations[i]->GetWeakPtr()), - base::BindLambdaForTesting( - [&callbacks_run](drive::FileError error) { ++callbacks_run; })); - } - - // Execute all pending tasks without advancing virtual time. - task_runner_->FastForwardBy(kTokenRefreshRate); - - ASSERT_EQ(callbacks_run, kDesiredQPS); - - // Add the remaining tasks to the queue, only the first should run as we've - // only advanced 1 refresh period. - for (int i = kDesiredQPS; i < kTasksToCreate; ++i) { - operation_queue_->AddOperation( - operations[i]->GetWeakPtr(), - base::BindOnce(&FakeDriveOperation::FakeOperation, - operations[i]->GetWeakPtr()), - base::BindLambdaForTesting( - [&callbacks_run](drive::FileError error) { ++callbacks_run; })); - } - - int last_callbacks_run = callbacks_run; - // Just run the tasks that are scheduled now. - task_runner_->RunUntilIdle(); - ASSERT_EQ(last_callbacks_run + 1, callbacks_run); - - // Run the rest of the tasks. - task_runner_->FastForwardUntilNoTasksRemain(); - ASSERT_EQ(kTasksToCreate, callbacks_run); -} - -// Ensure that burst mode is re-enabled if more than 1 second has advanced since -// the last task finished. -TEST_F(DriveOperationQueueTest, RepeatBurstMode) { - constexpr int kTasksToCreate = kDesiredQPS * 3; - - std::vector<std::unique_ptr<FakeDriveOperation>> operations; - - for (int i = 0; i < kTasksToCreate; ++i) { - operations.emplace_back(std::make_unique<FakeDriveOperation>()); - } - - int callbacks_run = 0; - - // Only run the burst mode tasks. - for (int i = 0; i < kDesiredQPS; ++i) { - operation_queue_->AddOperation( - operations[i]->GetWeakPtr(), - base::BindOnce(&FakeDriveOperation::FakeOperation, - operations[i]->GetWeakPtr()), - base::BindLambdaForTesting( - [&callbacks_run](drive::FileError error) { ++callbacks_run; })); - } - - // Execute all pending tasks. - task_runner_->FastForwardUntilNoTasksRemain(); - ASSERT_EQ(kDesiredQPS, callbacks_run); - - // Move forward two seconds, so that we should reset burst mode. - task_runner_->FastForwardBy(base::TimeDelta::FromSeconds(2)); - - // Add the remaining tasks to the queue, all should run in burst mode. - for (int i = kDesiredQPS; i < kTasksToCreate; ++i) { - operation_queue_->AddOperation( - operations[i]->GetWeakPtr(), - base::BindOnce(&FakeDriveOperation::FakeOperation, - operations[i]->GetWeakPtr()), - base::BindLambdaForTesting( - [&callbacks_run](drive::FileError error) { ++callbacks_run; })); - } - - callbacks_run = 0; - - // Execute all pending tasks without advancing virtual time. - task_runner_->RunUntilIdle(); - - // We should only have advanced through the burst mode tasks. - ASSERT_EQ(kDesiredQPS, callbacks_run); - - // The last tasks should not have been run yet. - for (int i = 2 * kDesiredQPS; i < kTasksToCreate; ++i) { - ASSERT_FALSE(operations[i]->HasTaskExecuted()); - } - - // Run the remaining tasks, which should happen at desired qps - base::TimeTicks start_ticks = task_runner_->NowTicks(); - task_runner_->FastForwardUntilNoTasksRemain(); - - ASSERT_LE(base::TimeDelta::FromSeconds(1), - task_runner_->NowTicks() - start_ticks); - - // All tasks have been run. - for (auto& operation : operations) { - ASSERT_TRUE(operation->HasTaskExecuted()); - } -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/file_change.cc b/components/drive/file_change.cc deleted file mode 100644 index 456b864..0000000 --- a/components/drive/file_change.cc +++ /dev/null
@@ -1,165 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/file_change.h" - -#include <sstream> - -#include "base/logging.h" -#include "base/strings/stringprintf.h" -#include "components/drive/drive.pb.h" - -namespace drive { - -FileChange::Change::Change(ChangeType change, FileType file_type) - : change_(change), file_type_(file_type) { -} - -FileChange::Change::Change(ChangeType change, - FileType file_type, - const std::string& team_drive_id) - : change_(change), file_type_(file_type), team_drive_id_(team_drive_id) {} - -std::string FileChange::Change::DebugString() const { - const char* change_string = nullptr; - switch (change()) { - case CHANGE_TYPE_ADD_OR_UPDATE: - change_string = "ADD_OR_UPDATE"; - break; - case CHANGE_TYPE_DELETE: - change_string = "DELETE"; - break; - } - const char* type_string = "NO_INFO"; - switch (file_type()) { - case FileChange::FILE_TYPE_FILE: - type_string = "FILE"; - break; - case FileChange::FILE_TYPE_DIRECTORY: - type_string = "DIRECTORY"; - break; - case FILE_TYPE_NO_INFO: - // Keeps it as "no_info". - break; - } - return base::StringPrintf("%s:%s", change_string, type_string); -} - -FileChange::ChangeList::ChangeList() = default; -FileChange::ChangeList::ChangeList(const ChangeList& other) = default; -FileChange::ChangeList::~ChangeList() = default; - -void FileChange::ChangeList::Update(const Change& new_change) { - if (list_.empty()) { - list_.push_back(new_change); - return; - } - - Change& last = list_.back(); - if (last.IsFile() != new_change.IsFile()) { - list_.push_back(new_change); - return; - } - - if (last.team_drive_id() != new_change.team_drive_id()) { - list_.push_back(new_change); - return; - } - - if (last.change() == new_change.change()) - return; - - // ADD + DELETE on directory -> revert - if (!last.IsFile() && last.IsAddOrUpdate() && new_change.IsDelete()) { - list_.pop_back(); - return; - } - - // DELETE + ADD/UPDATE -> ADD/UPDATE - // ADD/UPDATE + DELETE -> DELETE - last = new_change; -} - -FileChange::ChangeList FileChange::ChangeList::PopAndGetNewList() const { - ChangeList changes; - changes.list_ = this->list_; - changes.list_.pop_front(); - return changes; -} - -std::string FileChange::ChangeList::DebugString() const { - std::ostringstream ss; - ss << "{ "; - for (size_t i = 0; i < list_.size(); ++i) - ss << list_[i].DebugString() << ", "; - ss << "}"; - return ss.str(); -} - -FileChange::FileChange() = default; -FileChange::FileChange(const FileChange& other) = default; -FileChange::~FileChange() = default; - -void FileChange::Update(const base::FilePath file_path, - const FileChange::Change& new_change) { - map_[file_path].Update(new_change); -} - -void FileChange::Update(const base::FilePath file_path, - const FileChange::ChangeList& new_change) { - for (ChangeList::List::const_iterator it = new_change.list().begin(); - it != new_change.list().end(); - it++) { - map_[file_path].Update(*it); - } -} - -void FileChange::Update(const base::FilePath file_path, - FileType file_type, - FileChange::ChangeType change) { - Update(file_path, FileChange::Change(change, file_type)); -} - -void FileChange::Update(const base::FilePath file_path, - const ResourceEntry& entry, - FileChange::ChangeType change) { - FileType type = FILE_TYPE_NO_INFO; - std::string team_drive_id; - if (entry.has_file_info()) { - type = - entry.file_info().is_directory() ? FILE_TYPE_DIRECTORY : FILE_TYPE_FILE; - if (entry.file_info().is_team_drive_root()) { - team_drive_id = entry.resource_id(); - } - } - Update(file_path, FileChange::Change(change, type, team_drive_id)); -} - -void FileChange::Apply(const FileChange& new_changed_files) { - for (auto it = new_changed_files.map().begin(); - it != new_changed_files.map().end(); it++) { - Update(it->first, it->second); - } -} - -size_t FileChange::CountDirectory(const base::FilePath& directory_path) const { - size_t count = 0; - for (auto it = map_.begin(); it != map_.end(); it++) { - if (it->first.DirName() == directory_path) - count++; - } - return count; -} - -std::string FileChange::DebugString() const { - std::ostringstream ss; - ss << "{ "; - for (auto it = map_.begin(); it != map_.end(); it++) { - ss << it->first.value() << ": " << it->second.DebugString() << ", "; - } - ss << "}"; - return ss.str(); -} - -} // namespace drive
diff --git a/components/drive/file_change.h b/components/drive/file_change.h deleted file mode 100644 index a7ec41b..0000000 --- a/components/drive/file_change.h +++ /dev/null
@@ -1,127 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_FILE_CHANGE_H_ -#define COMPONENTS_DRIVE_FILE_CHANGE_H_ - -#include <stddef.h> - -#include <map> -#include <string> - -#include "base/containers/circular_deque.h" -#include "base/files/file_path.h" - -namespace drive { -class ResourceEntry; - -class FileChange { - public: - enum FileType { - FILE_TYPE_NO_INFO, - FILE_TYPE_FILE, - FILE_TYPE_DIRECTORY, - }; - - enum ChangeType { - CHANGE_TYPE_ADD_OR_UPDATE, - CHANGE_TYPE_DELETE, - }; - - class Change { - public: - Change(ChangeType change, FileType file_type); - Change(ChangeType change, - FileType file_type, - const std::string& team_drive_id); - - bool IsAddOrUpdate() const { return change_ == CHANGE_TYPE_ADD_OR_UPDATE; } - bool IsDelete() const { return change_ == CHANGE_TYPE_DELETE; } - - bool IsFile() const { return file_type_ == FILE_TYPE_FILE; } - bool IsDirectory() const { return file_type_ == FILE_TYPE_DIRECTORY; } - bool IsTypeUnknown() const { return !IsFile() && !IsDirectory(); } - - ChangeType change() const { return change_; } - FileType file_type() const { return file_type_; } - const std::string& team_drive_id() const { return team_drive_id_; } - - std::string DebugString() const; - - bool operator==(const Change& that) const { - return change() == that.change() && file_type() == that.file_type() && - team_drive_id() == that.team_drive_id(); - } - - private: - ChangeType change_; - FileType file_type_; - // The team drive id, will be empty if the change is not a team drive root. - std::string team_drive_id_; - }; - - class ChangeList { - public: - typedef base::circular_deque<Change> List; - - ChangeList(); - ChangeList(const ChangeList& other); - ~ChangeList(); - - // Updates the list with the |new_change|. - void Update(const Change& new_change); - - size_t size() const { return list_.size(); } - bool empty() const { return list_.empty(); } - void clear() { list_.clear(); } - const List& list() const { return list_; } - const Change& front() const { return list_.front(); } - const Change& back() const { return list_.back(); } - - ChangeList PopAndGetNewList() const; - - std::string DebugString() const; - - private: - List list_; - }; - - public: - typedef std::map<base::FilePath, FileChange::ChangeList> Map; - - FileChange(); - FileChange(const FileChange& other); - ~FileChange(); - - void Update(const base::FilePath file_path, - const FileChange::Change& new_change); - void Update(const base::FilePath file_path, - const FileChange::ChangeList& list); - void Update(const base::FilePath file_path, - FileType type, - FileChange::ChangeType change); - void Update(const base::FilePath file_path, - const ResourceEntry& entry, - FileChange::ChangeType change); - void Apply(const FileChange& new_changed_files); - - const Map& map() const { return map_; } - - size_t size() const { return map_.size(); } - bool empty() const { return map_.empty(); } - void ClearForTest() { map_.clear(); } - size_t CountDirectory(const base::FilePath& directory_path) const; - size_t count(const base::FilePath& file_path) const { - return map_.count(file_path); - } - - std::string DebugString() const; - - private: - Map map_; -}; - -} // namespace drive - -#endif // COMPONENTS_DRIVE_FILE_CHANGE_H_
diff --git a/components/drive/file_change_unittest.cc b/components/drive/file_change_unittest.cc deleted file mode 100644 index f934d1c..0000000 --- a/components/drive/file_change_unittest.cc +++ /dev/null
@@ -1,87 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/file_change.h" - -#include "components/drive/drive.pb.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { - -TEST(ChangeListTest, FileChange_Change) { - FileChange::ChangeType change_type = FileChange::CHANGE_TYPE_ADD_OR_UPDATE; - FileChange::FileType file_type = FileChange::FILE_TYPE_FILE; - - FileChange::Change change1(change_type, file_type); - EXPECT_EQ(change_type, change1.change()); - EXPECT_EQ(file_type, change1.file_type()); - - FileChange::Change change2(change_type, file_type); - EXPECT_EQ(change_type, change1.change()); - EXPECT_EQ(file_type, change1.file_type()); - EXPECT_EQ(change1, change2); - - FileChange::Change change3(change_type, FileChange::FILE_TYPE_DIRECTORY); - EXPECT_EQ(change_type, change3.change()); - EXPECT_EQ(FileChange::FILE_TYPE_DIRECTORY, change3.file_type()); - EXPECT_TRUE(!(change1 == change3)); -} - -TEST(ChangeListTest, FileChangeChangeList) { - FileChange::ChangeList changes; - EXPECT_TRUE(changes.empty()); - EXPECT_EQ(0u, changes.size()); - - changes.Update(FileChange::Change(FileChange::CHANGE_TYPE_ADD_OR_UPDATE, - FileChange::FILE_TYPE_FILE)); - EXPECT_EQ(1u, changes.size()); -} - -TEST(ChangeListTest, FileChange) { - base::FilePath change_path1(FILE_PATH_LITERAL("test")); - base::FilePath change_path2(FILE_PATH_LITERAL("a/b/c/d")); - base::FilePath change_path3(FILE_PATH_LITERAL("a/b/c/e")); - base::FilePath change_dir(FILE_PATH_LITERAL("a/b/c")); - - FileChange changed_files; - changed_files.Update(change_path1, FileChange::FILE_TYPE_FILE, - FileChange::CHANGE_TYPE_ADD_OR_UPDATE); - changed_files.Update(change_path2, FileChange::FILE_TYPE_FILE, - FileChange::CHANGE_TYPE_ADD_OR_UPDATE); - changed_files.Update(change_path2, FileChange::FILE_TYPE_FILE, - FileChange::CHANGE_TYPE_ADD_OR_UPDATE); - changed_files.Update(change_path3, FileChange::FILE_TYPE_FILE, - FileChange::CHANGE_TYPE_ADD_OR_UPDATE); - - ASSERT_EQ(3u, changed_files.size()); - ASSERT_EQ(2u, changed_files.CountDirectory(change_dir)); -} - -TEST(ChangeListTest, TeamDriveRootChange) { - base::FilePath team_drive1(FILE_PATH_LITERAL("a/b/c")); - base::FilePath team_drive2(FILE_PATH_LITERAL("a/b/d")); - - ResourceEntry resource; - resource.mutable_file_info()->set_is_directory(true); - resource.mutable_file_info()->set_is_team_drive_root(true); - - FileChange changed_files; - resource.set_resource_id("team_drive_id_1"); - changed_files.Update(team_drive1, resource, - FileChange::CHANGE_TYPE_ADD_OR_UPDATE); - - resource.set_resource_id("team_drive_id_2"); - changed_files.Update(team_drive2, resource, - FileChange::CHANGE_TYPE_ADD_OR_UPDATE); - - ASSERT_EQ(2UL, changed_files.size()); - - const FileChange::Map& change_map = changed_files.map(); - ASSERT_EQ("team_drive_id_1", - change_map.at(team_drive1).front().team_drive_id()); - ASSERT_EQ("team_drive_id_2", - change_map.at(team_drive2).front().team_drive_id()); -} - -} // namespace drive
diff --git a/components/drive/file_system_core_util.cc b/components/drive/file_system_core_util.cc index 41854a5..ad48bfed 100644 --- a/components/drive/file_system_core_util.cc +++ b/components/drive/file_system_core_util.cc
@@ -11,22 +11,13 @@ #include <string> #include <vector> -#include "base/bind.h" -#include "base/bind_helpers.h" #include "base/files/file_path.h" #include "base/files/file_util.h" -#include "base/i18n/icu_string_conversions.h" #include "base/json/json_file_value_serializer.h" #include "base/logging.h" #include "base/no_destructor.h" #include "base/strings/string_number_conversions.h" -#include "base/strings/string_util.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/drive/drive.pb.h" -#include "components/drive/drive_pref_names.h" -#include "components/drive/job_list.h" -#include "components/prefs/pref_service.h" +#include "base/values.h" namespace drive { namespace util { @@ -72,92 +63,11 @@ return *grand_root_path; } -const base::FilePath& GetDriveMyDriveRootPath() { - static base::NoDestructor<base::FilePath> drive_root_path( - GetDriveGrandRootPath().AppendASCII(kDriveMyDriveRootDirName)); - return *drive_root_path; -} - -const base::FilePath& GetDriveTeamDrivesRootPath() { - static base::NoDestructor<base::FilePath> team_drives_root_path( - GetDriveGrandRootPath().AppendASCII(kDriveTeamDrivesDirName)); - return *team_drives_root_path; -} - -bool IsTeamDrivesPath(const base::FilePath& file_path) { - return GetDriveTeamDrivesRootPath().IsParent(file_path); -} - -std::string EscapeCacheFileName(const std::string& filename) { - // This is based on net/base/escape.cc: net::(anonymous namespace)::Escape - std::string escaped; - for (size_t i = 0; i < filename.size(); ++i) { - char c = filename[i]; - if (c == '%' || c == '.' || c == '/') { - base::StringAppendF(&escaped, "%%%02X", c); - } else { - escaped.push_back(c); - } - } - return escaped; -} - -std::string UnescapeCacheFileName(const std::string& filename) { - std::string unescaped; - for (size_t i = 0; i < filename.size(); ++i) { - char c = filename[i]; - if (c == '%' && i + 2 < filename.length()) { - c = (base::HexDigitToInt(filename[i + 1]) << 4) + - base::HexDigitToInt(filename[i + 2]); - i += 2; - } - unescaped.push_back(c); - } - return unescaped; -} - std::string ConvertChangestampToStartPageToken(int64_t changestamp) { DCHECK_LE(0, changestamp); return base::NumberToString(changestamp + 1); } -// Convers a start page token to a numerical changestamp -bool ConvertStartPageTokenToChangestamp(const std::string& start_page_token, - int64_t* changestamp) { - DCHECK(changestamp); - int64_t result; - if (base::StringToInt64(start_page_token, &result)) { - // The minimum valid start_page_token is 1. - if (result > 0) { - *changestamp = result - 1; - return true; - } - } - return false; -} - -std::string NormalizeFileName(const std::string& input) { - DCHECK(base::IsStringUTF8(input)); - - std::string output; - if (!base::ConvertToUtf8AndNormalize(input, base::kCodepageUTF8, &output)) - output = input; - base::ReplaceChars(output, "/", "_", &output); - if (!output.empty() && output.find_first_not_of('.', 0) == std::string::npos) - output = "_"; - return output; -} - -bool CreateGDocFile(const base::FilePath& file_path, - const GURL& url, - const std::string& resource_id) { - std::string content = - base::StringPrintf(R"({"url": "%s", "resource_id": "%s"})", - url.spec().c_str(), resource_id.c_str()); - return base::WriteFile(file_path, content.data(), content.size()) == - static_cast<int>(content.size()); -} - GURL ReadUrlFromGDocFile(const base::FilePath& file_path) { return GURL(ReadStringFromGDocFile(file_path, "url")); }
diff --git a/components/drive/file_system_core_util.h b/components/drive/file_system_core_util.h index b83742f..a76671d 100644 --- a/components/drive/file_system_core_util.h +++ b/components/drive/file_system_core_util.h
@@ -46,37 +46,9 @@ // Returns the path of the top root of the pseudo tree. const base::FilePath& GetDriveGrandRootPath(); -// Returns the path of the directory representing "My Drive". -const base::FilePath& GetDriveMyDriveRootPath(); - -// Returns the path of the directory representing "Team Drives". -const base::FilePath& GetDriveTeamDrivesRootPath(); - -// Returns true if |file_path| is a child directory of the team drives root. -bool IsTeamDrivesPath(const base::FilePath& file_path); - -// Escapes a file name in Drive cache. -// Replaces percent ('%'), period ('.') and slash ('/') with %XX (hex) -std::string EscapeCacheFileName(const std::string& filename); - -// Unescapes a file path in Drive cache. -// This is the inverse of EscapeCacheFileName. -std::string UnescapeCacheFileName(const std::string& filename); - // Converts a numerical changestamp value to a start page token. std::string ConvertChangestampToStartPageToken(int64_t changestamp); -// Convers a start page token to a numerical changestamp -bool ConvertStartPageTokenToChangestamp(const std::string& stat_page_token, - int64_t* changestamp); - -// Converts the given string to a form suitable as a file name. Specifically, -// - Normalizes in Unicode Normalization Form C. -// - Replaces slashes '/' with '_'. -// - Replaces the whole input with "_" if the all input characters are '.'. -// |input| must be a valid UTF-8 encoded string. -std::string NormalizeFileName(const std::string& input); - // Helper to destroy objects which needs Destroy() to be called on destruction. struct DestroyHelper { template <typename T> @@ -86,15 +58,6 @@ } }; -// Creates a GDoc file with given values. -// -// GDoc files are used to represent hosted documents on local filesystems. -// A GDoc file contains a JSON whose content is a URL to view the document and -// a resource ID of the entry. -bool CreateGDocFile(const base::FilePath& file_path, - const GURL& url, - const std::string& resource_id); - // Reads URL from a GDoc file. GURL ReadUrlFromGDocFile(const base::FilePath& file_path);
diff --git a/components/drive/file_system_core_util_unittest.cc b/components/drive/file_system_core_util_unittest.cc deleted file mode 100644 index 29e7d09..0000000 --- a/components/drive/file_system_core_util_unittest.cc +++ /dev/null
@@ -1,99 +0,0 @@ -// Copyright 2015 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/drive/file_system_core_util.h" - -#include <vector> - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/utf_string_conversions.h" -#include "base/threading/thread_task_runner_handle.h" -#include "content/public/test/browser_task_environment.h" -#include "google_apis/drive/test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { -namespace util { - -class FileSystemUtilTest : public testing::Test { - content::BrowserTaskEnvironment task_environment_; -}; - -TEST_F(FileSystemUtilTest, EscapeUnescapeCacheFileName) { - const std::string kUnescapedFileName( - R"(tmp:`~!@#$%^&*()-_=+[{|]}\\;',<.>/?)"); - const std::string kEscapedFileName( - R"(tmp:`~!@#$%25^&*()-_=+[{|]}\\;',<%2E>%2F?)"); - EXPECT_EQ(kEscapedFileName, EscapeCacheFileName(kUnescapedFileName)); - EXPECT_EQ(kUnescapedFileName, UnescapeCacheFileName(kEscapedFileName)); -} - -TEST_F(FileSystemUtilTest, NormalizeFileName) { - EXPECT_EQ("", NormalizeFileName("")); - EXPECT_EQ("foo", NormalizeFileName("foo")); - // Slash - EXPECT_EQ("foo_zzz", NormalizeFileName("foo/zzz")); - EXPECT_EQ("___", NormalizeFileName("///")); - // Japanese hiragana "hi" + semi-voiced-mark is normalized to "pi". - EXPECT_EQ("\xE3\x81\xB4", NormalizeFileName("\xE3\x81\xB2\xE3\x82\x9A")); - // Dot - EXPECT_EQ("_", NormalizeFileName(".")); - EXPECT_EQ("_", NormalizeFileName("..")); - EXPECT_EQ("_", NormalizeFileName("...")); - EXPECT_EQ(".bashrc", NormalizeFileName(".bashrc")); - EXPECT_EQ("._", NormalizeFileName("./")); -} - -TEST_F(FileSystemUtilTest, GDocFile) { - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - - GURL url( - "https://docs.google.com/document/d/" - "1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug/edit"); - std::string resource_id("1YsCnrMxxgp7LDdtlFDt-WdtEIth89vA9inrILtvK-Ug"); - - // Read and write gdoc. - base::FilePath file = temp_dir.GetPath().AppendASCII("test.gdoc"); - EXPECT_TRUE(CreateGDocFile(file, url, resource_id)); - EXPECT_EQ(url, ReadUrlFromGDocFile(file)); - EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file)); - - // Read and write gsheet. - file = temp_dir.GetPath().AppendASCII("test.gsheet"); - EXPECT_TRUE(CreateGDocFile(file, url, resource_id)); - EXPECT_EQ(url, ReadUrlFromGDocFile(file)); - EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file)); - - // Read and write gslides. - file = temp_dir.GetPath().AppendASCII("test.gslides"); - EXPECT_TRUE(CreateGDocFile(file, url, resource_id)); - EXPECT_EQ(url, ReadUrlFromGDocFile(file)); - EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file)); - - // Read and write gdraw. - file = temp_dir.GetPath().AppendASCII("test.gdraw"); - EXPECT_TRUE(CreateGDocFile(file, url, resource_id)); - EXPECT_EQ(url, ReadUrlFromGDocFile(file)); - EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file)); - - // Read and write gtable. - file = temp_dir.GetPath().AppendASCII("test.gtable"); - EXPECT_TRUE(CreateGDocFile(file, url, resource_id)); - EXPECT_EQ(url, ReadUrlFromGDocFile(file)); - EXPECT_EQ(resource_id, ReadResourceIdFromGDocFile(file)); - - // Non GDoc file. - file = temp_dir.GetPath().AppendASCII("test.txt"); - std::string data = "Hello world!"; - EXPECT_TRUE(google_apis::test_util::WriteStringToFile(file, data)); - EXPECT_TRUE(ReadUrlFromGDocFile(file).is_empty()); - EXPECT_TRUE(ReadResourceIdFromGDocFile(file).empty()); -} - -} // namespace util -} // namespace drive
diff --git a/components/drive/file_system_metadata.cc b/components/drive/file_system_metadata.cc deleted file mode 100644 index 67cb98f8..0000000 --- a/components/drive/file_system_metadata.cc +++ /dev/null
@@ -1,14 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/file_system_metadata.h" - -namespace drive { - -FileSystemMetadata::FileSystemMetadata() - : refreshing(false), last_update_check_error(FILE_ERROR_OK) {} - -FileSystemMetadata::~FileSystemMetadata() = default; - -} // namespace drive
diff --git a/components/drive/file_system_metadata.h b/components/drive/file_system_metadata.h deleted file mode 100644 index 54156d2..0000000 --- a/components/drive/file_system_metadata.h +++ /dev/null
@@ -1,41 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_FILE_SYSTEM_METADATA_H_ -#define COMPONENTS_DRIVE_FILE_SYSTEM_METADATA_H_ - -#include <stdint.h> -#include <string> - -#include "base/time/time.h" -#include "components/drive/file_errors.h" - -namespace drive { - -// Metadata of FileSystem. Used by FileSystem::GetMetadata(). -struct FileSystemMetadata { - FileSystemMetadata(); - ~FileSystemMetadata(); - - // The start_page_token that the file system holds (may be different - // from the one on the server) - std::string start_page_token = ""; - - // True if the resource metadata is now being fetched from the server. - bool refreshing; - - // Time of the last update check. - base::Time last_update_check_time; - - // Error code of the last update check. - FileError last_update_check_error; - - // For team drives, this is the virtual path that the team drive is mounted - // at. - std::string path; -}; - -} // namespace drive - -#endif // COMPONENTS_DRIVE_FILE_SYSTEM_METADATA_H_
diff --git a/components/drive/file_write_watcher.cc b/components/drive/file_write_watcher.cc deleted file mode 100644 index 21ecee9..0000000 --- a/components/drive/file_write_watcher.cc +++ /dev/null
@@ -1,194 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/file_write_watcher.h" - -#include <stddef.h> -#include <stdint.h> - -#include <map> -#include <vector> - -#include "base/bind.h" -#include "base/callback.h" -#include "base/files/file_path_watcher.h" -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/sequenced_task_runner.h" -#include "base/timer/timer.h" -#include "google_apis/drive/task_util.h" - -namespace drive { -namespace internal { - -namespace { -const int64_t kWriteEventDelayInSeconds = 5; -} // namespace - -// base::FileWatcher needs to live in a thread that is allowed to do File IO -// and has a TYPE_IO message loop: that is, FILE thread. This class bridges the -// UI thread and FILE thread, and does all the main tasks in the FILE thread. -class FileWriteWatcher::FileWriteWatcherImpl { - public: - explicit FileWriteWatcherImpl( - base::SequencedTaskRunner* blocking_task_runner); - - // Forwards the call to DestoryOnBlockingThread(). This method must be used - // to destruct the instance. - void Destroy(); - - // Forwards the call to StartWatchOnBlockingThread(). |on_start_callback| is - // called back on the caller (UI) thread when the watch has started. - // |on_write_callback| is called when a write has happened to the path. - void StartWatch(const base::FilePath& path, - const StartWatchCallback& on_start_callback, - const base::Closure& on_write_callback); - - void set_delay(base::TimeDelta delay) { delay_ = delay; } - - private: - ~FileWriteWatcherImpl(); - - void DestroyOnBlockingThread(); - - void StartWatchOnBlockingThread(const base::FilePath& path, - const StartWatchCallback& on_start_callback, - const base::Closure& on_write_callback); - - void OnWriteEvent(const base::FilePath& path, bool error); - - void InvokeCallback(const base::FilePath& path); - - struct PathWatchInfo { - std::vector<base::Closure> on_write_callbacks; - base::FilePathWatcher watcher; - base::OneShotTimer timer; - - explicit PathWatchInfo(const base::Closure& on_write_callback) - : on_write_callbacks(1, on_write_callback) {} - }; - - base::TimeDelta delay_; - std::map<base::FilePath, std::unique_ptr<PathWatchInfo>> watchers_; - scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; - - base::ThreadChecker thread_checker_; - - // Note: This should remain the last member so it'll be destroyed and - // invalidate its weak pointers before any other members are destroyed. - base::WeakPtrFactory<FileWriteWatcherImpl> weak_ptr_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(FileWriteWatcherImpl); -}; - -FileWriteWatcher::FileWriteWatcherImpl::FileWriteWatcherImpl( - base::SequencedTaskRunner* blocking_task_runner) - : delay_(base::TimeDelta::FromSeconds(kWriteEventDelayInSeconds)), - blocking_task_runner_(blocking_task_runner) {} - -void FileWriteWatcher::FileWriteWatcherImpl::Destroy() { - DCHECK(thread_checker_.CalledOnValidThread()); - - // Just forwarding the call to FILE thread. - blocking_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&FileWriteWatcherImpl::DestroyOnBlockingThread, - base::Unretained(this))); -} - -void FileWriteWatcher::FileWriteWatcherImpl::StartWatch( - const base::FilePath& path, - const StartWatchCallback& on_start_callback, - const base::Closure& on_write_callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - - // Forwarding the call to FILE thread and relaying the |callback|. - blocking_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&FileWriteWatcherImpl::StartWatchOnBlockingThread, - base::Unretained(this), path, - google_apis::CreateRelayCallback(on_start_callback), - google_apis::CreateRelayCallback(on_write_callback))); -} - -FileWriteWatcher::FileWriteWatcherImpl::~FileWriteWatcherImpl() = default; - -void FileWriteWatcher::FileWriteWatcherImpl::DestroyOnBlockingThread() { - delete this; -} - -void FileWriteWatcher::FileWriteWatcherImpl::StartWatchOnBlockingThread( - const base::FilePath& path, - const StartWatchCallback& on_start_callback, - const base::Closure& on_write_callback) { - auto it = watchers_.find(path); - if (it != watchers_.end()) { - // We are already watching the path. - on_start_callback.Run(true); - it->second->on_write_callbacks.push_back(on_write_callback); - return; - } - - // Start watching |path|. - std::unique_ptr<PathWatchInfo> info = - std::make_unique<PathWatchInfo>(on_write_callback); - bool ok = info->watcher.Watch( - path, - false, // recursive - base::Bind(&FileWriteWatcherImpl::OnWriteEvent, - weak_ptr_factory_.GetWeakPtr())); - watchers_[path] = std::move(info); - on_start_callback.Run(ok); -} - -void FileWriteWatcher::FileWriteWatcherImpl::OnWriteEvent( - const base::FilePath& path, - bool error) { - if (error) - return; - - auto it = watchers_.find(path); - DCHECK(it != watchers_.end()); - - // Heuristics for detecting the end of successive write operations. - // Delay running on_write_event_callback by |delay_| time, and if OnWriteEvent - // is called again in the period, the timer is reset. In other words, we - // invoke callback when |delay_| has passed after the last OnWriteEvent(). - it->second->timer.Start(FROM_HERE, delay_, - base::BindOnce(&FileWriteWatcherImpl::InvokeCallback, - weak_ptr_factory_.GetWeakPtr(), path)); -} - -void FileWriteWatcher::FileWriteWatcherImpl::InvokeCallback( - const base::FilePath& path) { - auto it = watchers_.find(path); - DCHECK(it != watchers_.end()); - - std::vector<base::Closure> callbacks; - callbacks.swap(it->second->on_write_callbacks); - watchers_.erase(it); - - for (const auto& callback : callbacks) - callback.Run(); -} - -FileWriteWatcher::FileWriteWatcher( - base::SequencedTaskRunner* blocking_task_runner) - : watcher_impl_(new FileWriteWatcherImpl(blocking_task_runner)) {} - -FileWriteWatcher::~FileWriteWatcher() { - DCHECK(thread_checker_.CalledOnValidThread()); -} - -void FileWriteWatcher::StartWatch(const base::FilePath& file_path, - const StartWatchCallback& on_start_callback, - const base::Closure& on_write_callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - watcher_impl_->StartWatch(file_path, on_start_callback, on_write_callback); -} - -void FileWriteWatcher::DisableDelayForTesting() { - watcher_impl_->set_delay(base::TimeDelta()); -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/file_write_watcher.h b/components/drive/file_write_watcher.h deleted file mode 100644 index 1b3a5c7..0000000 --- a/components/drive/file_write_watcher.h +++ /dev/null
@@ -1,68 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_FILE_WRITE_WATCHER_H_ -#define COMPONENTS_DRIVE_FILE_WRITE_WATCHER_H_ - -#include <memory> - -#include "base/callback_forward.h" -#include "base/macros.h" -#include "base/threading/thread_checker.h" -#include "components/drive/file_system_core_util.h" - -namespace base { -class FilePath; -class SequencedTaskRunner; -} // namespace base - -namespace drive { - -namespace internal { - -typedef base::Callback<void(bool)> StartWatchCallback; - -// The class watches modification to Drive files in the cache directory. -// This is used for returning a local writable snapshot of Drive files from the -// Save-As file dialog, so that the callers of the dialog can save to Drive -// without any special handling about Drive. -class FileWriteWatcher { - public: - explicit FileWriteWatcher(base::SequencedTaskRunner* blocking_task_runner); - ~FileWriteWatcher(); - - // Starts watching the modification to |path|. When it successfully started - // watching, it runs |on_start_callback| by passing true as the argument. - // Or if it failed, the callback is run with false. - // Detected modification is notified by calling |on_write_callback|. - // - // Currently, the modification is watched in "one-shot" manner. That is, once - // a modification is notified, the watch is deactivated for freeing system - // resources. As a heuristic to capture the real end of write operations that - // might be done by several chunked writes, the notification is fired after - // 5 seconds has passed after the last write operation is detected. - // - // TODO(kinaba): investigate the possibility to continuously watch the whole - // cache directory. http://crbug.com/269424 - void StartWatch(const base::FilePath& path, - const StartWatchCallback& on_start_callback, - const base::Closure& on_write_callback); - - // For testing purpose, stops inserting delay between the write detection and - // notification to the |on_write_callback|. - void DisableDelayForTesting(); - - private: - class FileWriteWatcherImpl; - std::unique_ptr<FileWriteWatcherImpl, util::DestroyHelper> watcher_impl_; - - base::ThreadChecker thread_checker_; - - DISALLOW_COPY_AND_ASSIGN(FileWriteWatcher); -}; - -} // namespace internal -} // namespace drive - -#endif // COMPONENTS_DRIVE_FILE_WRITE_WATCHER_H_
diff --git a/components/drive/file_write_watcher_unittest.cc b/components/drive/file_write_watcher_unittest.cc deleted file mode 100644 index 43f4619..0000000 --- a/components/drive/file_write_watcher_unittest.cc +++ /dev/null
@@ -1,123 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/file_write_watcher.h" - -#include <set> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/run_loop.h" -#include "base/stl_util.h" -#include "base/task/post_task.h" -#include "content/public/browser/browser_thread.h" -#include "content/public/test/browser_task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { -namespace internal { - -namespace { - -class TestObserver { - public: - // After all the resource_ids in |expected_upload| are notified for the - // need of uploading, runs |quit_closure|. Also checks that each id is - // notified only once. - TestObserver(const std::set<std::string>& expected_upload, - const base::Closure& quit_closure) - : expected_upload_(expected_upload), - quit_closure_(quit_closure) { - } - - void OnWrite(const std::string& id) { - EXPECT_EQ(1U, expected_upload_.count(id)) << id; - expected_upload_.erase(id); - if (expected_upload_.empty()) - quit_closure_.Run(); - } - - private: - std::set<std::string> expected_upload_; - base::Closure quit_closure_; -}; - -// Writes something on the file at |path|. -void WriteSomethingAfterStartWatch(const base::FilePath& path, - bool watch_success) { - EXPECT_TRUE(watch_success) << path.value(); - - const char kDummy[] = "hello"; - ASSERT_EQ(static_cast<int>(base::size(kDummy)), - base::WriteFile(path, kDummy, base::size(kDummy))); -} - -class FileWriteWatcherTest : public testing::Test { - protected: - // The test requires UI thread (FileWriteWatcher DCHECKs that its public - // interface is running on UI thread) and FILE thread (Linux version of - // base::FilePathWatcher needs to live on an IOAllowed thread with TYPE_IO, - // which is FILE thread in the production environment). - // - // By using the IO_MAINLOOP test thread bundle, the main thread is used - // both as UI and FILE thread, with TYPE_IO message loop. - FileWriteWatcherTest() - : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP) {} - - void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); } - - base::FilePath GetTempPath(const std::string& name) { - return temp_dir_.GetPath().Append(name); - } - - private: - content::BrowserTaskEnvironment task_environment_; - base::ScopedTempDir temp_dir_; -}; - -} // namespace - -TEST_F(FileWriteWatcherTest, WatchThreeFiles) { - std::set<std::string> expected; - expected.insert("1"); - expected.insert("2"); - expected.insert("3"); - - base::RunLoop loop; - TestObserver observer(expected, loop.QuitClosure()); - - // Set up the watcher. - scoped_refptr<base::SequencedTaskRunner> task_runner = - base::CreateSequencedTaskRunner({base::ThreadPool(), base::MayBlock()}); - FileWriteWatcher watcher(task_runner.get()); - watcher.DisableDelayForTesting(); - - // Start watching and running. - base::FilePath path1 = GetTempPath("foo.txt"); - base::FilePath path2 = GetTempPath("bar.png"); - base::FilePath path3 = GetTempPath("buz.doc"); - base::FilePath path4 = GetTempPath("mya.mp3"); - watcher.StartWatch( - path1, - base::Bind(&WriteSomethingAfterStartWatch, path1), - base::Bind(&TestObserver::OnWrite, base::Unretained(&observer), "1")); - watcher.StartWatch( - path2, - base::Bind(&WriteSomethingAfterStartWatch, path2), - base::Bind(&TestObserver::OnWrite, base::Unretained(&observer), "2")); - watcher.StartWatch( - path3, - base::Bind(&WriteSomethingAfterStartWatch, path3), - base::Bind(&TestObserver::OnWrite, base::Unretained(&observer), "3")); - - // Unwatched write. It shouldn't be notified. - WriteSomethingAfterStartWatch(path4, true); - - // The loop should quit if all the three paths are notified to be written. - loop.Run(); -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/job_list.cc b/components/drive/job_list.cc deleted file mode 100644 index 91aaf42..0000000 --- a/components/drive/job_list.cc +++ /dev/null
@@ -1,137 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/job_list.h" - -#include "base/logging.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" - -namespace drive { - -std::string JobTypeToString(JobType type) { - switch (type){ - case TYPE_GET_ABOUT_RESOURCE: - return "TYPE_GET_ABOUT_RESOURCE"; - case TYPE_GET_APP_LIST: - return "TYPE_GET_APP_LIST"; - case TYPE_GET_ALL_TEAM_DRIVE_LIST: - return "TYPE_GET_ALL_TEAM_DRIVE_LIST"; - case TYPE_GET_ALL_RESOURCE_LIST: - return "TYPE_GET_ALL_RESOURCE_LIST"; - case TYPE_GET_RESOURCE_LIST_IN_DIRECTORY: - return "TYPE_GET_RESOURCE_LIST_IN_DIRECTORY"; - case TYPE_SEARCH: - return "TYPE_SEARCH"; - case TYPE_GET_CHANGE_LIST: - return "TYPE_GET_CHANGE_LIST"; - case TYPE_GET_START_PAGE_TOKEN: - return "TYPE_GET_START_PAGE_TOKEN"; - case TYPE_GET_REMAINING_CHANGE_LIST: - return "TYPE_GET_REMAINING_CHANGE_LIST"; - case TYPE_GET_REMAINING_TEAM_DRIVE_LIST: - return "TYPE_GET_REMAINING_TEAM_DRIVE_LIST"; - case TYPE_GET_REMAINING_FILE_LIST: - return "TYPE_GET_REMAINING_FILE_LIST"; - case TYPE_GET_RESOURCE_ENTRY: - return "TYPE_GET_RESOURCE_ENTRY"; - case TYPE_GET_SHARE_URL: - return "TYPE_GET_SHARE_URL"; - case TYPE_TRASH_RESOURCE: - return "TYPE_TRASH_RESOURCE"; - case TYPE_COPY_RESOURCE: - return "TYPE_COPY_RESOURCE"; - case TYPE_UPDATE_RESOURCE: - return "TYPE_UPDATE_RESOURCE"; - case TYPE_ADD_RESOURCE_TO_DIRECTORY: - return "TYPE_ADD_RESOURCE_TO_DIRECTORY"; - case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY: - return "TYPE_REMOVE_RESOURCE_FROM_DIRECTORY"; - case TYPE_ADD_NEW_DIRECTORY: - return "TYPE_ADD_NEW_DIRECTORY"; - case TYPE_DOWNLOAD_FILE: - return "TYPE_DOWNLOAD_FILE"; - case TYPE_UPLOAD_NEW_FILE: - return "TYPE_UPLOAD_NEW_FILE"; - case TYPE_UPLOAD_EXISTING_FILE: - return "TYPE_UPLOAD_EXISTING_FILE"; - case TYPE_ADD_PERMISSION: - return "TYPE_ADD_PERMISSION"; - } - NOTREACHED(); - return "(unknown job type)"; -} - -std::string JobStateToString(JobState state) { - switch (state) { - case STATE_NONE: - return "STATE_NONE"; - case STATE_RUNNING: - return "STATE_RUNNING"; - case STATE_RETRY: - return "STATE_RETRY"; - } - NOTREACHED(); - return "(unknown job state)"; -} - -JobInfo::JobInfo(JobType in_job_type) - : job_type(in_job_type), - job_id(-1), - state(STATE_NONE), - num_completed_bytes(0), - num_total_bytes(0) { -} - -std::string JobInfo::ToString() const { - std::string output = base::StringPrintf( - "%s %s [%d]", - JobTypeToString(job_type).c_str(), - JobStateToString(state).c_str(), - job_id); - if (job_type == TYPE_DOWNLOAD_FILE || - job_type == TYPE_UPLOAD_NEW_FILE || - job_type == TYPE_UPLOAD_EXISTING_FILE) { - base::StringAppendF(&output, " bytes: %s/%s", - base::NumberToString(num_completed_bytes).c_str(), - base::NumberToString(num_total_bytes).c_str()); - } - return output; -} - -bool IsActiveFileTransferJobInfo(const JobInfo& job_info) { - // Using switch statement so that compiler can warn when new states or types - // are added. - switch (job_info.job_type) { - case TYPE_GET_ABOUT_RESOURCE: - case TYPE_GET_START_PAGE_TOKEN: - case TYPE_GET_APP_LIST: - case TYPE_GET_ALL_TEAM_DRIVE_LIST: - case TYPE_GET_ALL_RESOURCE_LIST: - case TYPE_GET_RESOURCE_LIST_IN_DIRECTORY: - case TYPE_SEARCH: - case TYPE_GET_CHANGE_LIST: - case TYPE_GET_REMAINING_CHANGE_LIST: - case TYPE_GET_REMAINING_TEAM_DRIVE_LIST: - case TYPE_GET_REMAINING_FILE_LIST: - case TYPE_GET_RESOURCE_ENTRY: - case TYPE_GET_SHARE_URL: - case TYPE_TRASH_RESOURCE: - case TYPE_COPY_RESOURCE: - case TYPE_UPDATE_RESOURCE: - case TYPE_ADD_RESOURCE_TO_DIRECTORY: - case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY: - case TYPE_ADD_NEW_DIRECTORY: - case TYPE_ADD_PERMISSION: - return false; - case TYPE_DOWNLOAD_FILE: - case TYPE_UPLOAD_NEW_FILE: - case TYPE_UPLOAD_EXISTING_FILE: - break; - } - - return true; -} - -} // namespace drive
diff --git a/components/drive/job_list.h b/components/drive/job_list.h deleted file mode 100644 index ce178448..0000000 --- a/components/drive/job_list.h +++ /dev/null
@@ -1,144 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_JOB_LIST_H_ -#define COMPONENTS_DRIVE_JOB_LIST_H_ - -#include <stdint.h> - -#include <string> -#include <vector> - -#include "base/files/file_path.h" -#include "components/drive/file_errors.h" - -namespace drive { - -// Enum representing the type of job. -enum JobType { - TYPE_GET_ABOUT_RESOURCE, - TYPE_GET_APP_LIST, - TYPE_GET_ALL_TEAM_DRIVE_LIST, - TYPE_GET_ALL_RESOURCE_LIST, - TYPE_GET_RESOURCE_LIST_IN_DIRECTORY, - TYPE_SEARCH, - TYPE_GET_CHANGE_LIST, - TYPE_GET_START_PAGE_TOKEN, - TYPE_GET_REMAINING_CHANGE_LIST, - TYPE_GET_REMAINING_TEAM_DRIVE_LIST, - TYPE_GET_REMAINING_FILE_LIST, - TYPE_GET_RESOURCE_ENTRY, - TYPE_GET_SHARE_URL, - TYPE_TRASH_RESOURCE, - TYPE_COPY_RESOURCE, - TYPE_UPDATE_RESOURCE, - TYPE_ADD_RESOURCE_TO_DIRECTORY, - TYPE_REMOVE_RESOURCE_FROM_DIRECTORY, - TYPE_ADD_NEW_DIRECTORY, - TYPE_DOWNLOAD_FILE, - TYPE_UPLOAD_NEW_FILE, - TYPE_UPLOAD_EXISTING_FILE, - TYPE_ADD_PERMISSION, -}; - -// Returns the string representation of |type|. -std::string JobTypeToString(JobType type); - -// Current state of the job. -enum JobState { - // The job is queued, but not yet executed. - STATE_NONE, - - // The job is in the process of being handled. - STATE_RUNNING, - - // The job failed, but has been re-added to the queue. - STATE_RETRY, -}; - -// Returns the string representation of |state|. -std::string JobStateToString(JobState state); - -// Unique ID assigned to each job. -typedef int32_t JobID; - -// Information about a specific job that is visible to other systems. -struct JobInfo { - explicit JobInfo(JobType job_type); - - // Type of the job. - JobType job_type; - - // Id of the job, which can be used to query or modify it. - JobID job_id; - - // Current state of the operation. - JobState state; - - // The fields below are available only for jobs with job_type: - // TYPE_DOWNLOAD_FILE, TYPE_UPLOAD_NEW_FILE, or TYPE_UPLOAD_EXISTING_FILE. - - // Number of bytes completed. - int64_t num_completed_bytes; - - // Total bytes of this operation. - int64_t num_total_bytes; - - // Drive path of the file that this job acts on. - base::FilePath file_path; - - // Time when the job is started (i.e. the request is sent to the server). - base::Time start_time; - - // Returns the string representation of the job info. - std::string ToString() const; -}; - -// Checks if |job_info| represents a job for currently active file transfer. -bool IsActiveFileTransferJobInfo(const JobInfo& job_info); - -// The interface for observing JobListInterface. -// All events are notified in the UI thread. -class JobListObserver { - public: - // Called when a new job id added. - virtual void OnJobAdded(const JobInfo& job_info) {} - - // Called when a job id finished. - // |error| is FILE_ERROR_OK when the job successfully finished, and a value - // telling the reason of failure when the jobs is failed. - virtual void OnJobDone(const JobInfo& job_info, - FileError error) {} - - // Called when a job status is updated. - virtual void OnJobUpdated(const JobInfo& job_info) {} - - protected: - virtual ~JobListObserver() = default; -}; - -// The interface to expose the list of issued Drive jobs. -class JobListInterface { - public: - virtual ~JobListInterface() = default; - - // Returns the list of jobs currently managed by the scheduler. - virtual std::vector<JobInfo> GetJobInfoList() = 0; - - // Adds an observer. - virtual void AddObserver(JobListObserver* observer) = 0; - - // Removes an observer. - virtual void RemoveObserver(JobListObserver* observer) = 0; - - // Cancels the job. - virtual void CancelJob(JobID job_id) = 0; - - // Cancels all the jobs. - virtual void CancelAllJobs() = 0; -}; - -} // namespace drive - -#endif // COMPONENTS_DRIVE_JOB_LIST_H_
diff --git a/components/drive/job_queue.cc b/components/drive/job_queue.cc deleted file mode 100644 index 5a5aa8b..0000000 --- a/components/drive/job_queue.cc +++ /dev/null
@@ -1,106 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/job_queue.h" - -#include <algorithm> - -#include "base/logging.h" -#include "base/strings/stringprintf.h" - -namespace drive { - -JobQueue::Item::Item() : batchable(false), size(0) { -} - -JobQueue::Item::Item(JobID id, bool batchable, uint64_t size) - : id(id), batchable(batchable), size(size) {} - -JobQueue::Item::~Item() = default; - -JobQueue::JobQueue(size_t num_max_concurrent_jobs, - size_t num_priority_levels, - size_t num_max_batch_jobs, - size_t max_batch_size) - : num_max_concurrent_jobs_(num_max_concurrent_jobs), - queue_(num_priority_levels), - num_max_batch_jobs_(num_max_batch_jobs), - max_batch_size_(max_batch_size) { -} - -JobQueue::~JobQueue() = default; - -void JobQueue::PopForRun(int accepted_priority, std::vector<JobID>* jobs) { - DCHECK_LT(accepted_priority, static_cast<int>(queue_.size())); - jobs->clear(); - - // Too many jobs are running already. - if (running_.size() >= num_max_concurrent_jobs_) - return; - - // Looks up the queue in the order of priority upto |accepted_priority|. - uint64_t total_size = 0; - bool batchable = true; - for (int priority = 0; priority <= accepted_priority; ++priority) { - while (!queue_[priority].empty()) { - const auto& item = queue_[priority].front(); - total_size += item.size; - batchable = batchable && item.batchable && - jobs->size() < num_max_batch_jobs_ && - total_size <= max_batch_size_; - if (!(jobs->empty() || batchable)) - return; - jobs->push_back(item.id); - running_.insert(item.id); - queue_[priority].pop_front(); - } - } -} - -void JobQueue::GetQueuedJobs(int priority, std::vector<JobID>* jobs) const { - DCHECK_LT(priority, static_cast<int>(queue_.size())); - jobs->clear(); - for (const Item& item : queue_[priority]) { - jobs->push_back(item.id); - } -} - -void JobQueue::Push(JobID id, int priority, bool batchable, uint64_t size) { - DCHECK_LT(priority, static_cast<int>(queue_.size())); - queue_[priority].push_back(Item(id, batchable, size)); -} - -void JobQueue::MarkFinished(JobID id) { - size_t num_erased = running_.erase(id); - DCHECK_EQ(1U, num_erased); -} - -std::string JobQueue::ToString() const { - size_t pending = 0; - for (size_t i = 0; i < queue_.size(); ++i) - pending += queue_[i].size(); - return base::StringPrintf("pending: %d, running: %d", - static_cast<int>(pending), - static_cast<int>(running_.size())); -} - -size_t JobQueue::GetNumberOfJobs() const { - size_t count = running_.size(); - for (size_t i = 0; i < queue_.size(); ++i) - count += queue_[i].size(); - return count; -} - -void JobQueue::Remove(JobID id) { - for (size_t i = 0; i < queue_.size(); ++i) { - for (auto it = queue_[i].begin(); it != queue_[i].end(); ++it) { - if (it->id == id) { - queue_[i].erase(it); - break; - } - } - } -} - -} // namespace drive
diff --git a/components/drive/job_queue.h b/components/drive/job_queue.h deleted file mode 100644 index 341527b..0000000 --- a/components/drive/job_queue.h +++ /dev/null
@@ -1,92 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_JOB_QUEUE_H_ -#define COMPONENTS_DRIVE_JOB_QUEUE_H_ - -#include <stddef.h> -#include <stdint.h> - -#include <set> -#include <vector> - -#include "base/containers/circular_deque.h" -#include "base/macros.h" -#include "components/drive/job_list.h" - -namespace drive { - -// Priority queue for managing jobs in JobScheduler. -class JobQueue { - public: - // Creates a queue that allows |num_max_concurrent_jobs| concurrent job - // execution and has |num_priority_levels| levels of priority. - JobQueue(size_t num_max_concurrent_jobs, - size_t num_priority_levels, - size_t num_max_batch_jobs, - size_t max_batch_size); - ~JobQueue(); - - // Pushes a job |id| of |priority|. The job with the smallest priority value - // is popped first (lower values are higher priority). In the same priority, - // the queue is "first-in first-out". If multiple jobs with |batchable| = true - // are pushed continuously, there will be popped at the same time unless the - // number of jobs exceeds |num_max_batch_jobs_| or the sum of |job_size| - // exceeds or |max_batch_size_|. - void Push(JobID id, int priority, bool batchable, uint64_t job_size); - - // Pops the first job which meets |accepted_priority| (i.e. the first job in - // the queue with equal or higher priority (lower value)), and the limit of - // concurrent job count is satisfied. - // - // For instance, if |accepted_priority| is 1, the first job with priority 0 - // (higher priority) in the queue is picked even if a job with priority 1 was - // pushed earlier. If there is no job with priority 0, the first job with - // priority 1 in the queue is picked. - // - // If the first found job and following jobs are batchable, these jobs are - // popped out at the same time unless the total size of jobs exceeds - // |max_batch_size_|. - void PopForRun(int accepted_priority, std::vector<JobID>* jobs); - - // Gets queued jobs with the given priority. - void GetQueuedJobs(int priority, std::vector<JobID>* jobs) const; - - // Marks a running job |id| as finished running. This decreases the count - // of running parallel jobs and makes room for other jobs to be popped. - void MarkFinished(JobID id); - - // Generates a string representing the internal state for logging. - std::string ToString() const; - - // Gets the total number of jobs in the queue. - size_t GetNumberOfJobs() const; - - // Removes the job from the queue. - void Remove(JobID id); - - private: - // JobID and additional properties that are needed to determine which tasks it - // runs next. - struct Item { - Item(); - Item(JobID id, bool batchable, uint64_t size); - ~Item(); - JobID id; - bool batchable; - uint64_t size; - }; - - const size_t num_max_concurrent_jobs_; - std::vector<base::circular_deque<Item>> queue_; - const size_t num_max_batch_jobs_; - const size_t max_batch_size_; - std::set<JobID> running_; - - DISALLOW_COPY_AND_ASSIGN(JobQueue); -}; - -} // namespace drive - -#endif // COMPONENTS_DRIVE_JOB_QUEUE_H_
diff --git a/components/drive/job_queue_unittest.cc b/components/drive/job_queue_unittest.cc deleted file mode 100644 index 1390b1f..0000000 --- a/components/drive/job_queue_unittest.cc +++ /dev/null
@@ -1,200 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/job_queue.h" - -#include <stddef.h> - -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { - -TEST(JobQueueTest, BasicJobQueueOperations) { - const size_t kNumMaxConcurrentJobs = 3; - const size_t kNumPriorityLevels = 2; - const size_t kNumMaxBatchJob = 0; - const size_t kMaxBatchSize = 0; - enum {HIGH_PRIORITY, LOW_PRIORITY}; - - // Create a queue. Number of jobs are initially zero. - JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob, - kMaxBatchSize); - EXPECT_EQ(0U, queue.GetNumberOfJobs()); - - // Push 4 jobs. - queue.Push(101, LOW_PRIORITY, false, 0); - queue.Push(102, HIGH_PRIORITY, false, 0); - queue.Push(103, LOW_PRIORITY, false, 0); - queue.Push(104, HIGH_PRIORITY, false, 0); - - // High priority jobs should be popped first. - std::vector<JobID> ids; - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(102, ids[0]); - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(104, ids[0]); - - // Then low priority jobs follow. - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(101, ids[0]); - - // The queue allows at most 3 parallel runs. So returns false here. - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(0u, ids.size()); - - // No jobs finished yet, so the job count is four. - EXPECT_EQ(4U, queue.GetNumberOfJobs()); - - // Mark one job as finished. - queue.MarkFinished(104); - EXPECT_EQ(3U, queue.GetNumberOfJobs()); - - // Then the next jobs can be popped. - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(103, ids[0]); - - // Push 1 more job. - queue.Push(105, LOW_PRIORITY, false, 0); - - // Finish all 3 running jobs. - queue.MarkFinished(101); - queue.MarkFinished(102); - queue.MarkFinished(103); - EXPECT_EQ(1U, queue.GetNumberOfJobs()); - - // The remaining jobs is of low priority, so under HIGH_PRIORITY context, it - // cannot be popped for running. - queue.PopForRun(HIGH_PRIORITY, &ids); - ASSERT_EQ(0u, ids.size()); - - // Under the low priority context, it is fine. - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(105, ids[0]); -} - -TEST(JobQueueTest, JobQueueRemove) { - const size_t kNumMaxConcurrentJobs = 3; - const size_t kNumPriorityLevels = 2; - const size_t kNumMaxBatchJob = 0; - const size_t kMaxBatchSize = 0; - enum {HIGH_PRIORITY, LOW_PRIORITY}; - - // Create a queue. Number of jobs are initially zero. - JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob, - kMaxBatchSize); - EXPECT_EQ(0U, queue.GetNumberOfJobs()); - - // Push 4 jobs. - queue.Push(101, LOW_PRIORITY, false, 0); - queue.Push(102, HIGH_PRIORITY, false, 0); - queue.Push(103, LOW_PRIORITY, false, 0); - queue.Push(104, HIGH_PRIORITY, false, 0); - EXPECT_EQ(4U, queue.GetNumberOfJobs()); - - // Remove 2. - queue.Remove(101); - queue.Remove(104); - EXPECT_EQ(2U, queue.GetNumberOfJobs()); - - // Pop the 2 jobs. - std::vector<JobID> ids; - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(102, ids[0]); - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(103, ids[0]); - queue.MarkFinished(102); - queue.MarkFinished(103); - - // 0 job left. - EXPECT_EQ(0U, queue.GetNumberOfJobs()); - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(0u, ids.size()); -} - -TEST(JobQueueTest, BatchRequest) { - const size_t kNumMaxConcurrentJobs = 1; - const size_t kNumPriorityLevels = 2; - const size_t kNumMaxBatchJob = 100; - const size_t kMaxBatchSize = 5; - enum { HIGH_PRIORITY, LOW_PRIORITY }; - - // Create a queue. Number of jobs are initially zero. - JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob, - kMaxBatchSize); - EXPECT_EQ(0U, queue.GetNumberOfJobs()); - - // Push 6 jobs. - queue.Push(101, LOW_PRIORITY, true, 1); - queue.Push(102, HIGH_PRIORITY, true, 1); - queue.Push(103, LOW_PRIORITY, false, 1); - queue.Push(104, HIGH_PRIORITY, true, 1); - queue.Push(105, LOW_PRIORITY, true, 1); - queue.Push(106, HIGH_PRIORITY, true, 10); - - EXPECT_EQ(6U, queue.GetNumberOfJobs()); - - // Pop the 6 jobs. - std::vector<JobID> ids; - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(2u, ids.size()); - EXPECT_EQ(102, ids[0]); - EXPECT_EQ(104, ids[1]); - queue.MarkFinished(102); - queue.MarkFinished(104); - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(106, ids[0]); - queue.MarkFinished(106); - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(101, ids[0]); - queue.MarkFinished(101); - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(103, ids[0]); - queue.MarkFinished(103); - queue.PopForRun(LOW_PRIORITY, &ids); - ASSERT_EQ(1u, ids.size()); - EXPECT_EQ(105, ids[0]); - queue.MarkFinished(105); - queue.PopForRun(LOW_PRIORITY, &ids); - EXPECT_EQ(0u, ids.size()); -} - -TEST(JobQueueTest, BatchRequstNumMaxJobs) { - const size_t kNumMaxConcurrentJobs = 1; - const size_t kNumPriorityLevels = 2; - const size_t kNumMaxBatchJob = 5; - const size_t kMaxBatchSize = 100; - enum { HIGH_PRIORITY, LOW_PRIORITY }; - - // Create a queue. Number of jobs are initially zero. - JobQueue queue(kNumMaxConcurrentJobs, kNumPriorityLevels, kNumMaxBatchJob, - kMaxBatchSize); - EXPECT_EQ(0U, queue.GetNumberOfJobs()); - - // Push 6 jobs. - queue.Push(101, LOW_PRIORITY, true, 1); - queue.Push(102, LOW_PRIORITY, true, 1); - queue.Push(103, LOW_PRIORITY, true, 1); - queue.Push(104, LOW_PRIORITY, true, 1); - queue.Push(105, LOW_PRIORITY, true, 1); - queue.Push(106, LOW_PRIORITY, true, 1); - - EXPECT_EQ(6U, queue.GetNumberOfJobs()); - - // Pop the 5 of 6 jobs. - std::vector<JobID> ids; - queue.PopForRun(LOW_PRIORITY, &ids); - EXPECT_EQ(5u, ids.size()); -} - -} // namespace drive
diff --git a/components/drive/job_scheduler.cc b/components/drive/job_scheduler.cc deleted file mode 100644 index e0cb534..0000000 --- a/components/drive/job_scheduler.cc +++ /dev/null
@@ -1,1202 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/job_scheduler.h" - -#include <stddef.h> -#include <algorithm> -#include <memory> -#include <utility> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/metrics/histogram_macros.h" -#include "base/rand_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/drive/drive_pref_names.h" -#include "components/drive/event_logger.h" -#include "components/prefs/pref_service.h" -#include "google_apis/drive/drive_api_parser.h" - -namespace drive { - -namespace { - -// All jobs are retried at maximum of kMaxRetryCount when they fail due to -// throttling or server error. The delay before retrying a job is shared among -// jobs. It doubles in length on each failure, upto 2^kMaxThrottleCount seconds. -// -// According to the API documentation, kMaxRetryCount should be the same as -// kMaxThrottleCount (https://developers.google.com/drive/handle-errors). -// But currently multiplied by 2 to ensure upload related jobs retried for a -// sufficient number of times. crbug.com/269918 -const int kMaxThrottleCount = 4; -const int kMaxRetryCount = 2 * kMaxThrottleCount; -const size_t kMaxBatchCount = 20; -const size_t kMaxBatchSize = 1024 * 1024 * 10; - -// GetDefaultValue returns a value constructed by the default constructor. -template<typename T> struct DefaultValueCreator { - static T GetDefaultValue() { return T(); } -}; -template<typename T> struct DefaultValueCreator<const T&> { - static T GetDefaultValue() { return T(); } -}; - -// Helper of CreateErrorRunCallback implementation. -// Provides: -// - ResultType; the type of the Callback which should be returned by -// CreateErrorRunCallback. -// - Run(): a static function which takes the original |callback| and |error|, -// and runs the |callback|.Run() with the error code and default values -// for remaining arguments. -template<typename CallbackType> struct CreateErrorRunCallbackHelper; - -// CreateErrorRunCallback with two arguments. -template<typename P1> -struct CreateErrorRunCallbackHelper<void(google_apis::DriveApiErrorCode, P1)> { - static void Run( - const base::Callback<void(google_apis::DriveApiErrorCode, P1)>& callback, - google_apis::DriveApiErrorCode error) { - callback.Run(error, DefaultValueCreator<P1>::GetDefaultValue()); - } -}; - -// Returns a callback with the tail parameter bound to its default value. -// In other words, returned_callback.Run(error) runs callback.Run(error, T()). -template<typename CallbackType> -base::Callback<void(google_apis::DriveApiErrorCode)> -CreateErrorRunCallback(const base::Callback<CallbackType>& callback) { - return base::Bind(&CreateErrorRunCallbackHelper<CallbackType>::Run, callback); -} - -// Parameter struct for RunUploadNewFile. -struct UploadNewFileParams { - std::string parent_resource_id; - base::FilePath local_file_path; - std::string title; - std::string content_type; - UploadNewFileOptions options; - UploadCompletionCallback callback; - google_apis::ProgressCallback progress_callback; -}; - -// Helper function to work around the arity limitation of base::Bind. -google_apis::CancelCallback RunUploadNewFile( - DriveUploaderInterface* uploader, - const UploadNewFileParams& params) { - return uploader->UploadNewFile(params.parent_resource_id, - params.local_file_path, - params.title, - params.content_type, - params.options, - params.callback, - params.progress_callback); -} - -// Parameter struct for RunUploadExistingFile. -struct UploadExistingFileParams { - std::string resource_id; - base::FilePath local_file_path; - std::string content_type; - UploadExistingFileOptions options; - std::string etag; - UploadCompletionCallback callback; - google_apis::ProgressCallback progress_callback; -}; - -// Helper function to work around the arity limitation of base::Bind. -google_apis::CancelCallback RunUploadExistingFile( - DriveUploaderInterface* uploader, - const UploadExistingFileParams& params) { - return uploader->UploadExistingFile(params.resource_id, - params.local_file_path, - params.content_type, - params.options, - params.callback, - params.progress_callback); -} - -// Parameter struct for RunResumeUploadFile. -struct ResumeUploadFileParams { - GURL upload_location; - base::FilePath local_file_path; - std::string content_type; - UploadCompletionCallback callback; - google_apis::ProgressCallback progress_callback; -}; - -// Helper function to adjust the return type. -google_apis::CancelCallback RunResumeUploadFile( - DriveUploaderInterface* uploader, - const ResumeUploadFileParams& params) { - return uploader->ResumeUploadFile(params.upload_location, - params.local_file_path, - params.content_type, - params.callback, - params.progress_callback); -} - -} // namespace - -// Metadata jobs are cheap, so we run them concurrently. File jobs run serially. -const int JobScheduler::kMaxJobCount[] = { - 20, // METADATA_QUEUE - 1, // FILE_QUEUE -}; - -JobScheduler::JobEntry::JobEntry(JobType type) - : job_info(type), - context(ClientContext(USER_INITIATED)), - retry_count(0) { -} - -JobScheduler::JobEntry::~JobEntry() { - DCHECK(thread_checker_.CalledOnValidThread()); -} - -struct JobScheduler::ResumeUploadParams { - base::FilePath drive_file_path; - base::FilePath local_file_path; - std::string content_type; -}; - -JobScheduler::JobScheduler( - PrefService* pref_service, - EventLogger* logger, - DriveServiceInterface* drive_service, - network::NetworkConnectionTracker* network_connection_tracker, - base::SequencedTaskRunner* blocking_task_runner, - mojo::PendingRemote<device::mojom::WakeLockProvider> wake_lock_provider) - : throttle_count_(0), - wait_until_(base::Time::Now()), - disable_throttling_(false), - logger_(logger), - drive_service_(drive_service), - network_connection_tracker_(network_connection_tracker), - blocking_task_runner_(blocking_task_runner), - uploader_(new DriveUploader(drive_service, - blocking_task_runner, - std::move(wake_lock_provider))), - pref_service_(pref_service) { - for (int i = 0; i < NUM_QUEUES; ++i) - queue_[i] = std::make_unique<JobQueue>(kMaxJobCount[i], NUM_CONTEXT_TYPES, - kMaxBatchCount, kMaxBatchSize); - - network_connection_tracker_->AddNetworkConnectionObserver(this); -} - -JobScheduler::~JobScheduler() { - DCHECK(thread_checker_.CalledOnValidThread()); - - size_t num_queued_jobs = 0; - for (int i = 0; i < NUM_QUEUES; ++i) - num_queued_jobs += queue_[i]->GetNumberOfJobs(); - DCHECK_EQ(num_queued_jobs, job_map_.size()); - - network_connection_tracker_->RemoveNetworkConnectionObserver(this); -} - -std::vector<JobInfo> JobScheduler::GetJobInfoList() { - std::vector<JobInfo> job_info_list; - for (JobIDMap::iterator iter(&job_map_); !iter.IsAtEnd(); iter.Advance()) - job_info_list.push_back(iter.GetCurrentValue()->job_info); - return job_info_list; -} - -void JobScheduler::AddObserver(JobListObserver* observer) { - DCHECK(thread_checker_.CalledOnValidThread()); - observer_list_.AddObserver(observer); -} - -void JobScheduler::RemoveObserver(JobListObserver* observer) { - DCHECK(thread_checker_.CalledOnValidThread()); - observer_list_.RemoveObserver(observer); -} - -void JobScheduler::CancelJob(JobID job_id) { - DCHECK(thread_checker_.CalledOnValidThread()); - - JobEntry* job = job_map_.Lookup(job_id); - if (job) { - if (job->job_info.state == STATE_RUNNING) { - // If the job is running an HTTP request, cancel it via |cancel_callback| - // returned from the request, and wait for termination in the normal - // callback handler, OnJobDone. - if (!job->cancel_callback.is_null()) - job->cancel_callback.Run(); - } else { - AbortNotRunningJob(job, google_apis::DRIVE_CANCELLED); - } - } -} - -void JobScheduler::CancelAllJobs() { - DCHECK(thread_checker_.CalledOnValidThread()); - - // CancelJob may remove the entry from |job_map_|. That's OK. IDMap supports - // removable during iteration. - for (JobIDMap::iterator iter(&job_map_); !iter.IsAtEnd(); iter.Advance()) - CancelJob(iter.GetCurrentKey()); -} - -void JobScheduler::GetAboutResource( - const google_apis::AboutResourceCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_GET_ABOUT_RESOURCE); - new_job->task = base::Bind( - &DriveServiceInterface::GetAboutResource, - base::Unretained(drive_service_), - base::Bind(&JobScheduler::OnGetAboutResourceJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::GetStartPageToken( - const std::string& team_drive_id, - const google_apis::StartPageTokenCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_GET_START_PAGE_TOKEN); - new_job->task = base::BindRepeating( - &DriveServiceInterface::GetStartPageToken, - base::Unretained(drive_service_), team_drive_id, - base::BindRepeating(&JobScheduler::OnGetStartPageTokenDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::GetAllTeamDriveList( - const google_apis::TeamDriveListCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - JobEntry* new_job = CreateNewJob(TYPE_GET_ALL_TEAM_DRIVE_LIST); - new_job->task = - base::Bind(&DriveServiceInterface::GetAllTeamDriveList, - base::Unretained(drive_service_), - base::Bind(&JobScheduler::OnGetTeamDriveListJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::GetAllFileList( - const std::string& team_drive_id, - const google_apis::FileListCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_GET_ALL_RESOURCE_LIST); - new_job->task = base::Bind(&DriveServiceInterface::GetAllFileList, - base::Unretained(drive_service_), team_drive_id, - base::Bind(&JobScheduler::OnGetFileListJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::GetFileListInDirectory( - const std::string& directory_resource_id, - const google_apis::FileListCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob( - TYPE_GET_RESOURCE_LIST_IN_DIRECTORY); - new_job->task = base::Bind( - &DriveServiceInterface::GetFileListInDirectory, - base::Unretained(drive_service_), - directory_resource_id, - base::Bind(&JobScheduler::OnGetFileListJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::Search(const std::string& search_query, - const google_apis::FileListCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_SEARCH); - new_job->task = base::Bind( - &DriveServiceInterface::Search, - base::Unretained(drive_service_), - search_query, - base::Bind(&JobScheduler::OnGetFileListJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::GetChangeList( - int64_t start_changestamp, - const google_apis::ChangeListCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_GET_CHANGE_LIST); - new_job->task = base::Bind( - &DriveServiceInterface::GetChangeList, - base::Unretained(drive_service_), - start_changestamp, - base::Bind(&JobScheduler::OnGetChangeListJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::GetChangeList( - const std::string& team_drive_id, - const std::string& start_page_token, - const google_apis::ChangeListCallback& callback) { - JobEntry* new_job = CreateNewJob(TYPE_GET_CHANGE_LIST); - new_job->task = base::BindRepeating( - &DriveServiceInterface::GetChangeListByToken, - base::Unretained(drive_service_), team_drive_id, start_page_token, - base::BindRepeating(&JobScheduler::OnGetChangeListJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::GetRemainingChangeList( - const GURL& next_link, - const google_apis::ChangeListCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_GET_REMAINING_CHANGE_LIST); - new_job->task = base::Bind( - &DriveServiceInterface::GetRemainingChangeList, - base::Unretained(drive_service_), - next_link, - base::Bind(&JobScheduler::OnGetChangeListJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::GetRemainingTeamDriveList( - const std::string& page_token, - const google_apis::TeamDriveListCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - JobEntry* new_job = CreateNewJob(TYPE_GET_REMAINING_TEAM_DRIVE_LIST); - new_job->task = - base::Bind(&DriveServiceInterface::GetRemainingTeamDriveList, - base::Unretained(drive_service_), page_token, - base::Bind(&JobScheduler::OnGetTeamDriveListJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::GetRemainingFileList( - const GURL& next_link, - const google_apis::FileListCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_GET_REMAINING_FILE_LIST); - new_job->task = base::Bind( - &DriveServiceInterface::GetRemainingFileList, - base::Unretained(drive_service_), - next_link, - base::Bind(&JobScheduler::OnGetFileListJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::GetFileResource( - const std::string& resource_id, - const ClientContext& context, - const google_apis::FileResourceCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_GET_RESOURCE_ENTRY); - new_job->context = context; - new_job->task = base::Bind( - &DriveServiceInterface::GetFileResource, - base::Unretained(drive_service_), - resource_id, - base::Bind(&JobScheduler::OnGetFileResourceJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::TrashResource( - const std::string& resource_id, - const ClientContext& context, - const google_apis::EntryActionCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_TRASH_RESOURCE); - new_job->context = context; - new_job->task = base::Bind( - &DriveServiceInterface::TrashResource, - base::Unretained(drive_service_), - resource_id, - base::Bind(&JobScheduler::OnEntryActionJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = callback; - StartJob(new_job); -} - -void JobScheduler::CopyResource( - const std::string& resource_id, - const std::string& parent_resource_id, - const std::string& new_title, - const base::Time& last_modified, - const google_apis::FileResourceCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_COPY_RESOURCE); - new_job->task = base::Bind( - &DriveServiceInterface::CopyResource, - base::Unretained(drive_service_), - resource_id, - parent_resource_id, - new_title, - last_modified, - base::Bind(&JobScheduler::OnGetFileResourceJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::UpdateResource( - const std::string& resource_id, - const std::string& parent_resource_id, - const std::string& new_title, - const base::Time& last_modified, - const base::Time& last_viewed_by_me, - const google_apis::drive::Properties& properties, - const ClientContext& context, - const google_apis::FileResourceCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_UPDATE_RESOURCE); - new_job->context = context; - new_job->task = base::Bind(&DriveServiceInterface::UpdateResource, - base::Unretained(drive_service_), resource_id, - parent_resource_id, new_title, last_modified, - last_viewed_by_me, properties, - base::Bind(&JobScheduler::OnGetFileResourceJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::AddResourceToDirectory( - const std::string& parent_resource_id, - const std::string& resource_id, - const google_apis::EntryActionCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_ADD_RESOURCE_TO_DIRECTORY); - new_job->task = base::Bind( - &DriveServiceInterface::AddResourceToDirectory, - base::Unretained(drive_service_), - parent_resource_id, - resource_id, - base::Bind(&JobScheduler::OnEntryActionJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = callback; - StartJob(new_job); -} - -void JobScheduler::RemoveResourceFromDirectory( - const std::string& parent_resource_id, - const std::string& resource_id, - const ClientContext& context, - const google_apis::EntryActionCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - - JobEntry* new_job = CreateNewJob(TYPE_REMOVE_RESOURCE_FROM_DIRECTORY); - new_job->context = context; - new_job->task = base::Bind( - &DriveServiceInterface::RemoveResourceFromDirectory, - base::Unretained(drive_service_), - parent_resource_id, - resource_id, - base::Bind(&JobScheduler::OnEntryActionJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = callback; - StartJob(new_job); -} - -void JobScheduler::AddNewDirectory( - const std::string& parent_resource_id, - const std::string& directory_title, - const AddNewDirectoryOptions& options, - const ClientContext& context, - const google_apis::FileResourceCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - - JobEntry* new_job = CreateNewJob(TYPE_ADD_NEW_DIRECTORY); - new_job->context = context; - new_job->task = base::Bind( - &DriveServiceInterface::AddNewDirectory, - base::Unretained(drive_service_), - parent_resource_id, - directory_title, - options, - base::Bind(&JobScheduler::OnGetFileResourceJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -JobID JobScheduler::DownloadFile( - const base::FilePath& virtual_path, - int64_t expected_file_size, - const base::FilePath& local_cache_path, - const std::string& resource_id, - const ClientContext& context, - const google_apis::DownloadActionCallback& download_action_callback, - const google_apis::GetContentCallback& get_content_callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - - JobEntry* new_job = CreateNewJob(TYPE_DOWNLOAD_FILE); - new_job->job_info.file_path = virtual_path; - new_job->job_info.num_total_bytes = expected_file_size; - new_job->context = context; - new_job->task = base::Bind( - &DriveServiceInterface::DownloadFile, - base::Unretained(drive_service_), - local_cache_path, - resource_id, - base::Bind(&JobScheduler::OnDownloadActionJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - download_action_callback), - get_content_callback, - base::Bind(&JobScheduler::UpdateProgress, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id)); - new_job->abort_callback = CreateErrorRunCallback(download_action_callback); - StartJob(new_job); - return new_job->job_info.job_id; -} - -void JobScheduler::UploadNewFile( - const std::string& parent_resource_id, - int64_t expected_file_size, - const base::FilePath& drive_file_path, - const base::FilePath& local_file_path, - const std::string& title, - const std::string& content_type, - const UploadNewFileOptions& options, - const ClientContext& context, - const google_apis::FileResourceCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - - JobEntry* new_job = CreateNewJob(TYPE_UPLOAD_NEW_FILE); - new_job->job_info.file_path = drive_file_path; - new_job->job_info.num_total_bytes = expected_file_size; - new_job->context = context; - - UploadNewFileParams params; - params.parent_resource_id = parent_resource_id; - params.local_file_path = local_file_path; - params.title = title; - params.content_type = content_type; - params.options = options; - - ResumeUploadParams resume_params; - resume_params.local_file_path = params.local_file_path; - resume_params.content_type = params.content_type; - - params.callback = base::Bind(&JobScheduler::OnUploadCompletionJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - resume_params, - callback); - params.progress_callback = base::Bind(&JobScheduler::UpdateProgress, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id); - new_job->task = base::Bind(&RunUploadNewFile, uploader_.get(), params); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::UploadExistingFile( - const std::string& resource_id, - int64_t expected_file_size, - const base::FilePath& drive_file_path, - const base::FilePath& local_file_path, - const std::string& content_type, - const UploadExistingFileOptions& options, - const ClientContext& context, - const google_apis::FileResourceCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - - JobEntry* new_job = CreateNewJob(TYPE_UPLOAD_EXISTING_FILE); - new_job->job_info.file_path = drive_file_path; - new_job->job_info.num_total_bytes = expected_file_size; - new_job->context = context; - - UploadExistingFileParams params; - params.resource_id = resource_id; - params.local_file_path = local_file_path; - params.content_type = content_type; - params.options = options; - - ResumeUploadParams resume_params; - resume_params.local_file_path = params.local_file_path; - resume_params.content_type = params.content_type; - - params.callback = base::Bind(&JobScheduler::OnUploadCompletionJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - resume_params, - callback); - params.progress_callback = base::Bind(&JobScheduler::UpdateProgress, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id); - new_job->task = base::Bind(&RunUploadExistingFile, uploader_.get(), params); - new_job->abort_callback = CreateErrorRunCallback(callback); - StartJob(new_job); -} - -void JobScheduler::AddPermission( - const std::string& resource_id, - const std::string& email, - google_apis::drive::PermissionRole role, - const google_apis::EntryActionCallback& callback) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - JobEntry* new_job = CreateNewJob(TYPE_ADD_PERMISSION); - new_job->task = base::Bind(&DriveServiceInterface::AddPermission, - base::Unretained(drive_service_), - resource_id, - email, - role, - base::Bind(&JobScheduler::OnEntryActionJobDone, - weak_ptr_factory_.GetWeakPtr(), - new_job->job_info.job_id, - callback)); - new_job->abort_callback = callback; - StartJob(new_job); -} - -JobScheduler::JobEntry* JobScheduler::CreateNewJob(JobType type) { - auto job = std::make_unique<JobEntry>(type); - JobEntry* job_raw = job.get(); - int32_t job_key = job_map_.Add(std::move(job)); - job_raw->job_info.job_id = job_key; - return job_raw; -} - -void JobScheduler::StartJob(JobEntry* job) { - DCHECK(!job->task.is_null()); - - QueueJob(job->job_info.job_id); - NotifyJobAdded(job->job_info); - DoJobLoop(GetJobQueueType(job->job_info.job_type)); -} - -void JobScheduler::QueueJob(JobID job_id) { - DCHECK(thread_checker_.CalledOnValidThread()); - - JobEntry* job_entry = job_map_.Lookup(job_id); - DCHECK(job_entry); - const JobInfo& job_info = job_entry->job_info; - - const QueueType queue_type = GetJobQueueType(job_info.job_type); - const bool batchable = job_info.job_type == TYPE_UPLOAD_EXISTING_FILE || - job_info.job_type == TYPE_UPLOAD_NEW_FILE; - queue_[queue_type]->Push(job_id, job_entry->context.type, batchable, - job_info.num_total_bytes); - - const std::string retry_prefix = job_entry->retry_count > 0 ? - base::StringPrintf(" (retry %d)", job_entry->retry_count) : ""; - logger_->Log(logging::LOG_INFO, - "Job queued%s: %s - %s", - retry_prefix.c_str(), - job_info.ToString().c_str(), - GetQueueInfo(queue_type).c_str()); -} - -void JobScheduler::DoJobLoop(QueueType queue_type) { - DCHECK(thread_checker_.CalledOnValidThread()); - - const int accepted_priority = GetCurrentAcceptedPriority(queue_type); - - // Abort all USER_INITAITED jobs when not accepted. - if (accepted_priority < USER_INITIATED) { - std::vector<JobID> jobs; - queue_[queue_type]->GetQueuedJobs(USER_INITIATED, &jobs); - for (size_t i = 0; i < jobs.size(); ++i) { - JobEntry* job = job_map_.Lookup(jobs[i]); - DCHECK(job); - AbortNotRunningJob(job, google_apis::DRIVE_NO_CONNECTION); - } - } - - // Wait when throttled. - const base::Time now = base::Time::Now(); - if (now < wait_until_) { - base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&JobScheduler::DoJobLoop, weak_ptr_factory_.GetWeakPtr(), - queue_type), - wait_until_ - now); - return; - } - - // Run the job with the highest priority in the queue. - std::vector<JobID> job_ids; - queue_[queue_type]->PopForRun(accepted_priority, &job_ids); - if (job_ids.empty()) - return; - - if (job_ids.size() > 1) - uploader_->StartBatchProcessing(); - - for (JobID job_id : job_ids) { - JobEntry* entry = job_map_.Lookup(job_id); - DCHECK(entry); - - JobInfo* job_info = &entry->job_info; - job_info->state = STATE_RUNNING; - job_info->start_time = now; - NotifyJobUpdated(*job_info); - - entry->cancel_callback = entry->task.Run(); - logger_->Log(logging::LOG_INFO, "Job started: %s - %s", - job_info->ToString().c_str(), - GetQueueInfo(queue_type).c_str()); - } - - if (job_ids.size() > 1) - uploader_->StopBatchProcessing(); - - UpdateWait(); -} - -int JobScheduler::GetCurrentAcceptedPriority(QueueType queue_type) { - DCHECK(thread_checker_.CalledOnValidThread()); - - const int kNoJobShouldRun = -1; - - // Should stop if Drive was disabled while running the fetch loop. - if (pref_service_->GetBoolean(prefs::kDisableDrive)) - return kNoJobShouldRun; - - // Should stop if the network is not online. - auto connection_type = network::mojom::ConnectionType::CONNECTION_UNKNOWN; - network_connection_tracker_->GetConnectionType( - &connection_type, base::BindOnce(&JobScheduler::OnConnectionChanged, - weak_ptr_factory_.GetWeakPtr())); - if (connection_type == network::mojom::ConnectionType::CONNECTION_NONE) - return kNoJobShouldRun; - - // For the file queue, if it is on cellular network, only user initiated - // operations are allowed to start. - if (queue_type == FILE_QUEUE && - pref_service_->GetBoolean(prefs::kDisableDriveOverCellular) && - network::NetworkConnectionTracker::IsConnectionCellular(connection_type)) - return USER_INITIATED; - - // Otherwise, every operations including background tasks are allowed. - return BACKGROUND; -} - -void JobScheduler::UpdateWait() { - DCHECK(thread_checker_.CalledOnValidThread()); - - if (disable_throttling_ || throttle_count_ == 0) - return; - - // Exponential backoff: https://developers.google.com/drive/handle-errors. - base::TimeDelta delay = - base::TimeDelta::FromSeconds(static_cast<int64_t>(1) - << (throttle_count_ - 1)) + - base::TimeDelta::FromMilliseconds(base::RandInt(0, 1000)); - VLOG(1) << "Throttling for " << delay.InMillisecondsF(); - - wait_until_ = std::max(wait_until_, base::Time::Now() + delay); -} - -bool JobScheduler::OnJobDone(JobID job_id, - google_apis::DriveApiErrorCode error) { - DCHECK(thread_checker_.CalledOnValidThread()); - - JobEntry* job_entry = job_map_.Lookup(job_id); - DCHECK(job_entry); - JobInfo* job_info = &job_entry->job_info; - QueueType queue_type = GetJobQueueType(job_info->job_type); - queue_[queue_type]->MarkFinished(job_id); - - const base::TimeDelta elapsed = base::Time::Now() - job_info->start_time; - bool success = (GDataToFileError(error) == FILE_ERROR_OK); - logger_->Log(success ? logging::LOG_INFO : logging::LOG_WARNING, - "Job done: %s => %s (elapsed time: %sms) - %s", - job_info->ToString().c_str(), - DriveApiErrorCodeToString(error).c_str(), - base::NumberToString(elapsed.InMilliseconds()).c_str(), - GetQueueInfo(queue_type).c_str()); - - // Retry, depending on the error. - const bool is_server_error = - error == google_apis::HTTP_SERVICE_UNAVAILABLE || - error == google_apis::HTTP_INTERNAL_SERVER_ERROR; - if (is_server_error) { - if (throttle_count_ < kMaxThrottleCount) - ++throttle_count_; - UpdateWait(); - } else { - throttle_count_ = 0; - } - - const bool should_retry = - is_server_error && job_entry->retry_count < kMaxRetryCount; - if (should_retry) { - job_entry->cancel_callback.Reset(); - job_info->state = STATE_RETRY; - NotifyJobUpdated(*job_info); - - ++job_entry->retry_count; - - // Requeue the job. - QueueJob(job_id); - } else { - NotifyJobDone(*job_info, error); - // The job has finished, no retry will happen in the scheduler. Now we can - // remove the job info from the map. - job_map_.Remove(job_id); - } - - // Post a task to continue the job loop. This allows us to finish handling - // the current job before starting the next one. - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(&JobScheduler::DoJobLoop, - weak_ptr_factory_.GetWeakPtr(), queue_type)); - return !should_retry; -} - -void JobScheduler::OnGetTeamDriveListJobDone( - JobID job_id, - const google_apis::TeamDriveListCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::TeamDriveList> team_drive_list) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - if (OnJobDone(job_id, error)) - callback.Run(error, std::move(team_drive_list)); -} - -void JobScheduler::OnGetFileListJobDone( - JobID job_id, - const google_apis::FileListCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::FileList> file_list) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - if (OnJobDone(job_id, error)) - callback.Run(error, std::move(file_list)); -} - -void JobScheduler::OnGetChangeListJobDone( - JobID job_id, - const google_apis::ChangeListCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::ChangeList> change_list) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - if (OnJobDone(job_id, error)) - callback.Run(error, std::move(change_list)); -} - -void JobScheduler::OnGetFileResourceJobDone( - JobID job_id, - const google_apis::FileResourceCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::FileResource> entry) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - if (OnJobDone(job_id, error)) - callback.Run(error, std::move(entry)); -} - -void JobScheduler::OnGetAboutResourceJobDone( - JobID job_id, - const google_apis::AboutResourceCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::AboutResource> about_resource) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - if (OnJobDone(job_id, error)) - callback.Run(error, std::move(about_resource)); -} - -void JobScheduler::OnGetStartPageTokenDone( - JobID job_id, - const google_apis::StartPageTokenCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::StartPageToken> start_page_token) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - if (OnJobDone(job_id, error)) - callback.Run(error, std::move(start_page_token)); -} - -void JobScheduler::OnEntryActionJobDone( - JobID job_id, - const google_apis::EntryActionCallback& callback, - google_apis::DriveApiErrorCode error) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - if (OnJobDone(job_id, error)) - callback.Run(error); -} - -void JobScheduler::OnDownloadActionJobDone( - JobID job_id, - const google_apis::DownloadActionCallback& callback, - google_apis::DriveApiErrorCode error, - const base::FilePath& temp_file) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - if (OnJobDone(job_id, error)) - callback.Run(error, temp_file); -} - -void JobScheduler::OnUploadCompletionJobDone( - JobID job_id, - const ResumeUploadParams& resume_params, - const google_apis::FileResourceCallback& callback, - google_apis::DriveApiErrorCode error, - const GURL& upload_location, - std::unique_ptr<google_apis::FileResource> entry) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!callback.is_null()); - - if (!upload_location.is_empty()) { - // If upload_location is available, update the task to resume the - // upload process from the terminated point. - // When we need to retry, the error code should be HTTP_SERVICE_UNAVAILABLE - // so OnJobDone called below will be in charge to re-queue the job. - JobEntry* job_entry = job_map_.Lookup(job_id); - DCHECK(job_entry); - - ResumeUploadFileParams params; - params.upload_location = upload_location; - params.local_file_path = resume_params.local_file_path; - params.content_type = resume_params.content_type; - params.callback = base::Bind(&JobScheduler::OnResumeUploadFileDone, - weak_ptr_factory_.GetWeakPtr(), - job_id, - job_entry->task, - callback); - params.progress_callback = base::Bind(&JobScheduler::UpdateProgress, - weak_ptr_factory_.GetWeakPtr(), - job_id); - job_entry->task = base::Bind(&RunResumeUploadFile, uploader_.get(), params); - } - - if (OnJobDone(job_id, error)) - callback.Run(error, std::move(entry)); -} - -void JobScheduler::OnResumeUploadFileDone( - JobID job_id, - const base::Callback<google_apis::CancelCallback()>& original_task, - const google_apis::FileResourceCallback& callback, - google_apis::DriveApiErrorCode error, - const GURL& upload_location, - std::unique_ptr<google_apis::FileResource> entry) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(!original_task.is_null()); - DCHECK(!callback.is_null()); - - if (upload_location.is_empty()) { - // If upload_location is not available, we should discard it and stop trying - // to resume. Restore the original task. - JobEntry* job_entry = job_map_.Lookup(job_id); - DCHECK(job_entry); - job_entry->task = original_task; - } - - if (OnJobDone(job_id, error)) - callback.Run(error, std::move(entry)); -} - -void JobScheduler::UpdateProgress(JobID job_id, - int64_t progress, - int64_t total) { - JobEntry* job_entry = job_map_.Lookup(job_id); - DCHECK(job_entry); - - job_entry->job_info.num_completed_bytes = progress; - if (total != -1) - job_entry->job_info.num_total_bytes = total; - NotifyJobUpdated(job_entry->job_info); -} - -void JobScheduler::OnConnectionChanged(network::mojom::ConnectionType type) { - // When connection type switches from one connection to another, - // CONNECTION_NONE signal comes right before the changed connection signal. - // Ignore such signals to avoid aborting jobs. - if (type == network::mojom::ConnectionType::CONNECTION_NONE && - !network_connection_tracker_->IsOffline()) - return; - - DCHECK(thread_checker_.CalledOnValidThread()); - - // Resume the job loop. - // The network connection status will be checked - // in GetCurrentAcceptedPriority(). - for (int i = METADATA_QUEUE; i < NUM_QUEUES; ++i) - DoJobLoop(static_cast<QueueType>(i)); -} - -JobScheduler::QueueType JobScheduler::GetJobQueueType(JobType type) { - switch (type) { - case TYPE_GET_ABOUT_RESOURCE: - case TYPE_GET_APP_LIST: - case TYPE_GET_ALL_TEAM_DRIVE_LIST: - case TYPE_GET_ALL_RESOURCE_LIST: - case TYPE_GET_RESOURCE_LIST_IN_DIRECTORY: - case TYPE_SEARCH: - case TYPE_GET_CHANGE_LIST: - case TYPE_GET_REMAINING_CHANGE_LIST: - case TYPE_GET_REMAINING_TEAM_DRIVE_LIST: - case TYPE_GET_REMAINING_FILE_LIST: - case TYPE_GET_RESOURCE_ENTRY: - case TYPE_GET_SHARE_URL: - case TYPE_GET_START_PAGE_TOKEN: - case TYPE_TRASH_RESOURCE: - case TYPE_COPY_RESOURCE: - case TYPE_UPDATE_RESOURCE: - case TYPE_ADD_RESOURCE_TO_DIRECTORY: - case TYPE_REMOVE_RESOURCE_FROM_DIRECTORY: - case TYPE_ADD_NEW_DIRECTORY: - case TYPE_ADD_PERMISSION: - return METADATA_QUEUE; - - case TYPE_DOWNLOAD_FILE: - case TYPE_UPLOAD_NEW_FILE: - case TYPE_UPLOAD_EXISTING_FILE: - return FILE_QUEUE; - } - NOTREACHED(); - return FILE_QUEUE; -} - -void JobScheduler::AbortNotRunningJob(JobEntry* job, - google_apis::DriveApiErrorCode error) { - DCHECK(thread_checker_.CalledOnValidThread()); - - const base::TimeDelta elapsed = base::Time::Now() - job->job_info.start_time; - const QueueType queue_type = GetJobQueueType(job->job_info.job_type); - logger_->Log(logging::LOG_INFO, - "Job aborted: %s => %s (elapsed time: %sms) - %s", - job->job_info.ToString().c_str(), - DriveApiErrorCodeToString(error).c_str(), - base::NumberToString(elapsed.InMilliseconds()).c_str(), - GetQueueInfo(queue_type).c_str()); - - base::Callback<void(google_apis::DriveApiErrorCode)> callback = - job->abort_callback; - queue_[GetJobQueueType(job->job_info.job_type)]->Remove(job->job_info.job_id); - NotifyJobDone(job->job_info, error); - job_map_.Remove(job->job_info.job_id); - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::BindOnce(callback, error)); -} - -void JobScheduler::NotifyJobAdded(const JobInfo& job_info) { - DCHECK(thread_checker_.CalledOnValidThread()); - for (auto& observer : observer_list_) - observer.OnJobAdded(job_info); -} - -void JobScheduler::NotifyJobDone(const JobInfo& job_info, - google_apis::DriveApiErrorCode error) { - DCHECK(thread_checker_.CalledOnValidThread()); - for (auto& observer : observer_list_) - observer.OnJobDone(job_info, GDataToFileError(error)); -} - -void JobScheduler::NotifyJobUpdated(const JobInfo& job_info) { - DCHECK(thread_checker_.CalledOnValidThread()); - for (auto& observer : observer_list_) - observer.OnJobUpdated(job_info); -} - -std::string JobScheduler::GetQueueInfo(QueueType type) const { - return QueueTypeToString(type) + " " + queue_[type]->ToString(); -} - -// static -std::string JobScheduler::QueueTypeToString(QueueType type) { - switch (type) { - case METADATA_QUEUE: - return "METADATA_QUEUE"; - case FILE_QUEUE: - return "FILE_QUEUE"; - case NUM_QUEUES: - break; // This value is just a sentinel. Should never be used. - } - NOTREACHED(); - return ""; -} - -} // namespace drive
diff --git a/components/drive/job_scheduler.h b/components/drive/job_scheduler.h deleted file mode 100644 index 403cee2..0000000 --- a/components/drive/job_scheduler.h +++ /dev/null
@@ -1,435 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_JOB_SCHEDULER_H_ -#define COMPONENTS_DRIVE_JOB_SCHEDULER_H_ - -#include <stdint.h> - -#include <memory> -#include <string> -#include <vector> - -#include "base/containers/id_map.h" -#include "base/macros.h" -#include "base/observer_list.h" -#include "base/threading/thread_checker.h" -#include "components/drive/drive_uploader.h" -#include "components/drive/job_list.h" -#include "components/drive/job_queue.h" -#include "components/drive/service/drive_service_interface.h" -#include "mojo/public/cpp/bindings/pending_remote.h" -#include "services/device/public/mojom/wake_lock_provider.mojom.h" -#include "services/network/public/cpp/network_connection_tracker.h" - -class PrefService; - -namespace drive { - -class EventLogger; - -// Priority of a job. Higher values are lower priority. -enum ContextType { - USER_INITIATED, - BACKGROUND, - // Indicates the number of values of this enum. - NUM_CONTEXT_TYPES, -}; - -struct ClientContext { - explicit ClientContext(ContextType in_type) : type(in_type) {} - ContextType type; -}; - -// The JobScheduler is responsible for queuing and scheduling drive jobs. -// Because jobs are executed concurrently by priority and retried for network -// failures, there is no guarantee of orderings. -// -// Jobs are grouped into two priority levels: -// - USER_INITIATED jobs are those occur as a result of direct user actions. -// - BACKGROUND jobs runs in response to state changes, server actions, etc. -// USER_INITIATED jobs must be handled immediately, thus have higher priority. -// BACKGROUND jobs run only after all USER_INITIATED jobs have run. -// -// Orthogonally, jobs are grouped into two types: -// - "File jobs" transfer the contents of files. -// - "Metadata jobs" operates on file metadata or the directory structure. -// On WiFi or Ethernet connections, all types of jobs just run. -// On mobile connections (2G/3G/4G), we don't want large background traffic. -// USER_INITIATED jobs or metadata jobs will run. BACKGROUND file jobs wait -// in the queue until the network type changes. -// On offline case, no jobs run. USER_INITIATED jobs fail immediately. -// BACKGROUND jobs stay in the queue and wait for network connection. -class JobScheduler - : public network::NetworkConnectionTracker::NetworkConnectionObserver, - public JobListInterface { - public: - JobScheduler( - PrefService* pref_service, - EventLogger* logger, - DriveServiceInterface* drive_service, - network::NetworkConnectionTracker* network_connection_tracker, - base::SequencedTaskRunner* blocking_task_runner, - mojo::PendingRemote<device::mojom::WakeLockProvider> wake_lock_provider); - - ~JobScheduler() override; - - // JobListInterface overrides. - std::vector<JobInfo> GetJobInfoList() override; - void AddObserver(JobListObserver* observer) override; - void RemoveObserver(JobListObserver* observer) override; - void CancelJob(JobID job_id) override; - void CancelAllJobs() override; - - // Adds a GetAboutResource operation to the queue. - // |callback| must not be null. - void GetAboutResource(const google_apis::AboutResourceCallback& callback); - - // Adds a GetStartPageToken operation to the queue. - // If |team_drive_id| is empty then it will return the start token for the - // users changelog. - // |callback| must not be null. - void GetStartPageToken(const std::string& team_drive_id, - const google_apis::StartPageTokenCallback& callback); - - // Adds a GetAllTeamDriveList operation to the queue. - // |callback| must not be null. - void GetAllTeamDriveList(const google_apis::TeamDriveListCallback& callback); - - // Adds a GetAllFileList operation to the queue. - // If |team_drive_id| is empty then it will return the file list for the - // users default corpus, otherwise will return the file list for the - // specified team drive. - // |callback| must not be null. - void GetAllFileList(const std::string& team_drive_id, - const google_apis::FileListCallback& callback); - - // Adds a GetFileListInDirectory operation to the queue. - // |callback| must not be null. - void GetFileListInDirectory(const std::string& directory_resource_id, - const google_apis::FileListCallback& callback); - - // Adds a Search operation to the queue. - // |callback| must not be null. - void Search(const std::string& search_query, - const google_apis::FileListCallback& callback); - - // Adds a GetChangeList operation to the queue. - // |callback| must not be null. - void GetChangeList(int64_t start_changestamp, - const google_apis::ChangeListCallback& callback); - - // Adds a GetChangeList operation to the queue, where |start_page_token| - // is used to specify where to start retrieving the change list from. - // If |team_drive_id| is empty then it will return the change list for the - // users changelog. - // |callback| must not be null. - void GetChangeList(const std::string& team_drive_id, - const std::string& start_page_token, - const google_apis::ChangeListCallback& callback); - - // Adds GetRemainingChangeList operation to the queue. - // |callback| must not be null. - void GetRemainingChangeList(const GURL& next_link, - const google_apis::ChangeListCallback& callback); - - // Adds GetRemainingTeamDriveList operation to the queue. - // |callback| must not be null. - void GetRemainingTeamDriveList( - const std::string& page_token, - const google_apis::TeamDriveListCallback& callback); - - // Adds GetRemainingFileList operation to the queue. - // |callback| must not be null. - void GetRemainingFileList(const GURL& next_link, - const google_apis::FileListCallback& callback); - - // Adds a GetFileResource operation to the queue. - void GetFileResource(const std::string& resource_id, - const ClientContext& context, - const google_apis::FileResourceCallback& callback); - - // Adds a TrashResource operation to the queue. - void TrashResource(const std::string& resource_id, - const ClientContext& context, - const google_apis::EntryActionCallback& callback); - - // Adds a CopyResource operation to the queue. - void CopyResource(const std::string& resource_id, - const std::string& parent_resource_id, - const std::string& new_title, - const base::Time& last_modified, - const google_apis::FileResourceCallback& callback); - - // Adds a UpdateResource operation to the queue. - void UpdateResource(const std::string& resource_id, - const std::string& parent_resource_id, - const std::string& new_title, - const base::Time& last_modified, - const base::Time& last_viewed_by_me, - const google_apis::drive::Properties& properties, - const ClientContext& context, - const google_apis::FileResourceCallback& callback); - - // Adds a AddResourceToDirectory operation to the queue. - void AddResourceToDirectory(const std::string& parent_resource_id, - const std::string& resource_id, - const google_apis::EntryActionCallback& callback); - - // Adds a RemoveResourceFromDirectory operation to the queue. - void RemoveResourceFromDirectory( - const std::string& parent_resource_id, - const std::string& resource_id, - const ClientContext& context, - const google_apis::EntryActionCallback& callback); - - // Adds a AddNewDirectory operation to the queue. - void AddNewDirectory(const std::string& parent_resource_id, - const std::string& directory_title, - const AddNewDirectoryOptions& options, - const ClientContext& context, - const google_apis::FileResourceCallback& callback); - - // Adds a DownloadFile operation to the queue. - // The first two arguments |virtual_path| and |expected_file_size| are used - // only for filling JobInfo for the operation so that observers can get the - // detail. The actual operation never refers these values. - JobID DownloadFile( - const base::FilePath& virtual_path, - int64_t expected_file_size, - const base::FilePath& local_cache_path, - const std::string& resource_id, - const ClientContext& context, - const google_apis::DownloadActionCallback& download_action_callback, - const google_apis::GetContentCallback& get_content_callback); - - // Adds an UploadNewFile operation to the queue. - void UploadNewFile(const std::string& parent_resource_id, - int64_t expected_file_size, - const base::FilePath& drive_file_path, - const base::FilePath& local_file_path, - const std::string& title, - const std::string& content_type, - const UploadNewFileOptions& options, - const ClientContext& context, - const google_apis::FileResourceCallback& callback); - - // Adds an UploadExistingFile operation to the queue. - void UploadExistingFile(const std::string& resource_id, - int64_t expected_file_size, - const base::FilePath& drive_file_path, - const base::FilePath& local_file_path, - const std::string& content_type, - const UploadExistingFileOptions& options, - const ClientContext& context, - const google_apis::FileResourceCallback& callback); - - // Adds AddPermission operation to the queue. |callback| must not be null. - void AddPermission(const std::string& resource_id, - const std::string& email, - google_apis::drive::PermissionRole role, - const google_apis::EntryActionCallback& callback); - - private: - friend class JobSchedulerTest; - - enum QueueType { - METADATA_QUEUE, - FILE_QUEUE, - NUM_QUEUES - }; - - static const int kMaxJobCount[NUM_QUEUES]; - - // Represents a single entry in the job map. - struct JobEntry { - explicit JobEntry(JobType type); - ~JobEntry(); - - // General user-visible information on the job. - JobInfo job_info; - - // Context of the job. - ClientContext context; - - // The number of times the jobs is retried due to server errors. - int retry_count; - - // The callback to start the job. Called each time it is retry. - base::Callback<google_apis::CancelCallback()> task; - - // The callback to cancel the running job. It is returned from task.Run(). - google_apis::CancelCallback cancel_callback; - - // The callback to notify an error to the client of JobScheduler. - // This is used to notify cancel of a job that is not running yet. - base::Callback<void(google_apis::DriveApiErrorCode)> abort_callback; - - base::ThreadChecker thread_checker_; - }; - - // Parameters for DriveUploader::ResumeUploadFile. - struct ResumeUploadParams; - - // Creates a new job and add it to the job map. - JobEntry* CreateNewJob(JobType type); - - // Adds the specified job to the queue and starts the job loop for the queue - // if needed. - void StartJob(JobEntry* job); - - // Adds the specified job to the queue. - void QueueJob(JobID job_id); - - // Determines the next job that should run, and starts it. - void DoJobLoop(QueueType queue_type); - - // Returns the lowest acceptable priority level of the operations that is - // currently allowed to start for the |queue_type|. - int GetCurrentAcceptedPriority(QueueType queue_type); - - // Updates |wait_until_| to throttle requests. - void UpdateWait(); - - // Retries the job if needed and returns false. Otherwise returns true. - bool OnJobDone(JobID job_id, google_apis::DriveApiErrorCode error); - - // Callback for job finishing with a FileListCallback. - void OnGetTeamDriveListJobDone( - JobID job_id, - const google_apis::TeamDriveListCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::TeamDriveList> team_drive_list); - - // Callback for job finishing with a FileListCallback. - void OnGetFileListJobDone(JobID job_id, - const google_apis::FileListCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::FileList> file_list); - - // Callback for job finishing with a ChangeListCallback. - void OnGetChangeListJobDone( - JobID job_id, - const google_apis::ChangeListCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::ChangeList> change_list); - - // Callback for job finishing with a FileResourceCallback. - void OnGetFileResourceJobDone( - JobID job_id, - const google_apis::FileResourceCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::FileResource> entry); - - // Callback for job finishing with a AboutResourceCallback. - void OnGetAboutResourceJobDone( - JobID job_id, - const google_apis::AboutResourceCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::AboutResource> about_resource); - - // Callback for job finishing with a GetStartPageTokenCallback. - void OnGetStartPageTokenDone( - JobID job_id, - const google_apis::StartPageTokenCallback& callback, - google_apis::DriveApiErrorCode error, - std::unique_ptr<google_apis::StartPageToken> start_page_token); - - // Callback for job finishing with a EntryActionCallback. - void OnEntryActionJobDone(JobID job_id, - const google_apis::EntryActionCallback& callback, - google_apis::DriveApiErrorCode error); - - // Callback for job finishing with a DownloadActionCallback. - void OnDownloadActionJobDone( - JobID job_id, - const google_apis::DownloadActionCallback& callback, - google_apis::DriveApiErrorCode error, - const base::FilePath& temp_file); - - // Callback for job finishing with a UploadCompletionCallback. - void OnUploadCompletionJobDone( - JobID job_id, - const ResumeUploadParams& resume_params, - const google_apis::FileResourceCallback& callback, - google_apis::DriveApiErrorCode error, - const GURL& upload_location, - std::unique_ptr<google_apis::FileResource> entry); - - // Callback for DriveUploader::ResumeUploadFile(). - void OnResumeUploadFileDone( - JobID job_id, - const base::Callback<google_apis::CancelCallback()>& original_task, - const google_apis::FileResourceCallback& callback, - google_apis::DriveApiErrorCode error, - const GURL& upload_location, - std::unique_ptr<google_apis::FileResource> entry); - - // Updates the progress status of the specified job. - void UpdateProgress(JobID job_id, int64_t progress, int64_t total); - - // network::NetworkConnectionTracker::NetworkConnectionObserver override. - void OnConnectionChanged(network::mojom::ConnectionType type) override; - - // Get the type of queue the specified job should be put in. - QueueType GetJobQueueType(JobType type); - - // For testing only. Disables throttling so that testing is faster. - void SetDisableThrottling(bool disable) { disable_throttling_ = disable; } - - // Aborts a job which is not in STATE_RUNNING. - void AbortNotRunningJob(JobEntry* job, google_apis::DriveApiErrorCode error); - - // Notifies updates to observers. - void NotifyJobAdded(const JobInfo& job_info); - void NotifyJobDone(const JobInfo& job_info, - google_apis::DriveApiErrorCode error); - void NotifyJobUpdated(const JobInfo& job_info); - - // Gets information of the queue of the given type as string. - std::string GetQueueInfo(QueueType type) const; - - // Returns a string representation of QueueType. - static std::string QueueTypeToString(QueueType type); - - // The number of times operations have failed in a row, capped at - // kMaxThrottleCount. This is used to calculate the delay before running the - // next task. - int throttle_count_; - - // Jobs should not start running until this time. Used for throttling. - base::Time wait_until_; - - // Disables throttling for testing. - bool disable_throttling_; - - // The queues of jobs. - std::unique_ptr<JobQueue> queue_[NUM_QUEUES]; - - // The list of queued job info indexed by job IDs. - using JobIDMap = base::IDMap<std::unique_ptr<JobEntry>>; - JobIDMap job_map_; - - // The list of observers for the scheduler. - base::ObserverList<JobListObserver>::Unchecked observer_list_; - - EventLogger* logger_; - DriveServiceInterface* drive_service_; - network::NetworkConnectionTracker* network_connection_tracker_; - base::SequencedTaskRunner* blocking_task_runner_; - std::unique_ptr<DriveUploaderInterface> uploader_; - - PrefService* pref_service_; - - base::ThreadChecker thread_checker_; - - // Note: This should remain the last member so it'll be destroyed and - // invalidate its weak pointers before any other members are destroyed. - base::WeakPtrFactory<JobScheduler> weak_ptr_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(JobScheduler); -}; - -} // namespace drive - -#endif // COMPONENTS_DRIVE_JOB_SCHEDULER_H_
diff --git a/components/drive/job_scheduler_unittest.cc b/components/drive/job_scheduler_unittest.cc deleted file mode 100644 index 237bdc3..0000000 --- a/components/drive/job_scheduler_unittest.cc +++ /dev/null
@@ -1,1105 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/job_scheduler.h" - -#include <stddef.h> -#include <stdint.h> - -#include <memory> -#include <set> - -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/stl_util.h" -#include "base/strings/string_number_conversions.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/drive/chromeos/drive_test_util.h" -#include "components/drive/drive_pref_names.h" -#include "components/drive/event_logger.h" -#include "components/drive/file_system_core_util.h" -#include "components/drive/service/fake_drive_service.h" -#include "components/drive/service/test_util.h" -#include "components/prefs/testing_pref_service.h" -#include "content/public/test/browser_task_environment.h" -#include "google_apis/drive/drive_api_parser.h" -#include "google_apis/drive/test_util.h" -#include "services/network/test/test_network_connection_tracker.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { - -namespace { - -// Dummy value passed for the |expected_file_size| parameter of DownloadFile(). -const int64_t kDummyDownloadFileSize = 0; - -void CopyTitleFromFileResourceCallback( - std::vector<std::string>* title_list_out, - google_apis::DriveApiErrorCode error_in, - std::unique_ptr<google_apis::FileResource> entry_in) { - title_list_out->push_back(entry_in->title()); -} - -class JobListLogger : public JobListObserver { - public: - enum EventType { - ADDED, - UPDATED, - DONE, - }; - - struct EventLog { - EventType type; - JobInfo info; - - EventLog(EventType type, const JobInfo& info) : type(type), info(info) { - } - }; - - // Checks whether the specified type of event has occurred. - bool Has(EventType type, JobType job_type) { - for (size_t i = 0; i < events.size(); ++i) { - if (events[i].type == type && events[i].info.job_type == job_type) - return true; - } - return false; - } - - // Gets the progress event information of the specified type. - void GetProgressInfo(JobType job_type, std::vector<int64_t>* progress) { - for (size_t i = 0; i < events.size(); ++i) { - if (events[i].type == UPDATED && events[i].info.job_type == job_type) - progress->push_back(events[i].info.num_completed_bytes); - } - } - - // JobListObserver overrides. - void OnJobAdded(const JobInfo& info) override { - events.push_back(EventLog(ADDED, info)); - } - - void OnJobUpdated(const JobInfo& info) override { - events.push_back(EventLog(UPDATED, info)); - } - - void OnJobDone(const JobInfo& info, FileError error) override { - events.push_back(EventLog(DONE, info)); - } - - private: - std::vector<EventLog> events; -}; - -// Fake drive service extended for testing cancellation. -// When upload_new_file_cancelable is set, this Drive service starts -// returning a closure to cancel from InitiateUploadNewFile(). The task will -// finish only when the cancel closure is called. -class CancelTestableFakeDriveService : public FakeDriveService { - public: - CancelTestableFakeDriveService() - : upload_new_file_cancelable_(false) { - } - - void set_upload_new_file_cancelable(bool cancelable) { - upload_new_file_cancelable_ = cancelable; - } - - google_apis::CancelCallback InitiateUploadNewFile( - const std::string& content_type, - int64_t content_length, - const std::string& parent_resource_id, - const std::string& title, - const UploadNewFileOptions& options, - const google_apis::InitiateUploadCallback& callback) override { - if (upload_new_file_cancelable_) - return base::Bind(callback, google_apis::DRIVE_CANCELLED, GURL()); - - return FakeDriveService::InitiateUploadNewFile(content_type, - content_length, - parent_resource_id, - title, - options, - callback); - } - - private: - bool upload_new_file_cancelable_; -}; - -const char kHello[] = "Hello"; -const size_t kHelloLen = sizeof(kHello) - 1; - -} // namespace - -class JobSchedulerTest : public testing::Test { - public: - JobSchedulerTest() - : pref_service_(new TestingPrefServiceSimple) { - test_util::RegisterDrivePrefs(pref_service_->registry()); - } - - void SetUp() override { - logger_ = std::make_unique<EventLogger>(); - - fake_drive_service_ = std::make_unique<CancelTestableFakeDriveService>(); - test_util::SetUpTestEntries(fake_drive_service_.get()); - - ConnectToWifi(); - scheduler_ = std::make_unique<JobScheduler>( - pref_service_.get(), logger_.get(), fake_drive_service_.get(), - network::TestNetworkConnectionTracker::GetInstance(), - base::ThreadTaskRunnerHandle::Get().get(), mojo::NullRemote()); - scheduler_->SetDisableThrottling(true); - } - - protected: - // Sets up TestNetworkConnectionTracker as if it's connected to a network with - // the specified connection type. - void ChangeConnectionType(network::mojom::ConnectionType type) { - network::TestNetworkConnectionTracker::GetInstance()->SetConnectionType( - type); - } - - // Sets up TestNetworkConnectionTracker as if it's connected to wifi network. - void ConnectToWifi() { - ChangeConnectionType(network::mojom::ConnectionType::CONNECTION_WIFI); - } - - // Sets up TestNetworkConnectionTracker as if it's connected to cellular - // network. - void ConnectToCellular() { - ChangeConnectionType(network::mojom::ConnectionType::CONNECTION_2G); - } - - // Sets up TestNetworkConnectionTracker as if it's connected to wimax network. - void ConnectToWimax() { - ChangeConnectionType(network::mojom::ConnectionType::CONNECTION_4G); - } - - // Sets up TestNetworkConnectionTracker as if it's disconnected. - void ConnectToNone() { - ChangeConnectionType(network::mojom::ConnectionType::CONNECTION_NONE); - } - - static int GetMetadataQueueMaxJobCount() { - return JobScheduler::kMaxJobCount[JobScheduler::METADATA_QUEUE]; - } - - content::BrowserTaskEnvironment task_environment_; - std::unique_ptr<TestingPrefServiceSimple> pref_service_; - std::unique_ptr<EventLogger> logger_; - std::unique_ptr<CancelTestableFakeDriveService> fake_drive_service_; - std::unique_ptr<JobScheduler> scheduler_; -}; - -TEST_F(JobSchedulerTest, GetAboutResource) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::AboutResource> about_resource; - scheduler_->GetAboutResource( - google_apis::test_util::CreateCopyResultCallback( - &error, &about_resource)); - base::RunLoop().RunUntilIdle(); - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(about_resource); -} - -TEST_F(JobSchedulerTest, GetStartPageToken) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::StartPageToken> start_page_token; - scheduler_->GetStartPageToken( - util::kTeamDriveIdDefaultCorpus, - google_apis::test_util::CreateCopyResultCallback(&error, - &start_page_token)); - base::RunLoop().RunUntilIdle(); - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(start_page_token); -} - -TEST_F(JobSchedulerTest, GetAllTeamDriveList) { - ConnectToWifi(); - - fake_drive_service_->AddTeamDrive("TEAM_DRIVE_ID", "TEAM_DRIVE_NAME"); - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::TeamDriveList> team_drive_list; - - scheduler_->GetAllTeamDriveList( - google_apis::test_util::CreateCopyResultCallback(&error, - &team_drive_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(team_drive_list); -} - -TEST_F(JobSchedulerTest, GetAllFileList) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileList> file_list; - - scheduler_->GetAllFileList( - util::kTeamDriveIdDefaultCorpus, - google_apis::test_util::CreateCopyResultCallback(&error, &file_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(file_list); -} - -TEST_F(JobSchedulerTest, GetFileListInDirectory) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileList> file_list; - - scheduler_->GetFileListInDirectory( - fake_drive_service_->GetRootResourceId(), - google_apis::test_util::CreateCopyResultCallback(&error, &file_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(file_list); -} - -TEST_F(JobSchedulerTest, Search) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileList> file_list; - - scheduler_->Search( - "File", // search query - google_apis::test_util::CreateCopyResultCallback(&error, &file_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(file_list); -} - -TEST_F(JobSchedulerTest, GetChangeList) { - ConnectToWifi(); - - int64_t old_largest_change_id = - fake_drive_service_->about_resource().largest_change_id(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - - // Create a new directory. - { - std::unique_ptr<google_apis::FileResource> entry; - fake_drive_service_->AddNewDirectory( - fake_drive_service_->GetRootResourceId(), "new directory", - AddNewDirectoryOptions(), - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - base::RunLoop().RunUntilIdle(); - ASSERT_EQ(google_apis::HTTP_CREATED, error); - } - - error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::ChangeList> change_list; - scheduler_->GetChangeList( - old_largest_change_id + 1, - google_apis::test_util::CreateCopyResultCallback(&error, &change_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(change_list); -} - -TEST_F(JobSchedulerTest, GetChangeListWithStartToken) { - ConnectToWifi(); - - // TODO(slangley): Find the start page token from the fake drive service - const std::string& start_page_token = - fake_drive_service_->start_page_token().start_page_token(); - - const std::string team_drive_id; // Empty means users default corpus - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - - // Create a new directory. - { - std::unique_ptr<google_apis::FileResource> entry; - fake_drive_service_->AddNewDirectory( - fake_drive_service_->GetRootResourceId(), "new directory", - AddNewDirectoryOptions(), - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - base::RunLoop().RunUntilIdle(); - ASSERT_EQ(google_apis::HTTP_CREATED, error); - } - - error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::ChangeList> change_list; - scheduler_->GetChangeList( - team_drive_id, start_page_token, - google_apis::test_util::CreateCopyResultCallback(&error, &change_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(change_list); -} - -TEST_F(JobSchedulerTest, GetRemainingChangeList) { - ConnectToWifi(); - fake_drive_service_->set_default_max_results(2); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::ChangeList> change_list; - - scheduler_->GetChangeList( - 0, - google_apis::test_util::CreateCopyResultCallback(&error, &change_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(change_list); - - // Keep the next url before releasing the |change_list|. - GURL next_url(change_list->next_link()); - - error = google_apis::DRIVE_OTHER_ERROR; - change_list.reset(); - - scheduler_->GetRemainingChangeList( - next_url, - google_apis::test_util::CreateCopyResultCallback(&error, &change_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(change_list); -} - -TEST_F(JobSchedulerTest, GetRemainingTeamDriveList) { - ConnectToWifi(); - fake_drive_service_->set_default_max_results(2); - fake_drive_service_->AddTeamDrive("TEAM_DRIVE_ID_1", "TEAM_DRIVE_NAME 1"); - fake_drive_service_->AddTeamDrive("TEAM_DRIVE_ID_2", "TEAM_DRIVE_NAME 2"); - fake_drive_service_->AddTeamDrive("TEAM_DRIVE_ID_3", "TEAM_DRIVE_NAME 3"); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::TeamDriveList> team_drive_list; - - scheduler_->GetAllTeamDriveList( - google_apis::test_util::CreateCopyResultCallback(&error, - &team_drive_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(team_drive_list); - - // Keep the next page_token before releasing the |file_list|. - std::string next_page_token(team_drive_list->next_page_token()); - - error = google_apis::DRIVE_OTHER_ERROR; - team_drive_list.reset(); - - scheduler_->GetRemainingTeamDriveList( - next_page_token, google_apis::test_util::CreateCopyResultCallback( - &error, &team_drive_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(team_drive_list); -} - -TEST_F(JobSchedulerTest, GetRemainingFileList) { - ConnectToWifi(); - fake_drive_service_->set_default_max_results(2); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileList> file_list; - - scheduler_->GetFileListInDirectory( - fake_drive_service_->GetRootResourceId(), - google_apis::test_util::CreateCopyResultCallback(&error, &file_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(file_list); - - // Keep the next url before releasing the |file_list|. - GURL next_url(file_list->next_link()); - - error = google_apis::DRIVE_OTHER_ERROR; - file_list.reset(); - - scheduler_->GetRemainingFileList( - next_url, - google_apis::test_util::CreateCopyResultCallback(&error, &file_list)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(file_list); -} - -TEST_F(JobSchedulerTest, GetFileResource) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry; - - scheduler_->GetFileResource( - "2_file_resource_id", // resource ID - ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(entry); -} - -TEST_F(JobSchedulerTest, TrashResource) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - - scheduler_->TrashResource( - "2_file_resource_id", - ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); -} - -TEST_F(JobSchedulerTest, CopyResource) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry; - - scheduler_->CopyResource( - "2_file_resource_id", // resource ID - "1_folder_resource_id", // parent resource ID - "New Document", // new title - base::Time(), - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(entry); -} - -TEST_F(JobSchedulerTest, UpdateResource) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry; - - scheduler_->UpdateResource( - "2_file_resource_id", // resource ID - "1_folder_resource_id", // parent resource ID - "New Document", // new title - base::Time(), base::Time(), google_apis::drive::Properties(), - ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(entry); -} - -TEST_F(JobSchedulerTest, AddResourceToDirectory) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - - scheduler_->AddResourceToDirectory( - "1_folder_resource_id", - "2_file_resource_id", - google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_SUCCESS, error); -} - -TEST_F(JobSchedulerTest, RemoveResourceFromDirectory) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - - scheduler_->RemoveResourceFromDirectory( - "1_folder_resource_id", - "subdirectory_file_1_id", // resource ID - ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_NO_CONTENT, error); -} - -TEST_F(JobSchedulerTest, AddNewDirectory) { - ConnectToWifi(); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry; - - scheduler_->AddNewDirectory( - fake_drive_service_->GetRootResourceId(), // Root directory. - "New Directory", AddNewDirectoryOptions(), ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(google_apis::HTTP_CREATED, error); - ASSERT_TRUE(entry); -} - -TEST_F(JobSchedulerTest, PriorityHandling) { - // Saturate the metadata job queue with uninteresting jobs to prevent - // following jobs from starting. - google_apis::DriveApiErrorCode error_dontcare = - google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry_dontcare; - for (int i = 0; i < GetMetadataQueueMaxJobCount(); ++i) { - std::string resource_id("2_file_resource_id"); - scheduler_->GetFileResource( - resource_id, - ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error_dontcare, - &entry_dontcare)); - } - - // Start jobs with different priorities. - std::string title_1("new file 1"); - std::string title_2("new file 2"); - std::string title_3("new file 3"); - std::string title_4("new file 4"); - std::vector<std::string> titles; - - scheduler_->AddNewDirectory( - fake_drive_service_->GetRootResourceId(), title_1, - AddNewDirectoryOptions(), ClientContext(USER_INITIATED), - base::Bind(&CopyTitleFromFileResourceCallback, &titles)); - scheduler_->AddNewDirectory( - fake_drive_service_->GetRootResourceId(), title_2, - AddNewDirectoryOptions(), ClientContext(BACKGROUND), - base::Bind(&CopyTitleFromFileResourceCallback, &titles)); - scheduler_->AddNewDirectory( - fake_drive_service_->GetRootResourceId(), title_3, - AddNewDirectoryOptions(), ClientContext(BACKGROUND), - base::Bind(&CopyTitleFromFileResourceCallback, &titles)); - scheduler_->AddNewDirectory( - fake_drive_service_->GetRootResourceId(), title_4, - AddNewDirectoryOptions(), ClientContext(USER_INITIATED), - base::Bind(&CopyTitleFromFileResourceCallback, &titles)); - - base::RunLoop().RunUntilIdle(); - - ASSERT_EQ(4ul, titles.size()); - EXPECT_EQ(title_1, titles[0]); - EXPECT_EQ(title_4, titles[1]); - EXPECT_EQ(title_2, titles[2]); - EXPECT_EQ(title_3, titles[3]); -} - -TEST_F(JobSchedulerTest, NoConnectionUserInitiated) { - ConnectToNone(); - - std::string resource_id("2_file_resource_id"); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry; - scheduler_->GetFileResource( - resource_id, - ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(google_apis::DRIVE_NO_CONNECTION, error); -} - -TEST_F(JobSchedulerTest, NoConnectionBackground) { - ConnectToNone(); - - std::string resource_id("2_file_resource_id"); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry; - scheduler_->GetFileResource( - resource_id, - ClientContext(BACKGROUND), - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - base::RunLoop().RunUntilIdle(); - - EXPECT_FALSE(entry); - - // Reconnect to the net. - ConnectToWifi(); - - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(google_apis::HTTP_SUCCESS, error); - ASSERT_TRUE(entry); -} - -TEST_F(JobSchedulerTest, DownloadFileCellularDisabled) { - ConnectToCellular(); - - // Disable fetching over cellular network. - pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true); - - // Try to get a file in the background - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - - const base::FilePath kOutputFilePath = - temp_dir.GetPath().AppendASCII("whatever.txt"); - google_apis::DriveApiErrorCode download_error = - google_apis::DRIVE_OTHER_ERROR; - base::FilePath output_file_path; - scheduler_->DownloadFile( - base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path - kDummyDownloadFileSize, - kOutputFilePath, - "2_file_resource_id", - ClientContext(BACKGROUND), - google_apis::test_util::CreateCopyResultCallback( - &download_error, &output_file_path), - google_apis::GetContentCallback()); - // Metadata should still work - google_apis::DriveApiErrorCode metadata_error = - google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::AboutResource> about_resource; - - // Try to get the metadata - scheduler_->GetAboutResource( - google_apis::test_util::CreateCopyResultCallback( - &metadata_error, &about_resource)); - base::RunLoop().RunUntilIdle(); - - // Check the metadata - ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); - ASSERT_TRUE(about_resource); - - // Check the download - EXPECT_EQ(google_apis::DRIVE_OTHER_ERROR, download_error); - - // Switch to a Wifi connection - ConnectToWifi(); - - base::RunLoop().RunUntilIdle(); - - // Check the download again - EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); - std::string content; - EXPECT_EQ(output_file_path, kOutputFilePath); - ASSERT_TRUE(base::ReadFileToString(output_file_path, &content)); - EXPECT_EQ("This is some test content.", content); -} - -TEST_F(JobSchedulerTest, DownloadFileWimaxDisabled) { - ConnectToWimax(); - - // Disable fetching over cellular network. - pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true); - - // Try to get a file in the background - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - - const base::FilePath kOutputFilePath = - temp_dir.GetPath().AppendASCII("whatever.txt"); - google_apis::DriveApiErrorCode download_error = - google_apis::DRIVE_OTHER_ERROR; - base::FilePath output_file_path; - scheduler_->DownloadFile( - base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path - kDummyDownloadFileSize, - kOutputFilePath, - "2_file_resource_id", - ClientContext(BACKGROUND), - google_apis::test_util::CreateCopyResultCallback( - &download_error, &output_file_path), - google_apis::GetContentCallback()); - // Metadata should still work - google_apis::DriveApiErrorCode metadata_error = - google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::AboutResource> about_resource; - - // Try to get the metadata - scheduler_->GetAboutResource( - google_apis::test_util::CreateCopyResultCallback( - &metadata_error, &about_resource)); - base::RunLoop().RunUntilIdle(); - - // Check the metadata - ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); - ASSERT_TRUE(about_resource); - - // Check the download - EXPECT_EQ(google_apis::DRIVE_OTHER_ERROR, download_error); - - // Switch to a Wifi connection - ConnectToWifi(); - - base::RunLoop().RunUntilIdle(); - - // Check the download again - EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); - std::string content; - EXPECT_EQ(output_file_path, kOutputFilePath); - ASSERT_TRUE(base::ReadFileToString(output_file_path, &content)); - EXPECT_EQ("This is some test content.", content); -} - -TEST_F(JobSchedulerTest, DownloadFileCellularEnabled) { - ConnectToCellular(); - - // Enable fetching over cellular network. - pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, false); - - // Try to get a file in the background - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - - const base::FilePath kOutputFilePath = - temp_dir.GetPath().AppendASCII("whatever.txt"); - google_apis::DriveApiErrorCode download_error = - google_apis::DRIVE_OTHER_ERROR; - base::FilePath output_file_path; - scheduler_->DownloadFile( - base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path - kDummyDownloadFileSize, - kOutputFilePath, - "2_file_resource_id", - ClientContext(BACKGROUND), - google_apis::test_util::CreateCopyResultCallback( - &download_error, &output_file_path), - google_apis::GetContentCallback()); - // Metadata should still work - google_apis::DriveApiErrorCode metadata_error = - google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::AboutResource> about_resource; - - // Try to get the metadata - scheduler_->GetAboutResource( - google_apis::test_util::CreateCopyResultCallback( - &metadata_error, &about_resource)); - base::RunLoop().RunUntilIdle(); - - // Check the metadata - ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); - ASSERT_TRUE(about_resource); - - // Check the download - EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); - std::string content; - EXPECT_EQ(output_file_path, kOutputFilePath); - ASSERT_TRUE(base::ReadFileToString(output_file_path, &content)); - EXPECT_EQ("This is some test content.", content); -} - -TEST_F(JobSchedulerTest, DownloadFileWimaxEnabled) { - ConnectToWimax(); - - // Enable fetching over cellular network. - pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, false); - - // Try to get a file in the background - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - - const base::FilePath kOutputFilePath = - temp_dir.GetPath().AppendASCII("whatever.txt"); - google_apis::DriveApiErrorCode download_error = - google_apis::DRIVE_OTHER_ERROR; - base::FilePath output_file_path; - scheduler_->DownloadFile( - base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path - kDummyDownloadFileSize, - kOutputFilePath, - "2_file_resource_id", - ClientContext(BACKGROUND), - google_apis::test_util::CreateCopyResultCallback( - &download_error, &output_file_path), - google_apis::GetContentCallback()); - // Metadata should still work - google_apis::DriveApiErrorCode metadata_error = - google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::AboutResource> about_resource; - - // Try to get the metadata - scheduler_->GetAboutResource( - google_apis::test_util::CreateCopyResultCallback( - &metadata_error, &about_resource)); - base::RunLoop().RunUntilIdle(); - - // Check the metadata - ASSERT_EQ(google_apis::HTTP_SUCCESS, metadata_error); - ASSERT_TRUE(about_resource); - - // Check the download - EXPECT_EQ(google_apis::HTTP_SUCCESS, download_error); - std::string content; - EXPECT_EQ(output_file_path, kOutputFilePath); - ASSERT_TRUE(base::ReadFileToString(output_file_path, &content)); - EXPECT_EQ("This is some test content.", content); -} - -TEST_F(JobSchedulerTest, JobInfo) { - JobListLogger logger; - scheduler_->AddObserver(&logger); - - // Disable background upload/download. - ConnectToWimax(); - pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true); - - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry; - std::unique_ptr<google_apis::AboutResource> about_resource; - base::FilePath path; - - std::set<JobType> expected_types; - - // Add many jobs. - expected_types.insert(TYPE_ADD_NEW_DIRECTORY); - scheduler_->AddNewDirectory( - fake_drive_service_->GetRootResourceId(), "New Directory", - AddNewDirectoryOptions(), ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - expected_types.insert(TYPE_GET_ABOUT_RESOURCE); - scheduler_->GetAboutResource( - google_apis::test_util::CreateCopyResultCallback( - &error, &about_resource)); - expected_types.insert(TYPE_UPDATE_RESOURCE); - scheduler_->UpdateResource( - "2_file_resource_id", std::string(), "New Title", base::Time(), - base::Time(), google_apis::drive::Properties(), - ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - expected_types.insert(TYPE_DOWNLOAD_FILE); - scheduler_->DownloadFile( - base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path - kDummyDownloadFileSize, temp_dir.GetPath().AppendASCII("whatever.txt"), - "2_file_resource_id", ClientContext(BACKGROUND), - google_apis::test_util::CreateCopyResultCallback(&error, &path), - google_apis::GetContentCallback()); - - // The number of jobs queued so far. - EXPECT_EQ(4U, scheduler_->GetJobInfoList().size()); - EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_ADD_NEW_DIRECTORY)); - EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_GET_ABOUT_RESOURCE)); - EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_UPDATE_RESOURCE)); - EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_DOWNLOAD_FILE)); - EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_ADD_NEW_DIRECTORY)); - EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_GET_ABOUT_RESOURCE)); - EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_UPDATE_RESOURCE)); - EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE)); - - // Add more jobs. - expected_types.insert(TYPE_ADD_RESOURCE_TO_DIRECTORY); - scheduler_->AddResourceToDirectory( - "1_folder_resource_id", - "2_file_resource_id", - google_apis::test_util::CreateCopyResultCallback(&error)); - expected_types.insert(TYPE_COPY_RESOURCE); - scheduler_->CopyResource( - "5_document_resource_id", - fake_drive_service_->GetRootResourceId(), - "New Document", - base::Time(), // last_modified - google_apis::test_util::CreateCopyResultCallback(&error, &entry)); - - // 6 jobs in total were queued. - std::vector<JobInfo> jobs = scheduler_->GetJobInfoList(); - EXPECT_EQ(6U, jobs.size()); - std::set<JobType> actual_types; - std::set<JobID> job_ids; - for (size_t i = 0; i < jobs.size(); ++i) { - actual_types.insert(jobs[i].job_type); - job_ids.insert(jobs[i].job_id); - } - EXPECT_EQ(expected_types, actual_types); - EXPECT_EQ(6U, job_ids.size()) << "All job IDs must be unique"; - EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_ADD_RESOURCE_TO_DIRECTORY)); - EXPECT_TRUE(logger.Has(JobListLogger::ADDED, TYPE_COPY_RESOURCE)); - EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_ADD_RESOURCE_TO_DIRECTORY)); - EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_COPY_RESOURCE)); - - // Run the jobs. - base::RunLoop().RunUntilIdle(); - - // All jobs except the BACKGROUND job should have started running (UPDATED) - // and then finished (DONE). - jobs = scheduler_->GetJobInfoList(); - ASSERT_EQ(1U, jobs.size()); - EXPECT_EQ(TYPE_DOWNLOAD_FILE, jobs[0].job_type); - - EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_ADD_NEW_DIRECTORY)); - EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_GET_ABOUT_RESOURCE)); - EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_UPDATE_RESOURCE)); - EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, - TYPE_ADD_RESOURCE_TO_DIRECTORY)); - EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_COPY_RESOURCE)); - EXPECT_FALSE(logger.Has(JobListLogger::UPDATED, TYPE_DOWNLOAD_FILE)); - - EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_ADD_NEW_DIRECTORY)); - EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_GET_ABOUT_RESOURCE)); - EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_UPDATE_RESOURCE)); - EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_ADD_RESOURCE_TO_DIRECTORY)); - EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_COPY_RESOURCE)); - EXPECT_FALSE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE)); - - // Run the background downloading job as well. - ConnectToWifi(); - base::RunLoop().RunUntilIdle(); - - // All jobs should have finished. - EXPECT_EQ(0U, scheduler_->GetJobInfoList().size()); - EXPECT_TRUE(logger.Has(JobListLogger::UPDATED, TYPE_DOWNLOAD_FILE)); - EXPECT_TRUE(logger.Has(JobListLogger::DONE, TYPE_DOWNLOAD_FILE)); -} - -TEST_F(JobSchedulerTest, JobInfoProgress) { - JobListLogger logger; - scheduler_->AddObserver(&logger); - - ConnectToWifi(); - - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - - google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR; - base::FilePath path; - - // Download job. - scheduler_->DownloadFile( - base::FilePath::FromUTF8Unsafe("drive/whatever.txt"), // virtual path - kDummyDownloadFileSize, temp_dir.GetPath().AppendASCII("whatever.txt"), - "2_file_resource_id", ClientContext(BACKGROUND), - google_apis::test_util::CreateCopyResultCallback(&error, &path), - google_apis::GetContentCallback()); - base::RunLoop().RunUntilIdle(); - - std::vector<int64_t> download_progress; - logger.GetProgressInfo(TYPE_DOWNLOAD_FILE, &download_progress); - ASSERT_TRUE(!download_progress.empty()); - EXPECT_TRUE(base::STLIsSorted(download_progress)); - EXPECT_GE(download_progress.front(), 0); - EXPECT_LE(download_progress.back(), 26); - - // Upload job. - path = temp_dir.GetPath().AppendASCII("new_file.txt"); - ASSERT_TRUE(google_apis::test_util::WriteStringToFile(path, kHello)); - google_apis::DriveApiErrorCode upload_error = - google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry; - - scheduler_->UploadNewFile( - fake_drive_service_->GetRootResourceId(), kHelloLen, - base::FilePath::FromUTF8Unsafe("drive/new_file.txt"), path, "dummy title", - "plain/plain", UploadNewFileOptions(), ClientContext(BACKGROUND), - google_apis::test_util::CreateCopyResultCallback(&upload_error, &entry)); - base::RunLoop().RunUntilIdle(); - - std::vector<int64_t> upload_progress; - logger.GetProgressInfo(TYPE_UPLOAD_NEW_FILE, &upload_progress); - ASSERT_TRUE(!upload_progress.empty()); - EXPECT_TRUE(base::STLIsSorted(upload_progress)); - EXPECT_GE(upload_progress.front(), 0); - EXPECT_LE(upload_progress.back(), 13); -} - -TEST_F(JobSchedulerTest, CancelPendingJob) { - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - base::FilePath upload_path = temp_dir.GetPath().AppendASCII("new_file.txt"); - ASSERT_TRUE(google_apis::test_util::WriteStringToFile(upload_path, kHello)); - - // To create a pending job for testing, set the mode to cellular connection - // and issue BACKGROUND jobs. - ConnectToCellular(); - pref_service_->SetBoolean(prefs::kDisableDriveOverCellular, true); - - // Start the first job and record its job ID. - google_apis::DriveApiErrorCode error1 = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry; - scheduler_->UploadNewFile( - fake_drive_service_->GetRootResourceId(), kHelloLen, - base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path, - "dummy title 1", "text/plain", UploadNewFileOptions(), - ClientContext(BACKGROUND), - google_apis::test_util::CreateCopyResultCallback(&error1, &entry)); - - const std::vector<JobInfo>& jobs = scheduler_->GetJobInfoList(); - ASSERT_EQ(1u, jobs.size()); - ASSERT_EQ(STATE_NONE, jobs[0].state); // Not started yet. - JobID first_job_id = jobs[0].job_id; - - // Start the second job. - google_apis::DriveApiErrorCode error2 = google_apis::DRIVE_OTHER_ERROR; - scheduler_->UploadNewFile( - fake_drive_service_->GetRootResourceId(), kHelloLen, - base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path, - "dummy title 2", "text/plain", UploadNewFileOptions(), - ClientContext(BACKGROUND), - google_apis::test_util::CreateCopyResultCallback(&error2, &entry)); - - // Cancel the first one. - scheduler_->CancelJob(first_job_id); - - // Only the first job should be cancelled. - ConnectToWifi(); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(google_apis::DRIVE_CANCELLED, error1); - EXPECT_EQ(google_apis::HTTP_SUCCESS, error2); - EXPECT_TRUE(scheduler_->GetJobInfoList().empty()); -} - -TEST_F(JobSchedulerTest, CancelRunningJob) { - ConnectToWifi(); - - base::ScopedTempDir temp_dir; - ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); - base::FilePath upload_path = temp_dir.GetPath().AppendASCII("new_file.txt"); - ASSERT_TRUE(google_apis::test_util::WriteStringToFile(upload_path, kHello)); - - // Run as a cancelable task. - fake_drive_service_->set_upload_new_file_cancelable(true); - google_apis::DriveApiErrorCode error1 = google_apis::DRIVE_OTHER_ERROR; - std::unique_ptr<google_apis::FileResource> entry; - scheduler_->UploadNewFile( - fake_drive_service_->GetRootResourceId(), kHelloLen, - base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path, - "dummy title 1", "text/plain", UploadNewFileOptions(), - ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error1, &entry)); - - const std::vector<JobInfo>& jobs = scheduler_->GetJobInfoList(); - ASSERT_EQ(1u, jobs.size()); - ASSERT_EQ(STATE_RUNNING, jobs[0].state); // It's running. - JobID first_job_id = jobs[0].job_id; - - // Start the second job normally. - fake_drive_service_->set_upload_new_file_cancelable(false); - google_apis::DriveApiErrorCode error2 = google_apis::DRIVE_OTHER_ERROR; - scheduler_->UploadNewFile( - fake_drive_service_->GetRootResourceId(), kHelloLen, - base::FilePath::FromUTF8Unsafe("dummy/path"), upload_path, - "dummy title 2", "text/plain", UploadNewFileOptions(), - ClientContext(USER_INITIATED), - google_apis::test_util::CreateCopyResultCallback(&error2, &entry)); - - // Cancel the first one. - scheduler_->CancelJob(first_job_id); - - // Only the first job should be cancelled. - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(google_apis::DRIVE_CANCELLED, error1); - EXPECT_EQ(google_apis::HTTP_SUCCESS, error2); - EXPECT_TRUE(scheduler_->GetJobInfoList().empty()); -} - -} // namespace drive
diff --git a/components/drive/local_file_reader.cc b/components/drive/local_file_reader.cc deleted file mode 100644 index 9131fae..0000000 --- a/components/drive/local_file_reader.cc +++ /dev/null
@@ -1,67 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/local_file_reader.h" - -#include <utility> - -#include "base/bind.h" -#include "base/files/file_path.h" -#include "base/sequenced_task_runner.h" -#include "net/base/completion_once_callback.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" - -namespace drive { -namespace util { - -LocalFileReader::LocalFileReader( - base::SequencedTaskRunner* sequenced_task_runner) - : file_stream_(sequenced_task_runner) {} - -LocalFileReader::~LocalFileReader() = default; - -void LocalFileReader::Open(const base::FilePath& file_path, - int64_t offset, - net::CompletionOnceCallback callback) { - DCHECK(!callback.is_null()); - int flags = base::File::FLAG_OPEN | base::File::FLAG_READ | - base::File::FLAG_ASYNC; - - int rv = file_stream_.Open( - file_path, flags, - BindOnce(&LocalFileReader::DidOpen, weak_ptr_factory_.GetWeakPtr(), - std::move(callback), offset)); - DCHECK_EQ(rv, net::ERR_IO_PENDING); -} - -void LocalFileReader::Read(net::IOBuffer* in_buffer, - int buffer_length, - net::CompletionOnceCallback callback) { - DCHECK(!callback.is_null()); - DCHECK(file_stream_.IsOpen()); - int rv = file_stream_.Read(in_buffer, buffer_length, std::move(callback)); - DCHECK_EQ(rv, net::ERR_IO_PENDING); -} - -void LocalFileReader::DidOpen(net::CompletionOnceCallback callback, - int64_t offset, - int error) { - if (error != net::OK) - return std::move(callback).Run(error); - - int rv = file_stream_.Seek(offset, BindOnce(&LocalFileReader::DidSeek, - weak_ptr_factory_.GetWeakPtr(), - std::move(callback), offset)); - DCHECK_EQ(rv, net::ERR_IO_PENDING); -} - -void LocalFileReader::DidSeek(net::CompletionOnceCallback callback, - int64_t offset, - int64_t error) { - std::move(callback).Run(error == offset ? net::OK : net::ERR_FAILED); -} - -} // namespace util -} // namespace drive
diff --git a/components/drive/local_file_reader.h b/components/drive/local_file_reader.h deleted file mode 100644 index 2fba1a7c6..0000000 --- a/components/drive/local_file_reader.h +++ /dev/null
@@ -1,70 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_LOCAL_FILE_READER_H_ -#define COMPONENTS_DRIVE_LOCAL_FILE_READER_H_ - -#include <stdint.h> - -#include "base/macros.h" -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "net/base/completion_once_callback.h" -#include "net/base/file_stream.h" - -namespace base { -class FilePath; -class SequencedTaskRunner; -} // namespace base - -namespace net { -class IOBuffer; -} // namespace net - -namespace drive { -namespace util { - -// This is simple local file reader implementation focusing on Drive's use -// case. All the operations run on |sequenced_task_runner| asynchronously and -// the result will be notified to the caller via |callback|s on the caller's -// thread. -class LocalFileReader { - public: - explicit LocalFileReader(base::SequencedTaskRunner* sequenced_task_runner); - ~LocalFileReader(); - - // Opens the file at |file_path|. The initial position of the read will be - // at |offset| from the beginning of the file. - // Upon completion, |callback| will be called. - // |callback| must not be null. - void Open(const base::FilePath& file_path, - int64_t offset, - net::CompletionOnceCallback callback); - - // Reads the file and copies the data into |buffer|. |buffer_length| - // is the length of |buffer|. - // Upon completion, |callback| will be called with the result. - // |callback| must not be null. - void Read(net::IOBuffer* buffer, - int buffer_length, - net::CompletionOnceCallback callback); - - private: - void DidOpen(net::CompletionOnceCallback callback, int64_t offset, int error); - void DidSeek(net::CompletionOnceCallback callback, - int64_t offset, - int64_t error); - - net::FileStream file_stream_; - - // Note: This should remain the last member so it'll be destroyed and - // invalidate the weak pointers before any other members are destroyed. - base::WeakPtrFactory<LocalFileReader> weak_ptr_factory_{this}; - DISALLOW_COPY_AND_ASSIGN(LocalFileReader); -}; - -} // namespace util -} // namespace drive - -#endif // COMPONENTS_DRIVE_LOCAL_FILE_READER_H_
diff --git a/components/drive/local_file_reader_unittest.cc b/components/drive/local_file_reader_unittest.cc deleted file mode 100644 index e3028811..0000000 --- a/components/drive/local_file_reader_unittest.cc +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/local_file_reader.h" - -#include <stddef.h> -#include <stdint.h> - -#include <memory> -#include <string> -#include <utility> - -#include "base/files/file_path.h" -#include "base/files/scoped_temp_dir.h" -#include "base/memory/ref_counted.h" -#include "base/rand_util.h" -#include "base/test/task_environment.h" -#include "base/threading/thread.h" -#include "components/drive/chromeos/drive_test_util.h" -#include "google_apis/drive/test_util.h" -#include "net/base/io_buffer.h" -#include "net/base/test_completion_callback.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { -namespace util { -namespace { - -// An adapter to use test_util::ReadAllData. -class LocalFileReaderAdapter { - public: - explicit LocalFileReaderAdapter(LocalFileReader* reader) : reader_(reader) {} - int Read(net::IOBuffer* buffer, - int buffer_length, - net::CompletionOnceCallback callback) { - reader_->Read(buffer, buffer_length, std::move(callback)); - // As LocalFileReader::Read always works asynchronously, - // return ERR_IO_PENDING. - return net::ERR_IO_PENDING; - } - - private: - LocalFileReader* reader_; -}; - -} // namespace - -class LocalFileReaderTest : public ::testing::Test { - protected: - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - worker_thread_ = std::make_unique<base::Thread>("LocalFileReaderTest"); - ASSERT_TRUE(worker_thread_->Start()); - file_reader_ = - std::make_unique<LocalFileReader>(worker_thread_->task_runner().get()); - } - - base::test::SingleThreadTaskEnvironment task_environment_; - base::ScopedTempDir temp_dir_; - std::unique_ptr<base::Thread> worker_thread_; - std::unique_ptr<LocalFileReader> file_reader_; -}; - -TEST_F(LocalFileReaderTest, NonExistingFile) { - const base::FilePath kTestFile = - temp_dir_.GetPath().AppendASCII("non-existing"); - - net::TestCompletionCallback callback; - file_reader_->Open(kTestFile, 0, callback.callback()); - EXPECT_EQ(net::ERR_FILE_NOT_FOUND, callback.WaitForResult()); -} - -TEST_F(LocalFileReaderTest, FullRead) { - base::FilePath test_file; - std::string expected_content; - ASSERT_TRUE(google_apis::test_util::CreateFileOfSpecifiedSize( - temp_dir_.GetPath(), 1024, &test_file, &expected_content)); - - net::TestCompletionCallback callback; - file_reader_->Open(test_file, 0, callback.callback()); - ASSERT_EQ(net::OK, callback.WaitForResult()); - - LocalFileReaderAdapter adapter(file_reader_.get()); - std::string content; - ASSERT_EQ(net::OK, test_util::ReadAllData(&adapter, &content)); - EXPECT_EQ(expected_content, content); -} - -TEST_F(LocalFileReaderTest, OpenWithOffset) { - base::FilePath test_file; - std::string expected_content; - ASSERT_TRUE(google_apis::test_util::CreateFileOfSpecifiedSize( - temp_dir_.GetPath(), 1024, &test_file, &expected_content)); - - size_t offset = expected_content.size() / 2; - expected_content.erase(0, offset); - - net::TestCompletionCallback callback; - file_reader_->Open(test_file, static_cast<int64_t>(offset), - callback.callback()); - ASSERT_EQ(net::OK, callback.WaitForResult()); - - LocalFileReaderAdapter adapter(file_reader_.get()); - std::string content; - ASSERT_EQ(net::OK, test_util::ReadAllData(&adapter, &content)); - EXPECT_EQ(expected_content, content); -} - -} // namespace util -} // namespace drive
diff --git a/components/drive/remove_stale_cache_files_unittest.cc b/components/drive/remove_stale_cache_files_unittest.cc deleted file mode 100644 index 3fed4df7..0000000 --- a/components/drive/remove_stale_cache_files_unittest.cc +++ /dev/null
@@ -1,115 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/chromeos/remove_stale_cache_files.h" - -#include <memory> -#include <string> - -#include "base/files/file_path.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" -#include "base/single_thread_task_runner.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/drive/chromeos/drive_test_util.h" -#include "components/drive/chromeos/fake_free_disk_space_getter.h" -#include "components/drive/chromeos/resource_metadata.h" -#include "components/drive/drive.pb.h" -#include "components/drive/file_system_core_util.h" -#include "content/public/test/browser_task_environment.h" -#include "google_apis/drive/test_util.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { -namespace internal { - -class RemoveStaleCacheFilesTest : public testing::Test { - protected: - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - - fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>(); - - metadata_storage_.reset(new ResourceMetadataStorage( - temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); - - cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(), - base::ThreadTaskRunnerHandle::Get().get(), - fake_free_disk_space_getter_.get())); - - resource_metadata_.reset(new ResourceMetadata( - metadata_storage_.get(), cache_.get(), - base::ThreadTaskRunnerHandle::Get())); - - ASSERT_TRUE(metadata_storage_->Initialize()); - ASSERT_TRUE(cache_->Initialize()); - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize()); - } - - content::BrowserTaskEnvironment task_environment_; - base::ScopedTempDir temp_dir_; - - std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests> - metadata_storage_; - std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_; - std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> - resource_metadata_; - std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_; -}; - -TEST_F(RemoveStaleCacheFilesTest, RemoveStaleCacheFiles) { - base::FilePath dummy_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &dummy_file)); - std::string md5_metadata("abcdef0123456789"), md5_cache("ABCDEF9876543210"); - - // Create a stale cache file. - ResourceEntry entry; - std::string local_id; - entry.mutable_file_specific_info()->set_md5(md5_metadata); - entry.set_parent_local_id(util::kDriveGrandRootLocalId); - entry.set_title("File.txt"); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(entry, &local_id)); - - EXPECT_EQ(FILE_ERROR_OK, - cache_->Store(local_id, md5_cache, dummy_file, - FileCache::FILE_OPERATION_COPY)); - - // Remove stale cache files. - RemoveStaleCacheFiles(cache_.get(), resource_metadata_.get()); - - // Verify that the cache is deleted. - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->GetResourceEntryById(local_id, &entry)); - EXPECT_FALSE(entry.file_specific_info().cache_state().is_present()); -} - -TEST_F(RemoveStaleCacheFilesTest, DirtyCacheFiles) { - base::FilePath dummy_file; - ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &dummy_file)); - - // Dirty entry. - std::string md5_metadata("abcdef0123456789"); - - ResourceEntry entry; - std::string local_id; - entry.mutable_file_specific_info()->set_md5(md5_metadata); - entry.set_parent_local_id(util::kDriveGrandRootLocalId); - entry.set_title("file.txt"); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(entry, &local_id)); - - EXPECT_EQ(FILE_ERROR_OK, - cache_->Store(local_id, std::string(), dummy_file, - FileCache::FILE_OPERATION_COPY)); - - // Remove stale cache files. - RemoveStaleCacheFiles(cache_.get(), resource_metadata_.get()); - - // Dirty cache should not be removed even though its MD5 doesn't match. - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->GetResourceEntryById(local_id, &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_present()); -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/resource_entry_conversion.cc b/components/drive/resource_entry_conversion.cc deleted file mode 100644 index 2c7f2b9..0000000 --- a/components/drive/resource_entry_conversion.cc +++ /dev/null
@@ -1,188 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/resource_entry_conversion.h" - -#include <stdint.h> - -#include <string> - -#include "base/logging.h" -#include "base/time/time.h" -#include "components/drive/drive.pb.h" -#include "components/drive/drive_api_util.h" -#include "components/drive/file_system_core_util.h" -#include "google_apis/drive/drive_api_parser.h" - -namespace drive { - -void ConvertChangeResourceToResourceEntry( - const google_apis::ChangeResource& input, - ResourceEntry* out_entry, - std::string* out_parent_resource_id) { - DCHECK(out_entry); - DCHECK(out_parent_resource_id); - - out_entry->Clear(); - out_parent_resource_id->clear(); - - if (input.type() == google_apis::ChangeResource::TEAM_DRIVE) { - if (input.team_drive()) { - ConvertTeamDriveResourceToResourceEntry(*input.team_drive(), out_entry); - } else { - // resource_id is same as the Team Drive ID. - // Both team_drive_id() and team_drive().id() holds the same ID, but the - // latter doesn't exist for deleted items. - out_entry->set_resource_id(input.team_drive_id()); - out_entry->mutable_file_info()->set_is_directory(true); - out_entry->mutable_file_info()->set_is_team_drive_root(true); - out_entry->set_parent_local_id(util::kDriveTeamDrivesDirLocalId); - } - } else { - if (input.file()) { - ConvertFileResourceToResourceEntry(*input.file(), out_entry, - out_parent_resource_id); - } - out_entry->set_resource_id(input.file_id()); - } - out_entry->set_deleted(out_entry->deleted() || input.is_deleted()); - out_entry->set_modification_date(input.modification_date().ToInternalValue()); -} - -void ConvertFileResourceToResourceEntry(const google_apis::FileResource& input, - ResourceEntry* out_entry, - std::string* out_parent_resource_id) { - DCHECK(out_entry); - DCHECK(out_parent_resource_id); - - out_entry->Clear(); - out_parent_resource_id->clear(); - - // For regular files, the 'filename' and 'title' attribute in the metadata - // may be different (e.g. due to rename). To be consistent with the web - // interface and other client to use the 'title' attribute, instead of - // 'filename', as the file name in the local snapshot. - out_entry->set_title(input.title()); - out_entry->set_base_name(util::NormalizeFileName(out_entry->title())); - out_entry->set_resource_id(input.file_id()); - - // Gets parent Resource ID. On drive.google.com, a file can have multiple - // parents or no parent, but we are forcing a tree-shaped structure (i.e. no - // multi-parent or zero-parent entries). Therefore the first found "parent" is - // used for the entry. Tracked in http://crbug.com/158904. - if (!input.parents().empty()) - out_parent_resource_id->assign(input.parents()[0].file_id()); - - out_entry->set_deleted(input.labels().is_trashed()); - out_entry->set_starred(input.labels().is_starred()); - out_entry->set_shared_with_me(!input.shared_with_me_date().is_null()); - out_entry->set_shared(input.shared()); - if (!input.alternate_link().is_empty()) - out_entry->set_alternate_url(input.alternate_link().spec()); - - PlatformFileInfoProto* file_info = out_entry->mutable_file_info(); - - file_info->set_last_modified(input.modified_date().ToInternalValue()); - out_entry->set_last_modified_by_me( - input.modified_by_me_date().ToInternalValue()); - // If the file has never been viewed (last_viewed_by_me_date().is_null() == - // true), then we will set the last_accessed field in the protocol buffer to - // 0. - file_info->set_last_accessed( - input.last_viewed_by_me_date().ToInternalValue()); - file_info->set_creation_time(input.created_date().ToInternalValue()); - - // Set the capabilities. - const google_apis::FileResourceCapabilities& capabilities = - input.capabilities(); - out_entry->mutable_capabilities_info()->set_can_copy(capabilities.can_copy()); - out_entry->mutable_capabilities_info()->set_can_delete( - capabilities.can_delete()); - out_entry->mutable_capabilities_info()->set_can_rename( - capabilities.can_rename()); - out_entry->mutable_capabilities_info()->set_can_add_children( - capabilities.can_add_children()); - out_entry->mutable_capabilities_info()->set_can_share( - capabilities.can_share()); - - if (input.IsDirectory()) { - file_info->set_is_directory(true); - } else { - FileSpecificInfo* file_specific_info = - out_entry->mutable_file_specific_info(); - if (!input.IsHostedDocument()) { - file_info->set_size(input.file_size()); - file_specific_info->set_md5(input.md5_checksum()); - file_specific_info->set_is_hosted_document(false); - } else { - // Attach .g<something> extension to hosted documents so we can special - // case their handling in UI. - // TODO(satorux): Figure out better way how to pass input info like kind - // to UI through the File API stack. - const std::string document_extension = - drive::util::GetHostedDocumentExtension(input.mime_type()); - file_specific_info->set_document_extension(document_extension); - out_entry->set_base_name( - util::NormalizeFileName(out_entry->title() + document_extension)); - - // We don't know the size of hosted docs and it does not matter since - // it has no effect on the quota. - file_info->set_size(0); - file_specific_info->set_is_hosted_document(true); - } - file_info->set_is_directory(false); - file_specific_info->set_content_mime_type(input.mime_type()); - - const int64_t image_width = input.image_media_metadata().width(); - if (image_width != -1) - file_specific_info->set_image_width(image_width); - - const int64_t image_height = input.image_media_metadata().height(); - if (image_height != -1) - file_specific_info->set_image_height(image_height); - - const int64_t image_rotation = input.image_media_metadata().rotation(); - if (image_rotation != -1) - file_specific_info->set_image_rotation(image_rotation); - } -} - -void ConvertTeamDriveResourceToResourceEntry( - const google_apis::TeamDriveResource& input, - ResourceEntry* out_entry) { - DCHECK(out_entry); - out_entry->mutable_file_info()->set_is_directory(true); - out_entry->mutable_file_info()->set_is_team_drive_root(true); - out_entry->set_title(input.name()); - out_entry->set_base_name(input.name()); - out_entry->set_resource_id(input.id()); - out_entry->set_parent_local_id(util::kDriveTeamDrivesDirLocalId); - - // Set all the capabilities. - const google_apis::TeamDriveCapabilities& capabilities = input.capabilities(); - out_entry->mutable_capabilities_info()->set_can_copy(capabilities.can_copy()); - out_entry->mutable_capabilities_info()->set_can_delete( - capabilities.can_delete_team_drive()); - out_entry->mutable_capabilities_info()->set_can_rename( - capabilities.can_rename_team_drive()); - out_entry->mutable_capabilities_info()->set_can_add_children( - capabilities.can_add_children()); - out_entry->mutable_capabilities_info()->set_can_share( - capabilities.can_share()); -} - -void ConvertResourceEntryToFileInfo(const ResourceEntry& entry, - base::File::Info* file_info) { - file_info->size = entry.file_info().size(); - file_info->is_directory = entry.file_info().is_directory(); - file_info->is_symbolic_link = entry.file_info().is_symbolic_link(); - file_info->last_modified = base::Time::FromInternalValue( - entry.file_info().last_modified()); - file_info->last_accessed = base::Time::FromInternalValue( - entry.file_info().last_accessed()); - file_info->creation_time = base::Time::FromInternalValue( - entry.file_info().creation_time()); -} - -} // namespace drive
diff --git a/components/drive/resource_entry_conversion.h b/components/drive/resource_entry_conversion.h deleted file mode 100644 index ac1cd47d..0000000 --- a/components/drive/resource_entry_conversion.h +++ /dev/null
@@ -1,57 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_DRIVE_RESOURCE_ENTRY_CONVERSION_H_ -#define COMPONENTS_DRIVE_RESOURCE_ENTRY_CONVERSION_H_ - -#include <string> - -#include "base/files/file.h" - -namespace google_apis { -class ChangeResource; -class FileResource; -class TeamDriveResource; -} - -namespace drive { - -class ResourceEntry; - -// Converts a google_apis::ChangeResource into a drive::ResourceEntry. -// The converted result will be stored in |out_entry| and -// |out_parent_resource_id| will be set to the resource ID of the parent entry. -// -// Every entry is guaranteed to have one parent resource ID in ResourceMetadata. -// This requirement is needed to represent contents in Drive as a file system -// tree, and achieved as follows: -// -// 1) Entries without parents are allowed on drive.google.com. These entries are -// collected to "drive/other", and have "drive/other" as the parent. -// -// 2) Entries with multiple parents are allowed on drive.google.com. For these -// entries, the first parent is chosen. -void ConvertChangeResourceToResourceEntry( - const google_apis::ChangeResource& input, - ResourceEntry* out_entry, - std::string* out_parent_resource_id); - -// Converts a google_apis::FileResource into a drive::ResourceEntry. -// Also see the comment for ConvertChangeResourceToResourceEntry above. -void ConvertFileResourceToResourceEntry(const google_apis::FileResource& input, - ResourceEntry* out_entry, - std::string* out_parent_resource_id); - -// Converts a TeamDriveResource into a drive::ResourceEntry. -void ConvertTeamDriveResourceToResourceEntry( - const google_apis::TeamDriveResource& input, - ResourceEntry* out_entry); - -// Converts the resource entry to the platform file info. -void ConvertResourceEntryToFileInfo(const ResourceEntry& entry, - base::File::Info* file_info); - -} // namespace drive - -#endif // COMPONENTS_DRIVE_RESOURCE_ENTRY_CONVERSION_H_
diff --git a/components/drive/resource_entry_conversion_unittest.cc b/components/drive/resource_entry_conversion_unittest.cc deleted file mode 100644 index 7ca0eba..0000000 --- a/components/drive/resource_entry_conversion_unittest.cc +++ /dev/null
@@ -1,527 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/resource_entry_conversion.h" - -#include <memory> - -#include "base/time/time.h" -#include "components/drive/drive.pb.h" -#include "components/drive/drive_api_util.h" -#include "components/drive/file_system_core_util.h" -#include "google_apis/drive/drive_api_parser.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { - -namespace { - -base::Time GetTestTime() { - // 2011-12-14-T00:40:47.330Z - base::Time::Exploded exploded; - exploded.year = 2011; - exploded.month = 12; - exploded.day_of_month = 14; - exploded.day_of_week = 2; // Tuesday - exploded.hour = 0; - exploded.minute = 40; - exploded.second = 47; - exploded.millisecond = 330; - base::Time out_time; - EXPECT_TRUE(base::Time::FromUTCExploded(exploded, &out_time)); - return out_time; -} - -} // namespace - -TEST(ResourceEntryConversionTest, ConvertToResourceEntry_File) { - google_apis::FileResource file_resource; - file_resource.set_title("File 1.mp3"); - file_resource.set_file_id("resource_id"); - file_resource.set_created_date(GetTestTime()); - file_resource.set_modified_date( - GetTestTime() + base::TimeDelta::FromSeconds(10)); - file_resource.set_modified_by_me_date(GetTestTime() + - base::TimeDelta::FromSeconds(5)); - file_resource.set_mime_type("audio/mpeg"); - file_resource.set_alternate_link(GURL("https://file_link_alternate")); - file_resource.set_file_size(892721); - file_resource.set_md5_checksum("3b4382ebefec6e743578c76bbd0575ce"); - - google_apis::FileResourceCapabilities capabilities; - capabilities.set_can_copy(true); - capabilities.set_can_delete(false); - capabilities.set_can_rename(true); - capabilities.set_can_add_children(false); - capabilities.set_can_share(true); - file_resource.set_capabilities(capabilities); - - ResourceEntry entry; - std::string parent_resource_id; - ConvertFileResourceToResourceEntry(file_resource, &entry, - &parent_resource_id); - - EXPECT_EQ(file_resource.title(), entry.title()); - EXPECT_EQ(file_resource.title(), entry.base_name()); - EXPECT_EQ(file_resource.file_id(), entry.resource_id()); - EXPECT_EQ("", parent_resource_id); - - EXPECT_FALSE(entry.deleted()); - EXPECT_FALSE(entry.starred()); - EXPECT_FALSE(entry.shared_with_me()); - EXPECT_FALSE(entry.shared()); - - EXPECT_EQ(file_resource.modified_date().ToInternalValue(), - entry.file_info().last_modified()); - EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(), - entry.last_modified_by_me()); - // Last accessed value equal to 0 means that the file has never been viewed. - EXPECT_EQ(0, entry.file_info().last_accessed()); - EXPECT_EQ(file_resource.created_date().ToInternalValue(), - entry.file_info().creation_time()); - EXPECT_EQ(file_resource.alternate_link().spec(), entry.alternate_url()); - - EXPECT_EQ(file_resource.mime_type(), - entry.file_specific_info().content_mime_type()); - EXPECT_FALSE(entry.file_specific_info().is_hosted_document()); - - // Regular file specific fields. - EXPECT_EQ(file_resource.file_size(), entry.file_info().size()); - EXPECT_EQ(file_resource.md5_checksum(), entry.file_specific_info().md5()); - EXPECT_FALSE(entry.file_info().is_directory()); - - // Capabilities. - EXPECT_TRUE(entry.capabilities_info().can_copy()); - EXPECT_FALSE(entry.capabilities_info().can_delete()); - EXPECT_TRUE(entry.capabilities_info().can_rename()); - EXPECT_FALSE(entry.capabilities_info().can_add_children()); - EXPECT_TRUE(entry.capabilities_info().can_share()); -} - -TEST(ResourceEntryConversionTest, - ConvertFileResourceToResourceEntry_HostedDocument) { - google_apis::FileResource file_resource; - file_resource.set_title("Document 1"); - file_resource.set_file_id("resource_id"); - file_resource.set_created_date(GetTestTime()); - file_resource.set_modified_date( - GetTestTime() + base::TimeDelta::FromSeconds(10)); - file_resource.set_modified_by_me_date(GetTestTime() + - base::TimeDelta::FromSeconds(5)); - file_resource.set_last_viewed_by_me_date( - GetTestTime() + base::TimeDelta::FromSeconds(20)); - file_resource.set_mime_type(util::kGoogleDocumentMimeType); - file_resource.set_alternate_link(GURL("https://file_link_alternate")); - // Do not set file size to represent a hosted document. - - google_apis::FileResourceCapabilities capabilities; - capabilities.set_can_copy(false); - capabilities.set_can_delete(true); - capabilities.set_can_rename(false); - capabilities.set_can_add_children(true); - capabilities.set_can_share(false); - file_resource.set_capabilities(capabilities); - - ResourceEntry entry; - std::string parent_resource_id; - ConvertFileResourceToResourceEntry(file_resource, &entry, - &parent_resource_id); - - EXPECT_EQ(file_resource.title(), entry.title()); - EXPECT_EQ(file_resource.title() + ".gdoc", - entry.base_name()); // The suffix added. - EXPECT_EQ(".gdoc", entry.file_specific_info().document_extension()); - EXPECT_EQ(file_resource.file_id(), entry.resource_id()); - EXPECT_EQ("", parent_resource_id); - - EXPECT_FALSE(entry.deleted()); - EXPECT_FALSE(entry.starred()); - EXPECT_FALSE(entry.shared_with_me()); - EXPECT_FALSE(entry.shared()); - - EXPECT_EQ(file_resource.modified_date().ToInternalValue(), - entry.file_info().last_modified()); - EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(), - entry.last_modified_by_me()); - EXPECT_EQ(file_resource.last_viewed_by_me_date().ToInternalValue(), - entry.file_info().last_accessed()); - EXPECT_EQ(file_resource.created_date().ToInternalValue(), - entry.file_info().creation_time()); - EXPECT_EQ(file_resource.alternate_link().spec(), entry.alternate_url()); - - EXPECT_EQ(file_resource.mime_type(), - entry.file_specific_info().content_mime_type()); - EXPECT_TRUE(entry.file_specific_info().is_hosted_document()); - - // The size should be 0 for a hosted document. - EXPECT_EQ(0, entry.file_info().size()); - EXPECT_FALSE(entry.file_info().is_directory()); - - // Capabilities. - EXPECT_FALSE(entry.capabilities_info().can_copy()); - EXPECT_TRUE(entry.capabilities_info().can_delete()); - EXPECT_FALSE(entry.capabilities_info().can_rename()); - EXPECT_TRUE(entry.capabilities_info().can_add_children()); - EXPECT_FALSE(entry.capabilities_info().can_share()); -} - -TEST(ResourceEntryConversionTest, - ConvertFileResourceToResourceEntry_Directory) { - google_apis::FileResource file_resource; - file_resource.set_title("Folder"); - file_resource.set_file_id("resource_id"); - file_resource.set_created_date(GetTestTime()); - file_resource.set_modified_date( - GetTestTime() + base::TimeDelta::FromSeconds(10)); - file_resource.set_modified_by_me_date(GetTestTime() + - base::TimeDelta::FromSeconds(5)); - file_resource.set_last_viewed_by_me_date( - GetTestTime() + base::TimeDelta::FromSeconds(20)); - file_resource.set_mime_type(util::kDriveFolderMimeType); - - google_apis::ParentReference parent; - parent.set_file_id("parent_resource_id"); - file_resource.mutable_parents()->push_back(parent); - - ResourceEntry entry; - std::string parent_resource_id; - ConvertFileResourceToResourceEntry(file_resource, &entry, - &parent_resource_id); - - EXPECT_EQ(file_resource.title(), entry.title()); - EXPECT_EQ(file_resource.title(), entry.base_name()); - EXPECT_EQ(file_resource.file_id(), entry.resource_id()); - EXPECT_EQ(file_resource.alternate_link().spec(), entry.alternate_url()); - // The parent resource ID should be obtained as this is a sub directory - // under a non-root directory. - EXPECT_EQ(parent.file_id(), parent_resource_id); - - EXPECT_FALSE(entry.deleted()); - EXPECT_FALSE(entry.starred()); - EXPECT_FALSE(entry.shared_with_me()); - EXPECT_FALSE(entry.shared()); - - EXPECT_EQ(file_resource.modified_date().ToInternalValue(), - entry.file_info().last_modified()); - EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(), - entry.last_modified_by_me()); - EXPECT_EQ(file_resource.last_viewed_by_me_date().ToInternalValue(), - entry.file_info().last_accessed()); - EXPECT_EQ(file_resource.created_date().ToInternalValue(), - entry.file_info().creation_time()); - - EXPECT_TRUE(entry.file_info().is_directory()); -} - -TEST(ResourceEntryConversionTest, - ConvertFileResourceToResourceEntry_DeletedHostedDocument) { - google_apis::FileResource file_resource; - file_resource.set_title("Document 1"); - file_resource.set_file_id("resource_id"); - file_resource.set_created_date(GetTestTime()); - file_resource.set_modified_date( - GetTestTime() + base::TimeDelta::FromSeconds(10)); - file_resource.set_modified_by_me_date(GetTestTime() + - base::TimeDelta::FromSeconds(5)); - file_resource.set_last_viewed_by_me_date( - GetTestTime() + base::TimeDelta::FromSeconds(20)); - file_resource.set_mime_type(util::kGoogleDocumentMimeType); - file_resource.set_alternate_link(GURL("https://file_link_alternate")); - file_resource.mutable_labels()->set_trashed(true); - - ResourceEntry entry; - std::string parent_resource_id; - ConvertFileResourceToResourceEntry(file_resource, &entry, - &parent_resource_id); - - EXPECT_EQ(file_resource.title(), entry.title()); - EXPECT_EQ(file_resource.title() + ".gdoc", entry.base_name()); - EXPECT_EQ(file_resource.file_id(), entry.resource_id()); - EXPECT_EQ(file_resource.alternate_link().spec(), entry.alternate_url()); - EXPECT_EQ("", parent_resource_id); - - EXPECT_TRUE(entry.deleted()); // The document was deleted. - EXPECT_FALSE(entry.starred()); - EXPECT_FALSE(entry.shared_with_me()); - EXPECT_FALSE(entry.shared()); - - EXPECT_EQ(file_resource.modified_date().ToInternalValue(), - entry.file_info().last_modified()); - EXPECT_EQ(file_resource.modified_by_me_date().ToInternalValue(), - entry.last_modified_by_me()); - EXPECT_EQ(file_resource.last_viewed_by_me_date().ToInternalValue(), - entry.file_info().last_accessed()); - EXPECT_EQ(file_resource.created_date().ToInternalValue(), - entry.file_info().creation_time()); - - EXPECT_EQ(file_resource.mime_type(), - entry.file_specific_info().content_mime_type()); - EXPECT_TRUE(entry.file_specific_info().is_hosted_document()); - - // The size should be 0 for a hosted document. - EXPECT_EQ(0, entry.file_info().size()); -} - -TEST(ResourceEntryConversionTest, ConvertChangeResourceToResourceEntry) { - google_apis::ChangeResource change_resource; - change_resource.set_type(google_apis::ChangeResource::FILE); - change_resource.set_file(std::make_unique<google_apis::FileResource>()); - change_resource.set_file_id("resource_id"); - change_resource.set_modification_date(GetTestTime()); - - google_apis::FileResource* file_resource = change_resource.mutable_file(); - file_resource->set_title("File 1.mp3"); - file_resource->set_file_id("resource_id"); - // Set dummy file size to declare that this is a regular file. - file_resource->set_file_size(12345); - - ResourceEntry entry; - std::string parent_resource_id; - ConvertChangeResourceToResourceEntry(change_resource, &entry, - &parent_resource_id); - - EXPECT_EQ(change_resource.file_id(), entry.resource_id()); - EXPECT_EQ(change_resource.modification_date().ToInternalValue(), - entry.modification_date()); - - EXPECT_EQ(file_resource->title(), entry.title()); - EXPECT_EQ(file_resource->title(), entry.base_name()); - EXPECT_EQ("", parent_resource_id); - - EXPECT_FALSE(entry.deleted()); -} - -TEST(ResourceEntryConversionTest, - ConvertChangeResourceToResourceEntry_Trashed) { - google_apis::ChangeResource change_resource; - change_resource.set_type(google_apis::ChangeResource::FILE); - change_resource.set_file(std::make_unique<google_apis::FileResource>()); - change_resource.set_file_id("resource_id"); - change_resource.set_modification_date(GetTestTime()); - - google_apis::FileResource* file_resource = change_resource.mutable_file(); - file_resource->set_title("File 1.mp3"); - file_resource->set_file_id("resource_id"); - // Set dummy file size to declare that this is a regular file. - file_resource->set_file_size(12345); - file_resource->mutable_labels()->set_trashed(true); - - ResourceEntry entry; - std::string parent_resource_id; - ConvertChangeResourceToResourceEntry(change_resource, &entry, - &parent_resource_id); - - EXPECT_EQ(change_resource.file_id(), entry.resource_id()); - EXPECT_EQ(change_resource.modification_date().ToInternalValue(), - entry.modification_date()); - - EXPECT_EQ(file_resource->title(), entry.title()); - EXPECT_EQ(file_resource->title(), entry.base_name()); - EXPECT_EQ("", parent_resource_id); - - EXPECT_TRUE(entry.deleted()); -} - -TEST(ResourceEntryConversionTest, - ConvertChangeResourceToResourceEntry_Deleted) { - google_apis::ChangeResource change_resource; - change_resource.set_type(google_apis::ChangeResource::FILE); - change_resource.set_deleted(true); - change_resource.set_file_id("resource_id"); - change_resource.set_modification_date(GetTestTime()); - - ResourceEntry entry; - std::string parent_resource_id; - ConvertChangeResourceToResourceEntry(change_resource, &entry, - &parent_resource_id); - - EXPECT_EQ(change_resource.file_id(), entry.resource_id()); - EXPECT_EQ("", parent_resource_id); - - EXPECT_TRUE(entry.deleted()); - - EXPECT_EQ(change_resource.modification_date().ToInternalValue(), - entry.modification_date()); -} - -TEST(ResourceEntryConversionTest, - ConvertFileResourceToResourceEntry_StarredEntry) { - google_apis::FileResource file_resource; - file_resource.mutable_labels()->set_starred(true); - - ResourceEntry entry; - std::string parent_resource_id; - ConvertFileResourceToResourceEntry(file_resource, &entry, - &parent_resource_id); - EXPECT_TRUE(entry.starred()); -} - -TEST(ResourceEntryConversionTest, - ConvertFileResourceToResourceEntry_SharedWithMeEntry) { - google_apis::FileResource file_resource; - file_resource.set_shared(true); - file_resource.set_shared_with_me_date(GetTestTime()); - - ResourceEntry entry; - std::string parent_resource_id; - ConvertFileResourceToResourceEntry(file_resource, &entry, - &parent_resource_id); - EXPECT_TRUE(entry.shared_with_me()); - EXPECT_TRUE(entry.shared()); -} - -TEST(ResourceEntryConversionTest, ToPlatformFileInfo) { - ResourceEntry entry; - entry.mutable_file_info()->set_size(12345); - entry.mutable_file_info()->set_is_directory(true); - entry.mutable_file_info()->set_is_symbolic_link(true); - entry.mutable_file_info()->set_creation_time(999); - entry.mutable_file_info()->set_last_modified(123456789); - entry.mutable_file_info()->set_last_accessed(987654321); - - base::File::Info file_info; - ConvertResourceEntryToFileInfo(entry, &file_info); - EXPECT_EQ(entry.file_info().size(), file_info.size); - EXPECT_EQ(entry.file_info().is_directory(), file_info.is_directory); - EXPECT_EQ(entry.file_info().is_symbolic_link(), file_info.is_symbolic_link); - EXPECT_EQ(base::Time::FromInternalValue(entry.file_info().creation_time()), - file_info.creation_time); - EXPECT_EQ(base::Time::FromInternalValue(entry.file_info().last_modified()), - file_info.last_modified); - EXPECT_EQ(base::Time::FromInternalValue(entry.file_info().last_accessed()), - file_info.last_accessed); -} - -TEST(ResourceEntryConversionTest, - ConvertFileResourceToResourceEntry_ImageMediaMetadata) { - google_apis::FileResource entry_all_fields; - google_apis::FileResource entry_zero_fields; - google_apis::FileResource entry_no_fields; - - entry_all_fields.mutable_image_media_metadata()->set_width(640); - entry_all_fields.mutable_image_media_metadata()->set_height(480); - entry_all_fields.mutable_image_media_metadata()->set_rotation(90); - - entry_zero_fields.mutable_image_media_metadata()->set_width(0); - entry_zero_fields.mutable_image_media_metadata()->set_height(0); - entry_zero_fields.mutable_image_media_metadata()->set_rotation(0); - - { - ResourceEntry entry; - std::string parent_resource_id; - ConvertFileResourceToResourceEntry(entry_all_fields, &entry, - &parent_resource_id); - EXPECT_EQ(640, entry.file_specific_info().image_width()); - EXPECT_EQ(480, entry.file_specific_info().image_height()); - EXPECT_EQ(90, entry.file_specific_info().image_rotation()); - } - { - ResourceEntry entry; - std::string parent_resource_id; - ConvertFileResourceToResourceEntry(entry_zero_fields, &entry, - &parent_resource_id); - EXPECT_TRUE(entry.file_specific_info().has_image_width()); - EXPECT_TRUE(entry.file_specific_info().has_image_height()); - EXPECT_TRUE(entry.file_specific_info().has_image_rotation()); - EXPECT_EQ(0, entry.file_specific_info().image_width()); - EXPECT_EQ(0, entry.file_specific_info().image_height()); - EXPECT_EQ(0, entry.file_specific_info().image_rotation()); - } - { - ResourceEntry entry; - std::string parent_resource_id; - ConvertFileResourceToResourceEntry(entry_no_fields, &entry, - &parent_resource_id); - EXPECT_FALSE(entry.file_specific_info().has_image_width()); - EXPECT_FALSE(entry.file_specific_info().has_image_height()); - EXPECT_FALSE(entry.file_specific_info().has_image_rotation()); - } -} - -TEST(ResourceEntryConversionTest, - ConvertTeamDriveChangeResourceToResourceEntry) { - google_apis::ChangeResource change_resource; - change_resource.set_type(google_apis::ChangeResource::TEAM_DRIVE); - change_resource.set_team_drive( - std::make_unique<google_apis::TeamDriveResource>()); - change_resource.set_team_drive_id("team_drive_id"); - change_resource.set_modification_date(GetTestTime()); - change_resource.set_deleted(false); - - google_apis::TeamDriveResource* team_drive_resource = - change_resource.mutable_team_drive(); - team_drive_resource->set_name("ABC Team Drive"); - team_drive_resource->set_id("team_drive_id"); - - google_apis::TeamDriveCapabilities team_drive_capabilities; - team_drive_capabilities.set_can_copy(true); - team_drive_capabilities.set_can_delete_team_drive(false); - team_drive_capabilities.set_can_rename_team_drive(true); - // Can_rename is ignored for team drives. - team_drive_capabilities.set_can_rename(false); - team_drive_capabilities.set_can_add_children(false); - team_drive_capabilities.set_can_share(true); - team_drive_resource->set_capabilities(team_drive_capabilities); - - ResourceEntry entry; - std::string parent_resource_id; - ConvertChangeResourceToResourceEntry(change_resource, &entry, - &parent_resource_id); - - EXPECT_EQ(change_resource.team_drive_id(), entry.resource_id()); - EXPECT_EQ(team_drive_resource->name(), entry.title()); - EXPECT_EQ(team_drive_resource->name(), entry.base_name()); - EXPECT_EQ(change_resource.modification_date().ToInternalValue(), - entry.modification_date()); - EXPECT_TRUE(entry.file_info().is_directory()); - EXPECT_EQ(util::kDriveTeamDrivesDirLocalId, entry.parent_local_id()); - EXPECT_EQ("", parent_resource_id); - EXPECT_FALSE(entry.deleted()); - - EXPECT_TRUE(entry.capabilities_info().can_copy()); - EXPECT_FALSE(entry.capabilities_info().can_delete()); - EXPECT_TRUE(entry.capabilities_info().can_rename()); - EXPECT_FALSE(entry.capabilities_info().can_add_children()); - EXPECT_TRUE(entry.capabilities_info().can_share()); -} - -TEST(ResourceEntryConversionTest, ConvertTeamDriveResourceToResourceEntry) { - google_apis::TeamDriveResource team_drive_resource; - team_drive_resource.set_name("ABC Team Drive"); - team_drive_resource.set_id("team_drive_id"); - - ResourceEntry entry; - ConvertTeamDriveResourceToResourceEntry(team_drive_resource, &entry); - - EXPECT_EQ(team_drive_resource.id(), entry.resource_id()); - EXPECT_EQ(team_drive_resource.name(), entry.title()); - EXPECT_EQ(team_drive_resource.name(), entry.base_name()); - EXPECT_TRUE(entry.file_info().is_directory()); - EXPECT_EQ(util::kDriveTeamDrivesDirLocalId, entry.parent_local_id()); -} - -TEST(ResourceEntryConversionTest, - ConvertTeamDriveRemovalChangeResourceToResourceEntry) { - google_apis::ChangeResource change_resource; - change_resource.set_type(google_apis::ChangeResource::TEAM_DRIVE); - change_resource.set_team_drive_id("team_drive_id"); - change_resource.set_modification_date(GetTestTime()); - change_resource.set_deleted(true); - // team_drive field is not filled for a deleted change resource. - - ResourceEntry entry; - std::string parent_resource_id; - ConvertChangeResourceToResourceEntry(change_resource, &entry, - &parent_resource_id); - - EXPECT_EQ(change_resource.team_drive_id(), entry.resource_id()); - EXPECT_EQ(change_resource.modification_date().ToInternalValue(), - entry.modification_date()); - EXPECT_TRUE(entry.file_info().is_directory()); - EXPECT_EQ(util::kDriveTeamDrivesDirLocalId, entry.parent_local_id()); - EXPECT_EQ("", parent_resource_id); - EXPECT_TRUE(entry.deleted()); -} - -} // namespace drive
diff --git a/components/drive/resource_metadata_storage_unittest.cc b/components/drive/resource_metadata_storage_unittest.cc index f304599f..c759a3b8 100644 --- a/components/drive/resource_metadata_storage_unittest.cc +++ b/components/drive/resource_metadata_storage_unittest.cc
@@ -16,10 +16,10 @@ #include "base/stl_util.h" #include "base/strings/string_split.h" #include "base/threading/thread_task_runner_handle.h" -#include "components/drive/chromeos/drive_test_util.h" #include "components/drive/drive.pb.h" #include "components/drive/file_system_core_util.h" #include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/leveldatabase/src/include/leveldb/db.h" #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" @@ -27,6 +27,23 @@ namespace drive { namespace internal { +namespace { + +// Helper to destroy objects which needs Destroy() to be called on destruction. +// Note: When using this helper, you should destruct objects before +// BrowserThread. +struct DestroyHelperForTests { + template <typename T> + void operator()(T* object) const { + if (object) { + object->Destroy(); + content::RunAllTasksUntilIdle(); // Finish destruction. + } + } +}; + +} // namespace + class ResourceMetadataStorageTest : public testing::Test { protected: ResourceMetadataStorageTest() = default; @@ -78,8 +95,7 @@ content::BrowserTaskEnvironment task_environment_; base::ScopedTempDir temp_dir_; - std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests> - storage_; + std::unique_ptr<ResourceMetadataStorage, DestroyHelperForTests> storage_; DISALLOW_COPY_AND_ASSIGN(ResourceMetadataStorageTest); };
diff --git a/components/drive/resource_metadata_unittest.cc b/components/drive/resource_metadata_unittest.cc deleted file mode 100644 index fdc2051..0000000 --- a/components/drive/resource_metadata_unittest.cc +++ /dev/null
@@ -1,724 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "components/drive/chromeos/resource_metadata.h" - -#include <stddef.h> -#include <stdint.h> - -#include <algorithm> -#include <memory> -#include <string> -#include <vector> - -#include "base/files/scoped_temp_dir.h" -#include "base/single_thread_task_runner.h" -#include "base/strings/stringprintf.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/drive/chromeos/drive_test_util.h" -#include "components/drive/chromeos/fake_free_disk_space_getter.h" -#include "components/drive/chromeos/file_cache.h" -#include "components/drive/drive.pb.h" -#include "components/drive/file_system_core_util.h" -#include "content/public/test/browser_task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace drive { -namespace internal { -namespace { - -// The start page token of the resource metadata used in ResourceMetadataTest. -constexpr char kTestStartPageToken[] = "a token"; - -// Returns the sorted base names from |entries|. -std::vector<std::string> GetSortedBaseNames( - const ResourceEntryVector& entries) { - std::vector<std::string> base_names; - for (size_t i = 0; i < entries.size(); ++i) - base_names.push_back(entries[i].base_name()); - std::sort(base_names.begin(), base_names.end()); - - return base_names; -} - -// Creates a ResourceEntry for a directory with explicitly set resource_id. -ResourceEntry CreateDirectoryEntryWithResourceId( - const std::string& title, - const std::string& resource_id, - const std::string& parent_local_id) { - ResourceEntry entry; - entry.set_title(title); - entry.set_resource_id(resource_id); - entry.set_parent_local_id(parent_local_id); - entry.mutable_file_info()->set_is_directory(true); - entry.mutable_directory_specific_info()->set_start_page_token( - kTestStartPageToken); - return entry; -} - -// Creates a ResourceEntry for a directory. -ResourceEntry CreateDirectoryEntry(const std::string& title, - const std::string& parent_local_id) { - return CreateDirectoryEntryWithResourceId( - title, "id:" + title, parent_local_id); -} - -// Creates a ResourceEntry for a file with explicitly set resource_id. -ResourceEntry CreateFileEntryWithResourceId( - const std::string& title, - const std::string& resource_id, - const std::string& parent_local_id) { - ResourceEntry entry; - entry.set_title(title); - entry.set_resource_id(resource_id); - entry.set_parent_local_id(parent_local_id); - entry.mutable_file_info()->set_is_directory(false); - entry.mutable_file_info()->set_size(1024); - entry.mutable_file_specific_info()->set_md5("md5:" + title); - return entry; -} - -// Creates a ResourceEntry for a file. -ResourceEntry CreateFileEntry(const std::string& title, - const std::string& parent_local_id) { - return CreateFileEntryWithResourceId(title, "id:" + title, parent_local_id); -} - -// Creates the following files/directories -// drive/root/dir1/ -// drive/root/dir2/ -// drive/root/dir1/dir3/ -// drive/root/dir1/file4 -// drive/root/dir1/file5 -// drive/root/dir2/file6 -// drive/root/dir2/file7 -// drive/root/dir2/file8 -// drive/root/dir1/dir3/file9 -// drive/root/dir1/dir3/file10 -void SetUpEntries(ResourceMetadata* resource_metadata) { - std::string local_id; - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->GetIdByPath( - util::GetDriveMyDriveRootPath(), &local_id)); - const std::string root_local_id = local_id; - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry( - CreateDirectoryEntry("dir1", root_local_id), &local_id)); - const std::string local_id_dir1 = local_id; - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry( - CreateDirectoryEntry("dir2", root_local_id), &local_id)); - const std::string local_id_dir2 = local_id; - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry( - CreateDirectoryEntry("dir3", local_id_dir1), &local_id)); - const std::string local_id_dir3 = local_id; - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry( - CreateFileEntry("file4", local_id_dir1), &local_id)); - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry( - CreateFileEntry("file5", local_id_dir1), &local_id)); - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry( - CreateFileEntry("file6", local_id_dir2), &local_id)); - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry( - CreateFileEntry("file7", local_id_dir2), &local_id)); - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry( - CreateFileEntry("file8", local_id_dir2), &local_id)); - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry( - CreateFileEntry("file9", local_id_dir3), &local_id)); - ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry( - CreateFileEntry("file10", local_id_dir3), &local_id)); - - ASSERT_EQ(FILE_ERROR_OK, - resource_metadata->SetStartPageToken(kTestStartPageToken)); -} - -} // namespace - -// Tests for methods running on the blocking task runner. -class ResourceMetadataTest : public testing::Test { - protected: - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - - metadata_storage_.reset(new ResourceMetadataStorage( - temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); - ASSERT_TRUE(metadata_storage_->Initialize()); - - fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>(); - cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(), - base::ThreadTaskRunnerHandle::Get().get(), - fake_free_disk_space_getter_.get())); - ASSERT_TRUE(cache_->Initialize()); - - resource_metadata_.reset(new ResourceMetadata( - metadata_storage_.get(), cache_.get(), - base::ThreadTaskRunnerHandle::Get())); - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize()); - - SetUpEntries(resource_metadata_.get()); - } - - base::ScopedTempDir temp_dir_; - content::BrowserTaskEnvironment task_environment_; - std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests> - metadata_storage_; - std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_; - std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_; - std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> - resource_metadata_; -}; - -TEST_F(ResourceMetadataTest, StartPageToken) { - constexpr char kStartPageToken[] = "1234567"; - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->SetStartPageToken(kStartPageToken)); - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->GetStartPageToken(&start_page_token)); - EXPECT_EQ(kStartPageToken, start_page_token); -} - -TEST_F(ResourceMetadataTest, GetResourceEntryByPath) { - // Confirm that an existing file is found. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry)); - EXPECT_EQ("file4", entry.base_name()); - - // Confirm that a non existing file is not found. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/non_existing"), &entry)); - - // Confirm that the root is found. - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive"), &entry)); - - // Confirm that a non existing file is not found at the root level. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("non_existing"), &entry)); - - // Confirm that an entry is not found with a wrong root. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("non_existing/root"), &entry)); -} - -TEST_F(ResourceMetadataTest, ReadDirectoryByPath) { - // Confirm that an existing directory is found. - ResourceEntryVector entries; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->ReadDirectoryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &entries)); - ASSERT_EQ(3U, entries.size()); - // The order is not guaranteed so we should sort the base names. - std::vector<std::string> base_names = GetSortedBaseNames(entries); - EXPECT_EQ("dir3", base_names[0]); - EXPECT_EQ("file4", base_names[1]); - EXPECT_EQ("file5", base_names[2]); - - // Confirm that a non existing directory is not found. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->ReadDirectoryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/non_existing"), &entries)); - - // Confirm that reading a file results in FILE_ERROR_NOT_A_DIRECTORY. - EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, resource_metadata_->ReadDirectoryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entries)); -} - -TEST_F(ResourceMetadataTest, RefreshEntry) { - base::FilePath drive_file_path; - ResourceEntry entry; - - // Get file9. - std::string file_id; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), &file_id)); - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->GetResourceEntryById(file_id, &entry)); - EXPECT_EQ("file9", entry.base_name()); - EXPECT_TRUE(!entry.file_info().is_directory()); - EXPECT_EQ("md5:file9", entry.file_specific_info().md5()); - - // Rename it. - ResourceEntry file_entry(entry); - file_entry.set_title("file100"); - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->RefreshEntry(file_entry)); - - base::FilePath path; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(file_id, &path)); - EXPECT_EQ("drive/root/dir1/dir3/file100", path.AsUTF8Unsafe()); - entry.Clear(); - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->GetResourceEntryById(file_id, &entry)); - EXPECT_EQ("file100", entry.base_name()); - EXPECT_TRUE(!entry.file_info().is_directory()); - EXPECT_EQ("md5:file9", entry.file_specific_info().md5()); - - // Update the file md5. - const std::string updated_md5("md5:updated"); - file_entry = entry; - file_entry.mutable_file_specific_info()->set_md5(updated_md5); - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->RefreshEntry(file_entry)); - - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(file_id, &path)); - EXPECT_EQ("drive/root/dir1/dir3/file100", path.AsUTF8Unsafe()); - entry.Clear(); - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->GetResourceEntryById(file_id, &entry)); - EXPECT_EQ("file100", entry.base_name()); - EXPECT_TRUE(!entry.file_info().is_directory()); - EXPECT_EQ(updated_md5, entry.file_specific_info().md5()); - - // Make sure we get the same thing from GetResourceEntryByPath. - entry.Clear(); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file100"), &entry)); - EXPECT_EQ("file100", entry.base_name()); - ASSERT_TRUE(!entry.file_info().is_directory()); - EXPECT_EQ(updated_md5, entry.file_specific_info().md5()); - - // Get dir2. - entry.Clear(); - std::string dir_id; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &dir_id)); - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->GetResourceEntryById(dir_id, &entry)); - EXPECT_EQ("dir2", entry.base_name()); - ASSERT_TRUE(entry.file_info().is_directory()); - - // Get dir3's ID. - std::string dir3_id; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &dir3_id)); - - // Change the name to dir100 and change the parent to drive/dir1/dir3. - ResourceEntry dir_entry(entry); - dir_entry.set_title("dir100"); - dir_entry.set_parent_local_id(dir3_id); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(dir_entry)); - - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(dir_id, &path)); - EXPECT_EQ("drive/root/dir1/dir3/dir100", path.AsUTF8Unsafe()); - entry.Clear(); - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->GetResourceEntryById(dir_id, &entry)); - EXPECT_EQ("dir100", entry.base_name()); - EXPECT_TRUE(entry.file_info().is_directory()); - EXPECT_EQ("id:dir2", entry.resource_id()); - - // Make sure the children have moved over. Test file6. - entry.Clear(); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/dir100/file6"), - &entry)); - EXPECT_EQ("file6", entry.base_name()); - - // Make sure dir2 no longer exists. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &entry)); - - // Make sure that directory cannot move under a file. - dir_entry.set_parent_local_id(file_id); - EXPECT_EQ(FILE_ERROR_NOT_A_DIRECTORY, - resource_metadata_->RefreshEntry(dir_entry)); - - // Cannot refresh root. - dir_entry.Clear(); - dir_entry.set_local_id(util::kDriveGrandRootLocalId); - dir_entry.set_title("new-root-name"); - dir_entry.set_parent_local_id(dir3_id); - EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, - resource_metadata_->RefreshEntry(dir_entry)); -} - -TEST_F(ResourceMetadataTest, RefreshEntry_ResourceIDCheck) { - // Get an entry with a non-empty resource ID. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &entry)); - EXPECT_FALSE(entry.resource_id().empty()); - - // Add a new entry with an empty resource ID. - ResourceEntry new_entry; - new_entry.set_parent_local_id(entry.local_id()); - new_entry.set_title("new entry"); - std::string local_id; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(new_entry, &local_id)); - - // Try to refresh the new entry with a used resource ID. - new_entry.set_local_id(local_id); - new_entry.set_resource_id(entry.resource_id()); - EXPECT_EQ(FILE_ERROR_INVALID_OPERATION, - resource_metadata_->RefreshEntry(new_entry)); -} - -TEST_F(ResourceMetadataTest, RefreshEntry_DoNotOverwriteCacheState) { - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry)); - - // Try to set MD5 with RefreshEntry. - entry.mutable_file_specific_info()->mutable_cache_state()->set_md5("md5"); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(entry)); - - // Cache state is unchanged. - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().md5().empty()); - - // Pin the file. - EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(entry.local_id())); - - // Try to clear the cache state with RefreshEntry. - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry)); - entry.mutable_file_specific_info()->clear_cache_state(); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RefreshEntry(entry)); - - // Cache state is not cleared. - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &entry)); - EXPECT_TRUE(entry.file_specific_info().cache_state().is_pinned()); -} - -TEST_F(ResourceMetadataTest, GetSubDirectoriesRecursively) { - std::set<base::FilePath> sub_directories; - - // file9: not a directory, so no children. - std::string local_id; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), &local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively( - local_id, &sub_directories)); - EXPECT_TRUE(sub_directories.empty()); - - // dir2: no child directories. - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir2"), &local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively( - local_id, &sub_directories)); - EXPECT_TRUE(sub_directories.empty()); - const std::string dir2_id = local_id; - - // dir1: dir3 is the only child - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively( - local_id, &sub_directories)); - EXPECT_EQ(1u, sub_directories.size()); - EXPECT_EQ(1u, sub_directories.count( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"))); - sub_directories.clear(); - - // Add a few more directories to make sure deeper nesting works. - // dir2/dir100 - // dir2/dir101 - // dir2/dir101/dir102 - // dir2/dir101/dir103 - // dir2/dir101/dir104 - // dir2/dir101/dir104/dir105 - // dir2/dir101/dir104/dir105/dir106 - // dir2/dir101/dir104/dir105/dir106/dir107 - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntry("dir100", dir2_id), &local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntry("dir101", dir2_id), &local_id)); - const std::string dir101_id = local_id; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntry("dir102", dir101_id), &local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntry("dir103", dir101_id), &local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntry("dir104", dir101_id), &local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntry("dir105", local_id), &local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntry("dir106", local_id), &local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntry("dir107", local_id), &local_id)); - - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetSubDirectoriesRecursively( - dir2_id, &sub_directories)); - EXPECT_EQ(8u, sub_directories.size()); - EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe( - "drive/root/dir2/dir101"))); - EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe( - "drive/root/dir2/dir101/dir104"))); - EXPECT_EQ(1u, sub_directories.count(base::FilePath::FromUTF8Unsafe( - "drive/root/dir2/dir101/dir104/dir105/dir106/dir107"))); -} - -TEST_F(ResourceMetadataTest, AddEntry) { - // Add a file to dir3. - std::string local_id; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &local_id)); - ResourceEntry file_entry = CreateFileEntry("file100", local_id); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(file_entry, &local_id)); - base::FilePath path; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(local_id, &path)); - EXPECT_EQ("drive/root/dir1/dir3/file100", path.AsUTF8Unsafe()); - - // Add a directory. - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1"), &local_id)); - ResourceEntry dir_entry = CreateDirectoryEntry("dir101", local_id); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(dir_entry, &local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetFilePath(local_id, &path)); - EXPECT_EQ("drive/root/dir1/dir101", path.AsUTF8Unsafe()); - - // Add to an invalid parent. - ResourceEntry file_entry3 = CreateFileEntry("file103", "id:invalid"); - EXPECT_EQ(FILE_ERROR_NOT_FOUND, - resource_metadata_->AddEntry(file_entry3, &local_id)); - - // Add an existing file. - EXPECT_EQ(FILE_ERROR_EXISTS, - resource_metadata_->AddEntry(file_entry, &local_id)); -} - -TEST_F(ResourceMetadataTest, RemoveEntry) { - // Make sure file9 is found. - std::string file9_local_id; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3/file9"), - &file9_local_id)); - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - file9_local_id, &entry)); - EXPECT_EQ("file9", entry.base_name()); - - // Remove file9. - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(file9_local_id)); - - // file9 should no longer exist. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById( - file9_local_id, &entry)); - - // Look for dir3. - std::string dir3_local_id; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/dir3"), &dir3_local_id)); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - dir3_local_id, &entry)); - EXPECT_EQ("dir3", entry.base_name()); - - // Remove dir3. - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->RemoveEntry(dir3_local_id)); - - // dir3 should no longer exist. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById( - dir3_local_id, &entry)); - - // Remove unknown local_id using RemoveEntry. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->RemoveEntry("foo")); - - // Try removing root. This should fail. - EXPECT_EQ(FILE_ERROR_ACCESS_DENIED, resource_metadata_->RemoveEntry( - util::kDriveGrandRootLocalId)); -} - -TEST_F(ResourceMetadataTest, GetResourceEntryById_RootDirectory) { - // Look up the root directory by its ID. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - util::kDriveGrandRootLocalId, &entry)); - EXPECT_EQ("drive", entry.base_name()); -} - -TEST_F(ResourceMetadataTest, GetResourceEntryById) { - // Get file4 by path. - std::string local_id; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root/dir1/file4"), &local_id)); - - // Confirm that an existing file is found. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - local_id, &entry)); - EXPECT_EQ("file4", entry.base_name()); - - // Confirm that a non existing file is not found. - EXPECT_EQ(FILE_ERROR_NOT_FOUND, resource_metadata_->GetResourceEntryById( - "non_existing", &entry)); -} - -TEST_F(ResourceMetadataTest, Iterate) { - std::unique_ptr<ResourceMetadata::Iterator> it = - resource_metadata_->GetIterator(); - ASSERT_TRUE(it); - - int file_count = 0, directory_count = 0; - for (; !it->IsAtEnd(); it->Advance()) { - if (!it->GetValue().file_info().is_directory()) - ++file_count; - else - ++directory_count; - } - - EXPECT_EQ(7, file_count); - EXPECT_EQ(9, directory_count); -} - -TEST_F(ResourceMetadataTest, DuplicatedNames) { - std::string root_local_id; - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root"), &root_local_id)); - - ResourceEntry entry; - - // When multiple entries with the same title are added in a single directory, - // their base_names are de-duped. - // - drive/root/foo - // - drive/root/foo (1) - std::string dir_id_0; - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntryWithResourceId( - "foo", "foo0", root_local_id), &dir_id_0)); - std::string dir_id_1; - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntryWithResourceId( - "foo", "foo1", root_local_id), &dir_id_1)); - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - dir_id_0, &entry)); - EXPECT_EQ("foo", entry.base_name()); - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - dir_id_1, &entry)); - EXPECT_EQ("foo (1)", entry.base_name()); - - // - drive/root/foo/bar.txt - // - drive/root/foo/bar (1).txt - // - drive/root/foo/bar (2).txt - // ... - // - drive/root/foo/bar (99).txt - std::vector<std::string> file_ids(100); - for (size_t i = 0; i < file_ids.size(); ++i) { - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateFileEntryWithResourceId( - "bar.txt", base::StringPrintf("bar%d", static_cast<int>(i)), - dir_id_0), &file_ids[i])); - } - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - file_ids[0], &entry)); - EXPECT_EQ("bar.txt", entry.base_name()); - for (size_t i = 1; i < file_ids.size(); ++i) { - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - file_ids[i], &entry)) << i; - EXPECT_EQ(base::StringPrintf("bar (%d).txt", static_cast<int>(i)), - entry.base_name()); - } - - // Same name but different parent. No renaming. - // - drive/root/foo (1)/bar.txt - std::string file_id_3; - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateFileEntryWithResourceId( - "bar.txt", "bar_different_parent", dir_id_1), &file_id_3)); - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - file_id_3, &entry)); - EXPECT_EQ("bar.txt", entry.base_name()); - - // Checks that the entries can be looked up by the de-duped paths. - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/foo/bar (2).txt"), &entry)); - EXPECT_EQ("bar2", entry.resource_id()); - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive/root/foo (1)/bar.txt"), &entry)); - EXPECT_EQ("bar_different_parent", entry.resource_id()); -} - -TEST_F(ResourceMetadataTest, EncodedNames) { - std::string root_local_id; - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - base::FilePath::FromUTF8Unsafe("drive/root"), &root_local_id)); - - ResourceEntry entry; - - std::string dir_id; - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateDirectoryEntry("\\(^o^)/", root_local_id), &dir_id)); - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - dir_id, &entry)); - EXPECT_EQ("\\(^o^)_", entry.base_name()); - - std::string file_id; - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - CreateFileEntryWithResourceId("Slash /.txt", "myfile", dir_id), - &file_id)); - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryById( - file_id, &entry)); - EXPECT_EQ("Slash _.txt", entry.base_name()); - - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe( - "drive/root/\\(^o^)_/Slash _.txt"), - &entry)); - EXPECT_EQ("myfile", entry.resource_id()); -} - -TEST_F(ResourceMetadataTest, Reset) { - // The grand root has "root" which is not empty. - std::vector<ResourceEntry> entries; - ASSERT_EQ(FILE_ERROR_OK, - resource_metadata_->ReadDirectoryByPath( - base::FilePath::FromUTF8Unsafe("drive/root"), &entries)); - ASSERT_FALSE(entries.empty()); - - // Reset. - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->Reset()); - - // change stamp should be reset. - std::string start_page_token; - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->GetStartPageToken(&start_page_token)); - EXPECT_TRUE(start_page_token.empty()); - - // root should continue to exist. - ResourceEntry entry; - ASSERT_EQ(FILE_ERROR_OK, - resource_metadata_->GetResourceEntryByPath( - base::FilePath::FromUTF8Unsafe("drive"), &entry)); - EXPECT_EQ("drive", entry.base_name()); - ASSERT_TRUE(entry.file_info().is_directory()); - EXPECT_EQ(util::kDriveGrandRootLocalId, entry.local_id()); - - // There are "other", "trash" and "root", "team_drives" and "Computers" - // under "drive". - ASSERT_EQ(FILE_ERROR_OK, - resource_metadata_->ReadDirectoryByPath( - base::FilePath::FromUTF8Unsafe("drive"), &entries)); - EXPECT_EQ(5U, entries.size()); - - // The "other" directory should be empty. - ASSERT_EQ(FILE_ERROR_OK, - resource_metadata_->ReadDirectoryByPath( - base::FilePath::FromUTF8Unsafe("drive/other"), &entries)); - EXPECT_TRUE(entries.empty()); - - // The "trash" directory should be empty. - ASSERT_EQ(FILE_ERROR_OK, - resource_metadata_->ReadDirectoryByPath( - base::FilePath::FromUTF8Unsafe("drive/trash"), &entries)); - EXPECT_TRUE(entries.empty()); - - ASSERT_EQ(FILE_ERROR_OK, - resource_metadata_->ReadDirectoryByPath( - base::FilePath::FromUTF8Unsafe("drive/team_drives"), &entries)); - EXPECT_TRUE(entries.empty()); - - ASSERT_EQ(FILE_ERROR_OK, - resource_metadata_->ReadDirectoryByPath( - base::FilePath::FromUTF8Unsafe("drive/Computers"), &entries)); - EXPECT_TRUE(entries.empty()); -} - -} // namespace internal -} // namespace drive
diff --git a/components/drive/search_metadata_unittest.cc b/components/drive/search_metadata_unittest.cc index fa9e7f5b..bd4eb40 100644 --- a/components/drive/search_metadata_unittest.cc +++ b/components/drive/search_metadata_unittest.cc
@@ -10,21 +10,8 @@ #include <memory> #include <vector> -#include "base/bind.h" -#include "base/files/file_util.h" -#include "base/files/scoped_temp_dir.h" #include "base/i18n/string_search.h" -#include "base/run_loop.h" -#include "base/single_thread_task_runner.h" -#include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" -#include "base/threading/thread_task_runner_handle.h" -#include "components/drive/chromeos/drive_test_util.h" -#include "components/drive/chromeos/fake_free_disk_space_getter.h" -#include "components/drive/chromeos/file_cache.h" -#include "components/drive/drive_api_util.h" -#include "components/drive/file_system_core_util.h" -#include "content/public/test/browser_task_environment.h" #include "testing/gtest/include/gtest/gtest.h" namespace drive { @@ -32,8 +19,6 @@ namespace { -const int kDefaultAtMostNumMatches = 10; - // A simple wrapper for testing FindAndHighlightWrapper(). It just converts the // query text parameter to FixedPatternStringSearchIgnoringCaseAndAccents. bool FindAndHighlightWrapper( @@ -51,503 +36,6 @@ } // namespace -class SearchMetadataTest : public testing::Test { - protected: - void SetUp() override { - ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>(); - - metadata_storage_.reset(new ResourceMetadataStorage( - temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get())); - ASSERT_TRUE(metadata_storage_->Initialize()); - - cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(), - base::ThreadTaskRunnerHandle::Get().get(), - fake_free_disk_space_getter_.get())); - ASSERT_TRUE(cache_->Initialize()); - - resource_metadata_.reset( - new ResourceMetadata(metadata_storage_.get(), - cache_.get(), - base::ThreadTaskRunnerHandle::Get().get())); - ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize()); - - AddEntriesToMetadata(); - } - - void AddEntriesToMetadata() { - base::FilePath temp_file; - EXPECT_TRUE( - base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file)); - const std::string temp_file_md5 = "md5"; - - ResourceEntry entry; - std::string local_id; - - // drive/root - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->GetIdByPath( - util::GetDriveMyDriveRootPath(), &local_id)); - const std::string root_local_id = local_id; - - // drive/root/Directory-1 - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->AddEntry( - GetDirectoryEntry("Directory-1", "dir1", 1, 1, root_local_id), - &local_id)); - const std::string dir1_local_id = local_id; - - // drive/root/Directory-1/SubDirectory File 1.txt - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - GetFileEntry("SubDirectory File 1.txt", - "file1a", 2, 99, dir1_local_id), - &local_id)); - EXPECT_EQ(FILE_ERROR_OK, cache_->Store( - local_id, temp_file_md5, temp_file, FileCache::FILE_OPERATION_COPY)); - - // drive/root/Directory-1/Shared To The Account Owner.txt - entry = GetFileEntry("Shared To The Account Owner.txt", "file1b", 3, 3, - dir1_local_id); - entry.set_shared_with_me(true); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(entry, &local_id)); - - // drive/root/Directory 2 excludeDir-test - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->AddEntry( - GetDirectoryEntry("Directory 2 excludeDir-test", "dir2", 4, 4, - root_local_id), - &local_id)); - - // drive/root/Slash \xE2\x88\x95 in directory - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->AddEntry( - GetDirectoryEntry("Slash \xE2\x88\x95 in directory", "dir3", - 5, 5, root_local_id), - &local_id)); - const std::string dir3_local_id = local_id; - - // drive/root/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - GetFileEntry("Slash SubDir File.txt", "file3a", - 6, 6, dir3_local_id), - &local_id)); - - // drive/root/File 2.txt - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->AddEntry( - GetFileEntry("File 2.txt", "file2", 7, 7, root_local_id), - &local_id)); - EXPECT_EQ(FILE_ERROR_OK, cache_->Store( - local_id, temp_file_md5, temp_file, FileCache::FILE_OPERATION_COPY)); - - // drive/root/Document 1 excludeDir-test - entry = - GetFileEntry("Document 1 excludeDir-test", "doc1", 8, 8, root_local_id); - entry.mutable_file_specific_info()->set_is_hosted_document(true); - entry.mutable_file_specific_info()->set_document_extension(".gdoc"); - entry.mutable_file_specific_info()->set_content_mime_type( - drive::util::kGoogleDocumentMimeType); - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry(entry, &local_id)); - - // drive/team_drives - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->GetIdByPath( - util::GetDriveTeamDrivesRootPath(), &local_id)); - const std::string team_drive_root_local_id = local_id; - - // drive/team_drives/TD-1 - EXPECT_EQ(FILE_ERROR_OK, resource_metadata_->AddEntry( - GetDirectoryEntry("TD-1", "team_drive1", 1, 1, - team_drive_root_local_id), - &local_id)); - const std::string team_drive_dir1_local_id = local_id; - - // drive/team_drives/TD-1/TD File 1.txt - EXPECT_EQ(FILE_ERROR_OK, - resource_metadata_->AddEntry( - GetFileEntry("TD File 1.txt", "team_drive1_file1a", 2, 99, - team_drive_dir1_local_id), - &local_id)); - } - - ResourceEntry GetFileEntry(const std::string& name, - const std::string& resource_id, - int64_t last_accessed, - int64_t last_modified, - const std::string& parent_local_id) { - ResourceEntry entry; - entry.set_title(name); - entry.set_resource_id(resource_id); - entry.set_parent_local_id(parent_local_id); - entry.mutable_file_info()->set_last_accessed(last_accessed); - entry.mutable_file_info()->set_last_modified(last_modified); - return entry; - } - - ResourceEntry GetDirectoryEntry(const std::string& name, - const std::string& resource_id, - int64_t last_accessed, - int64_t last_modified, - const std::string& parent_local_id) { - ResourceEntry entry; - entry.set_title(name); - entry.set_resource_id(resource_id); - entry.set_parent_local_id(parent_local_id); - entry.mutable_file_info()->set_last_accessed(last_accessed); - entry.mutable_file_info()->set_last_modified(last_modified); - entry.mutable_file_info()->set_is_directory(true); - return entry; - } - - content::BrowserTaskEnvironment task_environment_; - base::ScopedTempDir temp_dir_; - std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_; - std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests> - metadata_storage_; - std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> - resource_metadata_; - std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_; -}; - -TEST_F(SearchMetadataTest, SearchMetadata_ZeroMatches) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), - "NonExistent", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(0U, result->size()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_RegularFile) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), - "SubDirectory File 1.txt", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(1U, result->size()); - EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt", - result->at(0).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_TeamDrive_RegularFile) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), - "TD File 1.txt", base::BindRepeating(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(1U, result->size()); - EXPECT_EQ("drive/team_drives/TD-1/TD File 1.txt", - result->at(0).path.AsUTF8Unsafe()); -} - -// This test checks if |FindAndHighlightWrapper| does case-insensitive search. -// Tricker test cases for |FindAndHighlightWrapper| can be found below. -TEST_F(SearchMetadataTest, SearchMetadata_CaseInsensitiveSearch) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - // The query is all in lower case. - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), - "subdirectory file 1.txt", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(1U, result->size()); - EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt", - result->at(0).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_RegularFiles) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "SubDir", - base::Bind(&MatchesType, SEARCH_METADATA_ALL), kDefaultAtMostNumMatches, - MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(2U, result->size()); - - // All base names should contain "File". The results should be sorted by the - // last accessed time in descending order. - EXPECT_EQ("drive/root/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt", - result->at(0).path.AsUTF8Unsafe()); - EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt", - result->at(1).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_AtMostOneFile_LastAccessed) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - // There are two files matching "SubDir" but only one file should be - // returned. Results are ordered by last accessed time. - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "SubDir", - base::Bind(&MatchesType, SEARCH_METADATA_ALL), - 1, // at_most_num_matches - MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(1U, result->size()); - EXPECT_EQ("drive/root/Slash \xE2\x88\x95 in directory/Slash SubDir File.txt", - result->at(0).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_AtMostOneFile_LastModified) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - // There are two files matching "SubDir" but only one file should be - // returned. Results are ordered by last modified time. - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "SubDir", - base::Bind(&MatchesType, SEARCH_METADATA_ALL), - 1, // at_most_num_matches - MetadataSearchOrder::LAST_MODIFIED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(1U, result->size()); - EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt", - result->at(0).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_Directory) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), - "Directory-1", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(1U, result->size()); - EXPECT_EQ("drive/root/Directory-1", result->at(0).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_TeamDrive_Directory) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "TD-1", - base::BindRepeating(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(1U, result->size()); - EXPECT_EQ("drive/team_drives/TD-1", result->at(0).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_HostedDocument) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "Document", - base::Bind(&MatchesType, SEARCH_METADATA_ALL), kDefaultAtMostNumMatches, - MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(1U, result->size()); - - EXPECT_EQ("drive/root/Document 1 excludeDir-test.gdoc", - result->at(0).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_ExcludeHostedDocument) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "Document", - base::Bind(&MatchesType, SEARCH_METADATA_EXCLUDE_HOSTED_DOCUMENTS), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(0U, result->size()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_SharedWithMe) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "", - base::Bind(&MatchesType, SEARCH_METADATA_SHARED_WITH_ME), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(1U, result->size()); - EXPECT_EQ("drive/root/Directory-1/Shared To The Account Owner.txt", - result->at(0).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_FileAndDirectory) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), - "excludeDir-test", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(2U, result->size()); - - EXPECT_EQ("drive/root/Document 1 excludeDir-test.gdoc", - result->at(0).path.AsUTF8Unsafe()); - EXPECT_EQ("drive/root/Directory 2 excludeDir-test", - result->at(1).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_ExcludeDirectory) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), - "excludeDir-test", - base::Bind(&MatchesType, SEARCH_METADATA_EXCLUDE_DIRECTORIES), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(1U, result->size()); - - EXPECT_EQ("drive/root/Document 1 excludeDir-test.gdoc", - result->at(0).path.AsUTF8Unsafe()); -} - -// "drive", "drive/root", "drive/other" should be excluded. -TEST_F(SearchMetadataTest, SearchMetadata_ExcludeSpecialDirectories) { - const char* const kQueries[] = { "drive", "root", "other" }; - for (size_t i = 0; i < base::size(kQueries); ++i) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - const std::string query = kQueries[i]; - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), query, - base::Bind(&MatchesType, SEARCH_METADATA_ALL), kDefaultAtMostNumMatches, - MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_TRUE(result->empty()) << ": " << query << " should not match"; - } -} - -TEST_F(SearchMetadataTest, SearchMetadata_Offline) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), "", - base::Bind(&MatchesType, SEARCH_METADATA_OFFLINE), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_EQ(3U, result->size()); - - // This is not included in the cache but is a hosted document. - EXPECT_EQ("drive/root/Document 1 excludeDir-test.gdoc", - result->at(0).path.AsUTF8Unsafe()); - - EXPECT_EQ("drive/root/File 2.txt", - result->at(1).path.AsUTF8Unsafe()); - EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt", - result->at(2).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, SearchMetadata_MultipleKeywords) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), - "Directory 1", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(2U, result->size()); - - EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt", - result->at(0).path.AsUTF8Unsafe()); - EXPECT_EQ("drive/root/Directory-1", result->at(1).path.AsUTF8Unsafe()); -} - -TEST_F(SearchMetadataTest, - SearchMetadata_KeywordsSeparatedWithIdeographicSpace) { - FileError error = FILE_ERROR_FAILED; - std::unique_ptr<MetadataSearchResultVector> result; - - // \xE3\x80\x80 is ideographic space. - SearchMetadata( - base::ThreadTaskRunnerHandle::Get(), resource_metadata_.get(), - R"(Directory 1)", base::Bind(&MatchesType, SEARCH_METADATA_ALL), - kDefaultAtMostNumMatches, MetadataSearchOrder::LAST_ACCESSED, - google_apis::test_util::CreateCopyResultCallback(&error, &result)); - - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - ASSERT_TRUE(result); - ASSERT_EQ(2U, result->size()); - - EXPECT_EQ("drive/root/Directory-1/SubDirectory File 1.txt", - result->at(0).path.AsUTF8Unsafe()); - EXPECT_EQ("drive/root/Directory-1", result->at(1).path.AsUTF8Unsafe()); -} - TEST(SearchMetadataSimpleTest, FindAndHighlight_ZeroMatches) { std::string highlighted_text; EXPECT_FALSE(FindAndHighlightWrapper("text", "query", &highlighted_text));
diff --git a/components/media_message_center/media_notification_view.cc b/components/media_message_center/media_notification_view.cc index 22d1524..c9a0261 100644 --- a/components/media_message_center/media_notification_view.cc +++ b/components/media_message_center/media_notification_view.cc
@@ -322,11 +322,23 @@ accessible_name_ = GetAccessibleNameFromMetadata(metadata); - if (!metadata.title.empty()) + // The title label should only be a11y-focusable when there is text to be + // read. + if (metadata.title.empty()) { + title_label_->SetFocusBehavior(FocusBehavior::NEVER); + } else { + title_label_->SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); RecordMetadataHistogram(Metadata::kTitle); + } - if (!metadata.artist.empty()) + // The artist label should only be a11y-focusable when there is text to be + // read. + if (metadata.artist.empty()) { + artist_label_->SetFocusBehavior(FocusBehavior::NEVER); + } else { + artist_label_->SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); RecordMetadataHistogram(Metadata::kArtist); + } if (!metadata.album.empty()) RecordMetadataHistogram(Metadata::kAlbum);
diff --git a/components/paint_preview/renderer/DEPS b/components/paint_preview/renderer/DEPS index 53de874..497159a7 100644 --- a/components/paint_preview/renderer/DEPS +++ b/components/paint_preview/renderer/DEPS
@@ -3,4 +3,5 @@ "+content/public/renderer", "+content/public/test", "+third_party/blink/public", + "+ui/native_theme/native_theme_features.h", ]
diff --git a/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc b/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc index c62e7aa..327d1389 100644 --- a/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc +++ b/components/paint_preview/renderer/paint_preview_recorder_browsertest.cc
@@ -7,11 +7,17 @@ #include "base/files/file.h" #include "base/files/file_path.h" #include "base/files/scoped_temp_dir.h" +#include "base/test/scoped_feature_list.h" +#include "base/threading/thread_restrictions.h" +#include "components/paint_preview/common/file_stream.h" #include "components/paint_preview/common/mojom/paint_preview_recorder.mojom.h" #include "content/public/renderer/render_frame.h" #include "content/public/renderer/render_view.h" #include "content/public/test/render_view_test.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/web/web_local_frame.h" +#include "third_party/skia/include/core/SkPicture.h" +#include "ui/native_theme/native_theme_features.h" namespace paint_preview { @@ -38,6 +44,12 @@ void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + + // TODO(crbug/1022398): This is required to bypass a seemingly unrelated + // DCHECK for |use_overlay_scrollbars_| in NativeThemeAura on ChromeOS when + // painting scrollbars when first calling LoadHTML(). + feature_list_.InitAndDisableFeature(features::kOverlayScrollbar); + RenderViewTest::SetUp(); } @@ -49,14 +61,155 @@ private: base::ScopedTempDir temp_dir_; + base::test::ScopedFeatureList feature_list_; }; -TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureMainFrame) { +TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureMainFrameAndClipping) { + LoadHTML( + "<body>" + " <div style='width: 600px; height: 80vh; " + " background-color: #ff0000'> </div>" + " <a style='display:inline-block' href='http://www.google.com'>Foo</a>" + " <div style='width: 100px; height: 600px; " + " background-color: #000000'> </div>" + " <div style='overflow: hidden; width: 100px; height: 100px;" + " background: orange;'>" + " <div style='width: 500px; height: 500px;" + " background: yellow;'></div>" + " </div>" + "</body>"); + base::FilePath skp_path = MakeTestFilePath("test.skp"); + + mojom::PaintPreviewCaptureParamsPtr params = + mojom::PaintPreviewCaptureParams::New(); + auto token = base::UnguessableToken::Create(); + params->guid = token; + params->clip_rect = gfx::Rect(); + params->is_main_frame = true; + base::File skp_file(skp_path, + base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); + params->file = std::move(skp_file); + + auto out_response = mojom::PaintPreviewCaptureResponse::New(); + content::RenderFrame* frame = GetFrame(); + int routing_id = frame->GetRoutingID(); + PaintPreviewRecorderImpl paint_preview_recorder(frame); + paint_preview_recorder.CapturePaintPreview( + std::move(params), + base::BindOnce(&OnCaptureFinished, mojom::PaintPreviewStatus::kOk, + base::Unretained(&out_response))); + + // Here id() is just the routing ID. + EXPECT_EQ(static_cast<int>(out_response->id), routing_id); + EXPECT_EQ(out_response->content_id_proxy_id_map.size(), 0U); + + EXPECT_EQ(out_response->links.size(), 1U); + EXPECT_EQ(out_response->links[0]->url, GURL("http://www.google.com/")); + // Relaxed checks on dimensions and no checks on positions. This is not + // intended to test the rendering behavior of the page only that a link + // was captured and has a bounding box. + EXPECT_GT(out_response->links[0]->rect.width(), 0); + EXPECT_GT(out_response->links[0]->rect.height(), 0); + + sk_sp<SkPicture> pic; + { + base::ScopedAllowBlockingForTesting scope; + FileRStream rstream(base::File( + skp_path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ)); + pic = SkPicture::MakeFromStream(&rstream, nullptr); + } + // The min page height is the sum of the three top level divs of 800. The min + // width is that of the widest div at 600. + EXPECT_GE(pic->cullRect().height(), 800); + EXPECT_GE(pic->cullRect().width(), 600); + SkBitmap bitmap; + ASSERT_TRUE(bitmap.tryAllocN32Pixels(pic->cullRect().width(), + pic->cullRect().height())); + SkCanvas canvas(bitmap); + canvas.drawPicture(pic); + // This should be inside the top right corner of the first top level div. + // Success means there was no horizontal clipping as this region is red, + // matching the div. + EXPECT_EQ(bitmap.getColor(600, 50), 0xFFFF0000U); + // This should be inside the bottom of the second top level div. Success means + // there was no vertical clipping as this region is black matching the div. If + // the yellow div within the orange div overflowed then this would be yellow + // and fail. + EXPECT_EQ(bitmap.getColor(50, pic->cullRect().height() - 150), 0xFF000000U); + // This should be for the white background in the bottom right. This checks + // that the background is not clipped. + EXPECT_EQ(bitmap.getColor(pic->cullRect().width() - 50, + pic->cullRect().height() - 50), + 0xFFFFFFFFU); +} + +TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureFragment) { + // Use position absolute position to check that the captured link dimensions + // match what is specified. LoadHTML( "<body style='min-height:1000px;'>" - " <div style='width: 100px; height: 100px; " - " background-color: #000000'> </div>" - " <p><a href='https://www.foo.com'>Foo</a></p>" + " <a style='position: absolute; left: -15px; top: 0px; width: 20px; " + " height: 30px;' href='#fragment'>Foo</a>" + " <h1 id='fragment'>I'm a fragment</h1>" + "</body>"); + base::FilePath skp_path = MakeTestFilePath("test.skp"); + + mojom::PaintPreviewCaptureParamsPtr params = + mojom::PaintPreviewCaptureParams::New(); + auto token = base::UnguessableToken::Create(); + params->guid = token; + params->clip_rect = gfx::Rect(); + params->is_main_frame = true; + base::File skp_file(skp_path, + base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); + params->file = std::move(skp_file); + + auto out_response = mojom::PaintPreviewCaptureResponse::New(); + content::RenderFrame* frame = GetFrame(); + int routing_id = frame->GetRoutingID(); + PaintPreviewRecorderImpl paint_preview_recorder(frame); + paint_preview_recorder.CapturePaintPreview( + std::move(params), + base::BindOnce(&OnCaptureFinished, mojom::PaintPreviewStatus::kOk, + &out_response)); + // Here id() is just the routing ID. + EXPECT_EQ(static_cast<int>(out_response->id), routing_id); + EXPECT_EQ(out_response->content_id_proxy_id_map.size(), 0U); + + EXPECT_EQ(out_response->links.size(), 1U); + EXPECT_EQ(out_response->links[0]->url, GURL("fragment")); + EXPECT_EQ(out_response->links[0]->rect.x(), -15); + EXPECT_EQ(out_response->links[0]->rect.y(), 0); + EXPECT_EQ(out_response->links[0]->rect.width(), 20); + EXPECT_EQ(out_response->links[0]->rect.height(), 30); +} + +TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureInvalidFile) { + LoadHTML("<body></body>"); + + mojom::PaintPreviewCaptureParamsPtr params = + mojom::PaintPreviewCaptureParams::New(); + auto token = base::UnguessableToken::Create(); + params->guid = token; + params->clip_rect = gfx::Rect(); + params->is_main_frame = true; + base::File skp_file; // Invalid file. + params->file = std::move(skp_file); + + content::RenderFrame* frame = GetFrame(); + PaintPreviewRecorderImpl paint_preview_recorder(frame); + paint_preview_recorder.CapturePaintPreview( + std::move(params), + base::BindOnce(&OnCaptureFinished, + mojom::PaintPreviewStatus::kCaptureFailed, nullptr)); +} + +TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureMainFrameAndLocalFrame) { + LoadHTML( + "<body style='min-height:1000px;'>" + " <iframe style='width: 500px, height: 500px'" + " srcdoc=\"<div style='width: 100px; height: 100px;" + " background-color: #000000'> </div>\"></iframe>" "</body>"); base::FilePath skp_path = MakeTestFilePath("test.skp"); @@ -81,29 +234,40 @@ // Here id() is just the routing ID. EXPECT_EQ(static_cast<int>(out_response->id), routing_id); EXPECT_EQ(out_response->content_id_proxy_id_map.size(), 0U); - - // NOTE: should be non-zero once the Blink implementation is hooked up. - EXPECT_EQ(out_response->links.size(), 0U); } -TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureInvalidFile) { - LoadHTML("<body></body>"); +TEST_F(PaintPreviewRecorderRenderViewTest, TestCaptureLocalFrame) { + LoadHTML( + "<body style='min-height:1000px;'>" + " <iframe style='width: 500px, height: 500px'" + " srcdoc=\"<div style='width: 100px; height: 100px;" + " background-color: #000000'> </div>\"></iframe>" + "</body>"); + base::FilePath skp_path = MakeTestFilePath("test.skp"); mojom::PaintPreviewCaptureParamsPtr params = mojom::PaintPreviewCaptureParams::New(); auto token = base::UnguessableToken::Create(); params->guid = token; params->clip_rect = gfx::Rect(); - params->is_main_frame = true; - base::File skp_file; // Invalid file. + params->is_main_frame = false; + base::File skp_file(skp_path, + base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); params->file = std::move(skp_file); - content::RenderFrame* frame = GetFrame(); - PaintPreviewRecorderImpl paint_preview_recorder(frame); + auto out_response = mojom::PaintPreviewCaptureResponse::New(); + auto* child_frame = content::RenderFrame::FromWebFrame( + GetFrame()->GetWebFrame()->FirstChild()->ToWebLocalFrame()); + ASSERT_TRUE(child_frame); + int routing_id = child_frame->GetRoutingID(); + PaintPreviewRecorderImpl paint_preview_recorder(child_frame); paint_preview_recorder.CapturePaintPreview( std::move(params), - base::BindOnce(&OnCaptureFinished, - mojom::PaintPreviewStatus::kCaptureFailed, nullptr)); + base::BindOnce(&OnCaptureFinished, mojom::PaintPreviewStatus::kOk, + base::Unretained(&out_response))); + // Here id() is just the routing ID. + EXPECT_EQ(static_cast<int>(out_response->id), routing_id); + EXPECT_EQ(out_response->content_id_proxy_id_map.size(), 0U); } } // namespace paint_preview
diff --git a/components/paint_preview/renderer/paint_preview_recorder_impl.cc b/components/paint_preview/renderer/paint_preview_recorder_impl.cc index 3b236b3..d807c8ec 100644 --- a/components/paint_preview/renderer/paint_preview_recorder_impl.cc +++ b/components/paint_preview/renderer/paint_preview_recorder_impl.cc
@@ -101,15 +101,18 @@ } cc::PaintRecorder recorder; - recorder.beginRecording(bounds.width(), bounds.height()); PaintPreviewTracker tracker(params->guid, routing_id_, is_main_frame_); - // TODO(crbug/1008885): Create a method on |canvas| to inject |tracker_| to - // propagate to graphics contexts and inner canvases - // TODO(crbug/1001109): Create a method on |frame| to execute the capture - // within Blink. + cc::PaintCanvas* canvas = + recorder.beginRecording(bounds.width(), bounds.height()); + canvas->SetPaintPreviewTracker(&tracker); + bool success = frame->CapturePaintPreview(bounds, canvas); // Restore to before out-of-lifecycle paint phase. frame->DispatchAfterPrintEvent(); + if (!success) { + *status = mojom::PaintPreviewStatus::kCaptureFailed; + return; + } // TODO(crbug/1011896): Determine if making this async would be beneficial. *status = FinishRecording(recorder.finishRecordingAsPicture(), bounds,
diff --git a/components/password_manager/core/browser/password_form_manager.cc b/components/password_manager/core/browser/password_form_manager.cc index af5f94e..7f0747f 100644 --- a/components/password_manager/core/browser/password_form_manager.cc +++ b/components/password_manager/core/browser/password_form_manager.cc
@@ -302,7 +302,7 @@ newly_blacklisted_ = false; } - if (password_overridden_ && + if (IsPasswordUpdate() && pending_credentials_.type == PasswordForm::Type::kGenerated && !HasGeneratedPassword()) { metrics_util::LogPasswordGenerationSubmissionEvent( @@ -310,7 +310,7 @@ pending_credentials_.type = PasswordForm::Type::kManual; } - if (is_new_login_) { + if (IsNewLogin()) { metrics_util::LogNewlySavedPasswordIsGenerated( pending_credentials_.type == PasswordForm::Type::kGenerated); SanitizePossibleUsernames(&pending_credentials_); @@ -319,6 +319,9 @@ GetBestMatches(), &pending_credentials_); SavePendingToStore(false /*update*/); } else { + // It sounds wrong that we still update even if the + // |pending_credentials_state_| is NONE. We should double check if this + // actually necessary. Currently some tests depend on this behavior. ProcessUpdate(); SavePendingToStore(true /*update*/); } @@ -346,7 +349,7 @@ pending_credentials_.skip_zero_click = skip_zero_click; pending_credentials_.preferred = true; pending_credentials_.date_last_used = base::Time::Now(); - is_new_login_ = false; + pending_credentials_state_ = PendingCredentialsState::UPDATE; ProcessUpdate(); SavePendingToStore(true /*update*/); @@ -465,7 +468,8 @@ } bool PasswordFormManager::IsNewLogin() const { - return is_new_login_; + return pending_credentials_state_ == PendingCredentialsState::NEW_LOGIN || + pending_credentials_state_ == PendingCredentialsState::AUTOMATIC_SAVE; } FormFetcher* PasswordFormManager::GetFormFetcher() { @@ -518,7 +522,7 @@ } bool PasswordFormManager::IsPasswordUpdate() const { - return password_overridden_; + return pending_credentials_state_ == PendingCredentialsState::UPDATE; } base::WeakPtr<PasswordManagerDriver> PasswordFormManager::GetDriver() const { @@ -608,8 +612,7 @@ result->parsed_submitted_form_.reset( new PasswordForm(*parsed_submitted_form_)); } - result->is_new_login_ = is_new_login_; - result->password_overridden_ = password_overridden_; + result->pending_credentials_state_ = pending_credentials_state_; result->is_submitted_ = is_submitted_; return result; @@ -907,8 +910,8 @@ // This function might be called multiple times so set variables that are // changed in this function to initial states. - is_new_login_ = true; - SetPasswordOverridden(false); + pending_credentials_state_ = PendingCredentialsState::NONE; + votes_uploader_.set_password_overridden(false); ValueElementPair password_to_save(PasswordToSave(*parsed_submitted_form_)); // Look for the actually submitted credentials in the list of previously saved @@ -916,16 +919,18 @@ const PasswordForm* saved_form = password_manager_util::GetMatchForUpdating( *parsed_submitted_form_, GetBestMatches()); if (saved_form) { - // A similar credential exists in the store already. + // A similar credential exists in the store already. We should either update + // the password or create an new record if it's a PSL-matched credentials. pending_credentials_ = *saved_form; - SetPasswordOverridden(pending_credentials_.password_value != - password_to_save.first); - // If the autofilled credentials were a PSL match, store a copy with the - // current origin and signon realm. This ensures that on the next visit, a - // precise match is found. - is_new_login_ = pending_credentials_.is_public_suffix_match; - - if (is_new_login_) { + if (pending_credentials_.password_value != password_to_save.first) { + // Password should be updated. + pending_credentials_state_ = PendingCredentialsState::UPDATE; + votes_uploader_.set_password_overridden(true); + } else if (pending_credentials_.is_public_suffix_match) { + // If the autofilled credentials were a PSL match, store a copy with the + // current origin and signon realm. This ensures that on the next visit, a + // precise match is found. + pending_credentials_state_ = PendingCredentialsState::AUTOMATIC_SAVE; // Update credential to reflect that it has been used for submission. // If this isn't updated, then password generation uploads are off for // sites where PSL matching is required to fill the login form, as two @@ -938,7 +943,7 @@ pending_credentials_.action = parsed_submitted_form_->action; } } else { - is_new_login_ = true; + pending_credentials_state_ = PendingCredentialsState::NEW_LOGIN; // No stored credentials can be matched to the submitted form. Offer to // save new credentials. CreatePendingCredentialsForNewCredentials(password_to_save.second); @@ -956,6 +961,8 @@ kCorrectedUsernameInForm); } } + // Whether it's a new credential or an update to existing one, we set the + // following fields. pending_credentials_.password_value = HasGeneratedPassword() ? generation_manager_->generated_password() : password_to_save.first; @@ -1133,7 +1140,7 @@ void PasswordFormManager::SavePendingToStore(bool update) { const PasswordForm* saved_form = password_manager_util::GetMatchForUpdating( *parsed_submitted_form_, GetBestMatches()); - if ((update || password_overridden_) && + if ((update || IsPasswordUpdate()) && !pending_credentials_.IsFederatedCredential()) { DCHECK(saved_form); }
diff --git a/components/password_manager/core/browser/password_form_manager.h b/components/password_manager/core/browser/password_form_manager.h index 1522780..5b194e6 100644 --- a/components/password_manager/core/browser/password_form_manager.h +++ b/components/password_manager/core/browser/password_form_manager.h
@@ -35,6 +35,8 @@ class PasswordManagerDriver; struct PossibleUsernameData; +enum class PendingCredentialsState { NONE, NEW_LOGIN, UPDATE, AUTOMATIC_SAVE }; + // This class helps with filling the observed form and with saving/updating the // stored information about it. class PasswordFormManager : public PasswordFormManagerForUI, @@ -246,11 +248,6 @@ void CreatePendingCredentialsForNewCredentials( const base::string16& password_element); - void SetPasswordOverridden(bool password_overridden) { - password_overridden_ = password_overridden; - votes_uploader_.set_password_overridden(password_overridden); - } - // Helper for Save in the case there is at least one match for the pending // credentials. This sends needed signals to the autofill server, and also // triggers some UMA reporting. @@ -329,19 +326,12 @@ // |submitted_form_| and |best_matches_|. autofill::PasswordForm pending_credentials_; - // Whether |pending_credentials_| stores a credential that should be added - // to the password store. False means it's a pure update to the existing ones. - // TODO(crbug/831123): this value only makes sense internally. Remove public - // dependencies on it. - bool is_new_login_ = true; + PendingCredentialsState pending_credentials_state_ = + PendingCredentialsState::NONE; // Handles the user flows related to the generation. std::unique_ptr<PasswordGenerationManager> generation_manager_; - // Whether a saved password was overridden. The flag is true when there is a - // credential in the store that will get a new password value. - bool password_overridden_ = false; - // If Chrome has already autofilled a few times, it is probable that autofill // is triggered by programmatic changes in the page. We set a maximum number // of times that Chrome will autofill to avoid being stuck in an infinite
diff --git a/components/performance_manager/BUILD.gn b/components/performance_manager/BUILD.gn index cb1d23a..0d8e13c1 100644 --- a/components/performance_manager/BUILD.gn +++ b/components/performance_manager/BUILD.gn
@@ -26,6 +26,8 @@ "graph/page_node.cc", "graph/page_node_impl.cc", "graph/page_node_impl.h", + "graph/policies/process_priority_policy.cc", + "graph/policies/process_priority_policy.h", "graph/process_node.cc", "graph/process_node_impl.cc", "graph/process_node_impl.h", @@ -95,6 +97,7 @@ "graph/node_attached_data_unittest.cc", "graph/node_base_unittest.cc", "graph/page_node_impl_unittest.cc", + "graph/policies/process_priority_policy_unittest.cc", "graph/process_node_impl_unittest.cc", "graph/properties_unittest.cc", "graph/system_node_impl_unittest.cc",
diff --git a/components/performance_manager/graph/graph_impl.cc b/components/performance_manager/graph/graph_impl.cc index 70e6525..c689418a 100644 --- a/components/performance_manager/graph/graph_impl.cc +++ b/components/performance_manager/graph/graph_impl.cc
@@ -211,6 +211,10 @@ return GetAllNodesOfType<WorkerNodeImpl, const WorkerNode*>(); } +bool GraphImpl::IsEmpty() const { + return nodes_.empty(); +} + ukm::UkmRecorder* GraphImpl::GetUkmRecorder() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); return ukm_recorder();
diff --git a/components/performance_manager/graph/graph_impl.h b/components/performance_manager/graph/graph_impl.h index f2b7c70..87bee66 100644 --- a/components/performance_manager/graph/graph_impl.h +++ b/components/performance_manager/graph/graph_impl.h
@@ -70,6 +70,7 @@ std::vector<const FrameNode*> GetAllFrameNodes() const override; std::vector<const PageNode*> GetAllPageNodes() const override; std::vector<const WorkerNode*> GetAllWorkerNodes() const override; + bool IsEmpty() const override; ukm::UkmRecorder* GetUkmRecorder() const override; uintptr_t GetImplType() const override; const void* GetImpl() const override;
diff --git a/components/performance_manager/graph/graph_impl_unittest.cc b/components/performance_manager/graph/graph_impl_unittest.cc index 23d5849f..049f26c 100644 --- a/components/performance_manager/graph/graph_impl_unittest.cc +++ b/components/performance_manager/graph/graph_impl_unittest.cc
@@ -25,7 +25,9 @@ } TEST_F(GraphImplTest, FindOrCreateSystemNode) { + EXPECT_TRUE(graph()->IsEmpty()); SystemNodeImpl* system_node = graph()->FindOrCreateSystemNodeImpl(); + EXPECT_FALSE(graph()->IsEmpty()); // A second request should return the same instance. EXPECT_EQ(system_node, graph()->FindOrCreateSystemNodeImpl());
diff --git a/components/performance_manager/graph/policies/process_priority_policy.cc b/components/performance_manager/graph/policies/process_priority_policy.cc new file mode 100644 index 0000000..91c79a7 --- /dev/null +++ b/components/performance_manager/graph/policies/process_priority_policy.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/performance_manager/graph/policies/process_priority_policy.h" + +#include "base/bind.h" +#include "base/memory/ptr_util.h" +#include "base/task/post_task.h" +#include "components/performance_manager/public/render_process_host_proxy.h" +#include "content/public/browser/browser_task_traits.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" + +namespace performance_manager { +namespace policies { + +namespace { + +#if DCHECK_IS_ON() +size_t g_instance_count = 0; +#endif + +// Used as a testing seam. If this is set then SetProcessPriorityOnUiThread will +// invoke the provided callback immediately after calling SetPriorityOverride on +// the RenderProcessHost. +ProcessPriorityPolicy::SetPriorityOnUiThreadCallback* g_callback = nullptr; + +// Maps a TaskPriority to a "is_foreground" bool. Process priorities are +// currently simply "background" or "foreground", despite there actually being +// more expressive power on most platforms. +bool IsForegroundTaskPriority(base::TaskPriority priority) { + switch (priority) { + case base::TaskPriority::BEST_EFFORT: + return false; + + case base::TaskPriority::USER_VISIBLE: + case base::TaskPriority::USER_BLOCKING: + break; + } + + return true; +} + +// Helper function for setting the RenderProcessHost priority. +void SetProcessPriorityOnUIThread(RenderProcessHostProxy rph_proxy, + bool foreground) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + // Deliver the policy message if the RPH still exists by the time the + // message arrives. Note that this will involve yet another bounce over to + // the process launcher thread. + auto* rph = rph_proxy.Get(); + if (rph) + rph->SetPriorityOverride(foreground); + + // Invoke the testing seam callback if one was provided. + if (g_callback && !g_callback->is_null()) + g_callback->Run(rph_proxy, foreground); +} + +// Dispatches a process priority change to the RenderProcessHost associated with +// a given ProcessNode. The task is posted to the UI thread, where the RPH +// lives. +void DispatchSetProcessPriority(const ProcessNode* process_node, + bool foreground) { + // TODO(chrisha): This will actually result in a further thread-hop over to + // the process launcher thread. If we migrate to process priority logic being + // driven 100% from the PM, we could post directly to the launcher thread + // via the base::Process directly. + const auto& proxy = process_node->GetRenderProcessHostProxy(); + base::PostTask( + FROM_HERE, {content::BrowserThread::UI}, + base::BindOnce(&SetProcessPriorityOnUIThread, proxy, foreground)); +} + +} // namespace + +ProcessPriorityPolicy::ProcessPriorityPolicy() { +#if DCHECK_IS_ON() + DCHECK_EQ(0u, g_instance_count); + ++g_instance_count; +#endif +} + +ProcessPriorityPolicy::~ProcessPriorityPolicy() { +#if DCHECK_IS_ON() + DCHECK_EQ(1u, g_instance_count); + --g_instance_count; +#endif +} + +// static +void ProcessPriorityPolicy::SetCallbackForTesting( + SetPriorityOnUiThreadCallback callback) { + ClearCallbackForTesting(); + g_callback = new SetPriorityOnUiThreadCallback(callback); +} + +void ProcessPriorityPolicy::ClearCallbackForTesting() { + if (!g_callback) + return; + delete g_callback; + g_callback = nullptr; +} + +void ProcessPriorityPolicy::OnPassedToGraph(Graph* graph) { + DCHECK(graph->IsEmpty()); + graph->AddProcessNodeObserver(this); +} + +void ProcessPriorityPolicy::OnTakenFromGraph(Graph* graph) { + graph->RemoveProcessNodeObserver(this); +} + +void ProcessPriorityPolicy::OnProcessNodeAdded( + const ProcessNode* process_node) { + // Set the initial process priority. + // TODO(chrisha): Get provisional nodes working so we can make an informed + // choice in the graph (processes launching ads-to-be, or extensions, or + // frames for backgrounded tabs, etc, can be launched with background + // priority). + // TODO(chrisha): Make process creation take a detour through the graph in + // order to get the initial priority parameter that is set here. Currently + // this is effectively a nop. + DispatchSetProcessPriority( + process_node, IsForegroundTaskPriority(process_node->GetPriority())); +} + +void ProcessPriorityPolicy::OnPriorityChanged( + const ProcessNode* process_node, + base::TaskPriority previous_value) { + bool previous_foreground = IsForegroundTaskPriority(previous_value); + bool current_foreground = + IsForegroundTaskPriority(process_node->GetPriority()); + + // Only dispatch a message if the resulting process priority has changed. + if (previous_foreground != current_foreground) + DispatchSetProcessPriority(process_node, current_foreground); +} + +} // namespace policies +} // namespace performance_manager
diff --git a/components/performance_manager/graph/policies/process_priority_policy.h b/components/performance_manager/graph/policies/process_priority_policy.h new file mode 100644 index 0000000..06796db --- /dev/null +++ b/components/performance_manager/graph/policies/process_priority_policy.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 COMPONENTS_PERFORMANCE_MANAGER_GRAPH_POLICIES_PROCESS_PRIORITY_POLICY_H_ +#define COMPONENTS_PERFORMANCE_MANAGER_GRAPH_POLICIES_PROCESS_PRIORITY_POLICY_H_ + +#include "base/callback.h" +#include "components/performance_manager/public/graph/graph.h" +#include "components/performance_manager/public/graph/process_node.h" +#include "components/performance_manager/public/render_process_host_proxy.h" + +namespace performance_manager { +namespace policies { + +// Policy that observes priority changes on ProcessNodes, and applies these +// to the actual processes via RenderProcessHost::SetPriorityOverride. There +// is no need for more than one of these to be instantiated at a time (enforced +// by a DCHECK). This policy expects to be attached to an empty graph (also +// enforced by a DCHECK). +class ProcessPriorityPolicy : public GraphOwned, + public ProcessNode::ObserverDefaultImpl { + public: + using SetPriorityOnUiThreadCallback = + base::RepeatingCallback<void(RenderProcessHostProxy rph_proxy, + bool foreground)>; + + ProcessPriorityPolicy(); + ProcessPriorityPolicy(const ProcessPriorityPolicy&) = delete; + ProcessPriorityPolicy(ProcessPriorityPolicy&&) = delete; + ProcessPriorityPolicy& operator=(const ProcessPriorityPolicy&) = delete; + ProcessPriorityPolicy& operator=(ProcessPriorityPolicy&&) = delete; + ~ProcessPriorityPolicy() override; + + // Testing seams. This allows testing this class without requiring a full + // browser test. + static void SetCallbackForTesting(SetPriorityOnUiThreadCallback callback); + static void ClearCallbackForTesting(); + + private: + // GraphOwned implementation: + void OnPassedToGraph(Graph* graph) override; + void OnTakenFromGraph(Graph* graph) override; + + // ProcessNodeObserver implementation: + void OnProcessNodeAdded(const ProcessNode* process_node) override; + void OnPriorityChanged(const ProcessNode* process_node, + base::TaskPriority previous_value) override; +}; + +} // namespace policies +} // namespace performance_manager + +#endif // COMPONENTS_PERFORMANCE_MANAGER_GRAPH_POLICIES_PROCESS_PRIORITY_POLICY_H_
diff --git a/components/performance_manager/graph/policies/process_priority_policy_unittest.cc b/components/performance_manager/graph/policies/process_priority_policy_unittest.cc new file mode 100644 index 0000000..58e28c7 --- /dev/null +++ b/components/performance_manager/graph/policies/process_priority_policy_unittest.cc
@@ -0,0 +1,141 @@ +// 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/performance_manager/graph/policies/process_priority_policy.h" + +#include "base/test/bind_test_util.h" +#include "base/threading/sequenced_task_runner_handle.h" +#include "components/performance_manager/graph/process_node_impl.h" +#include "components/performance_manager/performance_manager_test_harness.h" +#include "components/performance_manager/public/performance_manager.h" +#include "components/performance_manager/render_process_user_data.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/test/navigation_simulator.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace performance_manager { +namespace policies { + +namespace { + +// Returns a priority that will lead to an opposite process priority. +base::TaskPriority GetOppositePriority(base::TaskPriority priority) { + switch (priority) { + case base::TaskPriority::BEST_EFFORT: + return base::TaskPriority::USER_BLOCKING; + + case base::TaskPriority::USER_VISIBLE: + case base::TaskPriority::USER_BLOCKING: + break; + } + + return base::TaskPriority::BEST_EFFORT; +} + +void PostToggleProcessNodePriority(content::RenderProcessHost* rph) { + auto* rpud = RenderProcessUserData::GetForRenderProcessHost(rph); + auto* process_node = rpud->process_node(); + + PerformanceManager::CallOnGraph( + FROM_HERE, + base::BindLambdaForTesting([process_node](Graph* graph_unused) { + process_node->set_priority( + GetOppositePriority(process_node->priority())); + })); +} + +class ProcessPriorityPolicyTest : public PerformanceManagerTestHarness { + public: + ProcessPriorityPolicyTest() {} + ProcessPriorityPolicyTest(const ProcessPriorityPolicyTest&) = delete; + ProcessPriorityPolicyTest(ProcessPriorityPolicyTest&&) = delete; + ProcessPriorityPolicyTest& operator=(const ProcessPriorityPolicyTest&) = + delete; + ProcessPriorityPolicyTest& operator=(ProcessPriorityPolicyTest&&) = delete; + ~ProcessPriorityPolicyTest() override {} + + void SetUp() override { + PerformanceManagerTestHarness::SetUp(); + + // It's safe to pass unretained as we clear the callback before being + // torn down. + ProcessPriorityPolicy::SetCallbackForTesting( + base::Bind(&ProcessPriorityPolicyTest::OnSetPriorityWrapper, + base::Unretained(this))); + } + + void TearDown() override { + ProcessPriorityPolicy::ClearCallbackForTesting(); + + // Clean up the web contents, which should dispose of the page and frame + // nodes involved. + DeleteContents(); + + // The RenderProcessHosts seem to get leaked, or at least be still alive + // here, so explicitly detach from them in order to clean up the graph + // nodes. + RenderProcessUserData::DetachAndDestroyAll(); + + PerformanceManagerTestHarness::TearDown(); + } + + void RunUntilOnSetPriority() { + base::RunLoop run_loop; + quit_closure_ = run_loop.QuitClosure(); + run_loop.Run(); + quit_closure_.Reset(); + } + + // This is eventually invoked by the testing callback when the policy sets a + // process priority. + MOCK_METHOD2(OnSetPriority, void(content::RenderProcessHost*, bool)); + + private: + void OnSetPriorityWrapper(RenderProcessHostProxy rph_proxy, bool foreground) { + OnSetPriority(rph_proxy.Get(), foreground); + quit_closure_.Run(); + } + + base::RepeatingClosure quit_closure_; +}; + +} // namespace + +TEST_F(ProcessPriorityPolicyTest, GraphReflectedToRenderProcessHost) { + // Create an instance of the process priority policy. + PerformanceManager::CallOnGraph( + FROM_HERE, base::Bind([](Graph* graph) { + std::unique_ptr<ProcessPriorityPolicy> policy( + new ProcessPriorityPolicy()); + graph->PassToGraph(std::move(policy)); + })); + + // Set the active contents in the RenderViewHostTestHarness. + SetContents(CreateTestWebContents()); + auto* rvh = web_contents()->GetRenderViewHost(); + DCHECK(rvh); + auto* rph = rvh->GetProcess(); + DCHECK(rph); + + // Simulate a navigation so that graph nodes spring into existence. + content::NavigationSimulator::NavigateAndCommitFromBrowser( + web_contents(), GURL("https://www.foo.com/")); + + // Expect a background priority override to be set for process creation. + // NOTE: This is going to change once we have provisional frames and the like, + // and can calculate meaningful process startup priorities. + EXPECT_CALL(*this, OnSetPriority(rph, false)); + RunUntilOnSetPriority(); + + // Toggle the priority and expect it to change. + PostToggleProcessNodePriority(rph); + EXPECT_CALL(*this, OnSetPriority(rph, true)); + RunUntilOnSetPriority(); + + testing::Mock::VerifyAndClearExpectations(this); +} + +} // namespace policies +} // namespace performance_manager
diff --git a/components/performance_manager/public/graph/graph.h b/components/performance_manager/public/graph/graph.h index 37cd408..e69bdbc 100644 --- a/components/performance_manager/public/graph/graph.h +++ b/components/performance_manager/public/graph/graph.h
@@ -80,6 +80,9 @@ virtual std::vector<const PageNode*> GetAllPageNodes() const = 0; virtual std::vector<const WorkerNode*> GetAllWorkerNodes() const = 0; + // Returns true if the graph is currently empty. + virtual bool IsEmpty() const = 0; + // Returns the associated UKM recorder if it is defined. virtual ukm::UkmRecorder* GetUkmRecorder() const = 0;
diff --git a/components/policy/proto/chrome_device_policy.proto b/components/policy/proto/chrome_device_policy.proto index 11619c2..0d8a926f 100644 --- a/components/policy/proto/chrome_device_policy.proto +++ b/components/policy/proto/chrome_device_policy.proto
@@ -6,9 +6,13 @@ option optimize_for = LITE_RUNTIME; +import "policy_common_definitions.proto"; + package enterprise_management; -import "policy_common_definitions.proto"; +// Everything below this comment will be synchronized between client and server +// repos ( go/cros-proto-sync ). +// Please don't manually edit any lines below this comment. message DevicePolicyRefreshRateProto { // In milliseconds.
diff --git a/components/policy/proto/device_management_backend.proto b/components/policy/proto/device_management_backend.proto index e67f9c9..51c9939 100644 --- a/components/policy/proto/device_management_backend.proto +++ b/components/policy/proto/device_management_backend.proto
@@ -10,6 +10,7 @@ // Everything below this comment will be synchronized between client and server // repos ( go/cros-proto-sync ). +// Please don't manually edit any lines below this comment. // This enum needs to be shared between DeviceRegisterRequest and // LicenseAvailability protos. With java_api_version 1, this means that enum
diff --git a/components/policy/proto/policy_common_definitions.proto b/components/policy/proto/policy_common_definitions.proto index 274ae91..b5ffd71 100644 --- a/components/policy/proto/policy_common_definitions.proto +++ b/components/policy/proto/policy_common_definitions.proto
@@ -8,6 +8,10 @@ package enterprise_management; +// Everything below this comment will be synchronized between client and server +// repos ( go/cros-proto-sync ). +// Please don't manually edit any lines below this comment. + message StringList { repeated string entries = 1; } @@ -42,4 +46,4 @@ message StringListPolicyProto { optional PolicyOptions policy_options = 1; optional StringList value = 2; -} \ No newline at end of file +}
diff --git a/components/sessions/BUILD.gn b/components/sessions/BUILD.gn index ff1e1c08..6b21f91 100644 --- a/components/sessions/BUILD.gn +++ b/components/sessions/BUILD.gn
@@ -48,6 +48,8 @@ sources = [ "ios/ios_live_tab.h", "ios/ios_live_tab.mm", + "ios/ios_restore_live_tab.h", + "ios/ios_restore_live_tab.mm", "ios/ios_serialized_navigation_builder.h", "ios/ios_serialized_navigation_builder.mm", "ios/ios_serialized_navigation_driver.cc", @@ -62,6 +64,7 @@ deps = [ "//base", "//ios/web/common", + "//ios/web/public/session", ] } }
diff --git a/components/sessions/ios/ios_restore_live_tab.h b/components/sessions/ios/ios_restore_live_tab.h new file mode 100644 index 0000000..e68c2e6 --- /dev/null +++ b/components/sessions/ios/ios_restore_live_tab.h
@@ -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. + +#ifndef COMPONENTS_SESSIONS_IOS_IOS_RESTORE_LIVE_TAB_H_ +#define COMPONENTS_SESSIONS_IOS_IOS_RESTORE_LIVE_TAB_H_ + +#include "base/macros.h" +#include "base/supports_user_data.h" +#include "components/sessions/core/live_tab.h" + +@class CRWSessionStorage; + +namespace sessions { + +// An implementation of LiveTab that is backed by web::CRWSessionStorage for use +// when restoring tabs from a crashed session. +class SESSIONS_EXPORT RestoreIOSLiveTab : public LiveTab { + public: + explicit RestoreIOSLiveTab(CRWSessionStorage* session); + ~RestoreIOSLiveTab() override; + RestoreIOSLiveTab(const RestoreIOSLiveTab&) = delete; + RestoreIOSLiveTab& operator=(const RestoreIOSLiveTab&) = delete; + + // LiveTab: + bool IsInitialBlankNavigation() override; + int GetCurrentEntryIndex() override; + int GetPendingEntryIndex() override; + sessions::SerializedNavigationEntry GetEntryAtIndex(int index) override; + sessions::SerializedNavigationEntry GetPendingEntry() override; + int GetEntryCount() override; + const std::string& GetUserAgentOverride() override; + + private: + CRWSessionStorage* session_; + + // Needed to return an empty string in GetUserAgentOverride(). + const std::string user_agent_override_; +}; + +} // namespace sessions + +#endif // COMPONENTS_SESSIONS_IOS_IOS_RESTORE_LIVE_TAB_H_
diff --git a/components/sessions/ios/ios_restore_live_tab.mm b/components/sessions/ios/ios_restore_live_tab.mm new file mode 100644 index 0000000..f26fa555 --- /dev/null +++ b/components/sessions/ios/ios_restore_live_tab.mm
@@ -0,0 +1,51 @@ +// 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/sessions/ios/ios_restore_live_tab.h" + +#include "components/sessions/ios/ios_serialized_navigation_builder.h" +#include "ios/web/public/session/crw_navigation_item_storage.h" +#include "ios/web/public/session/crw_session_storage.h" + +namespace sessions { + +RestoreIOSLiveTab::RestoreIOSLiveTab(CRWSessionStorage* session) + : session_(session) {} + +RestoreIOSLiveTab::~RestoreIOSLiveTab() {} + +bool RestoreIOSLiveTab::IsInitialBlankNavigation() { + return false; +} + +int RestoreIOSLiveTab::GetCurrentEntryIndex() { + return session_.lastCommittedItemIndex; +} + +int RestoreIOSLiveTab::GetPendingEntryIndex() { + return -1; +} + +sessions::SerializedNavigationEntry RestoreIOSLiveTab::GetEntryAtIndex( + int index) { + NSArray* item_storages = session_.itemStorages; + CRWNavigationItemStorage* item = item_storages[index]; + return sessions::IOSSerializedNavigationBuilder::FromNavigationStorageItem( + index, item); +} + +sessions::SerializedNavigationEntry RestoreIOSLiveTab::GetPendingEntry() { + return sessions::SerializedNavigationEntry(); +} + +int RestoreIOSLiveTab::GetEntryCount() { + return session_.itemStorages.count; +} + +const std::string& RestoreIOSLiveTab::GetUserAgentOverride() { + // Dynamic user agent overrides are not supported on iOS. + return user_agent_override_; +} + +} // namespace sessions
diff --git a/components/sessions/ios/ios_serialized_navigation_builder.h b/components/sessions/ios/ios_serialized_navigation_builder.h index def0b1f1..7871753 100644 --- a/components/sessions/ios/ios_serialized_navigation_builder.h +++ b/components/sessions/ios/ios_serialized_navigation_builder.h
@@ -12,6 +12,8 @@ class NavigationItem; } +@class CRWNavigationItemStorage; + namespace sessions { class SerializedNavigationEntry; @@ -24,6 +26,12 @@ static SerializedNavigationEntry FromNavigationItem( int index, const web::NavigationItem& item); + // Construct a SerializedNavigationEntry for a particular index from the given + // CRWNavigationItemStorage. + static SerializedNavigationEntry FromNavigationStorageItem( + int index, + CRWNavigationItemStorage* item); + // Convert the given SerializedNavigationEntry into a NavigationItem. The // NavigationItem will have a transition type of // PAGE_TRANSITION_RELOAD and a new unique ID.
diff --git a/components/sessions/ios/ios_serialized_navigation_builder.mm b/components/sessions/ios/ios_serialized_navigation_builder.mm index 8224e75..096bf40 100644 --- a/components/sessions/ios/ios_serialized_navigation_builder.mm +++ b/components/sessions/ios/ios_serialized_navigation_builder.mm
@@ -8,6 +8,7 @@ #include "ios/web/public/favicon/favicon_status.h" #include "ios/web/public/navigation/navigation_item.h" #include "ios/web/public/navigation/referrer.h" +#include "ios/web/public/session/crw_navigation_item_storage.h" namespace sessions { @@ -30,6 +31,26 @@ return navigation; } +SerializedNavigationEntry +IOSSerializedNavigationBuilder::FromNavigationStorageItem( + int index, + CRWNavigationItemStorage* item) { + // Create a NavigationItem to reserve a UniqueID. + auto navigation_item = web::NavigationItem::Create(); + SerializedNavigationEntry navigation; + navigation.index_ = index; + navigation.unique_id_ = navigation_item->GetUniqueID(); + navigation.referrer_url_ = item.referrer.url; + navigation.referrer_policy_ = item.referrer.policy; + navigation.virtual_url_ = item.virtualURL; + navigation.title_ = item.title; + // Use reload transition type to avoid incorrect increase for typed count. + navigation.transition_type_ = ui::PAGE_TRANSITION_RELOAD; + navigation.timestamp_ = item.timestamp; + + return navigation; +} + // static std::unique_ptr<web::NavigationItem> IOSSerializedNavigationBuilder::ToNavigationItem(
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm index 17e96fd..d93f242 100644 --- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm +++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm
@@ -207,7 +207,7 @@ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); // Get the list of new account ids. - std::set<std::string> new_account_ids; + std::set<CoreAccountId> new_account_ids; for (const auto& new_account : provider_->GetAllAccounts()) { DCHECK(!new_account.gaia.empty()); DCHECK(!new_account.email.empty()); @@ -216,7 +216,7 @@ // the GAIA ID is available if any client of this token service starts // a fetch access token operation when it receives a // |OnRefreshTokenAvailable| notification. - std::string account_id = account_tracker_service_->SeedAccountInfo( + CoreAccountId account_id = account_tracker_service_->SeedAccountInfo( AccountInfoFromDeviceAccount(new_account)); new_account_ids.insert(account_id); }
diff --git a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm index 5374520..b0eeef2 100644 --- a/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm +++ b/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm
@@ -99,7 +99,7 @@ auth_error_changed_count_ = 0; } - std::string GetAccountId(const ProviderAccount& provider_account) { + CoreAccountId GetAccountId(const ProviderAccount& provider_account) { return account_tracker_.PickAccountIdForAccount(provider_account.gaia, provider_account.email); } @@ -139,7 +139,8 @@ EXPECT_EQ(0, tokens_loaded_count_); EXPECT_EQ(1, token_revoked_count_); EXPECT_EQ(0U, oauth2_delegate_->GetAccounts().size()); - EXPECT_FALSE(oauth2_delegate_->RefreshTokenIsAvailable("another_account")); + EXPECT_FALSE(oauth2_delegate_->RefreshTokenIsAvailable( + CoreAccountId("another_account"))); } TEST_F(ProfileOAuth2TokenServiceIOSDelegateTest, @@ -277,7 +278,7 @@ ResetObserverCounts(); GoogleServiceAuthError error(GoogleServiceAuthError::SERVICE_ERROR); oauth2_delegate_->UpdateAuthError(GetAccountId(account1), error); - EXPECT_EQ(error, oauth2_delegate_->GetAuthError("gaia_1")); + EXPECT_EQ(error, oauth2_delegate_->GetAuthError(GetAccountId(account1))); EXPECT_EQ(1, auth_error_changed_count_); oauth2_delegate_->RevokeAllCredentials(); @@ -292,15 +293,15 @@ oauth2_delegate_->ReloadCredentials(); base::RunLoop().RunUntilIdle(); EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), - oauth2_delegate_->GetAuthError("gaia_1")); + oauth2_delegate_->GetAuthError(GetAccountId(account1))); // Update the error. GoogleServiceAuthError error = GoogleServiceAuthError::FromInvalidGaiaCredentialsReason( GoogleServiceAuthError::InvalidGaiaCredentialsReason:: CREDENTIALS_REJECTED_BY_SERVER); - oauth2_delegate_->UpdateAuthError("gaia_1", error); - EXPECT_EQ(error, oauth2_delegate_->GetAuthError("gaia_1")); + oauth2_delegate_->UpdateAuthError(GetAccountId(account1), error); + EXPECT_EQ(error, oauth2_delegate_->GetAuthError(GetAccountId(account1))); // Unknown account has no error. EXPECT_EQ(GoogleServiceAuthError::AuthErrorNone(), - oauth2_delegate_->GetAuthError("gaia_2")); + oauth2_delegate_->GetAuthError(CoreAccountId("gaia_2"))); }
diff --git a/components/storage_monitor/image_capture_device.mm b/components/storage_monitor/image_capture_device.mm index 3b2b0207e..cfc9e1e 100644 --- a/components/storage_monitor/image_capture_device.mm +++ b/components/storage_monitor/image_capture_device.mm
@@ -263,4 +263,36 @@ NOTIMPLEMENTED(); } +// Mac 10.15 SDK methods, not yet implemented (https://crbug.com/849689) + +- (void)cameraDevice:(ICCameraDevice*)camera didRemoveItems:(NSArray*)items { + NOTIMPLEMENTED(); +} + +- (void)cameraDevice:(ICCameraDevice*)camera + didReceiveThumbnail:(CGImageRef)thumbnail + forItem:(ICCameraItem*)item + error:(NSError*)error { + NOTIMPLEMENTED(); +} + +- (void)cameraDevice:(ICCameraDevice*)camera + didReceiveMetadata:(NSDictionary*)metadata + forItem:(ICCameraItem*)item + error:(NSError*)error { + NOTIMPLEMENTED(); +} + +- (void)cameraDeviceDidEnableAccessRestriction:(ICDevice*)device { + NOTIMPLEMENTED(); +} + +- (void)cameraDeviceDidRemoveAccessRestriction:(ICDevice*)device { + NOTIMPLEMENTED(); +} + +- (void)device:(ICDevice*)device didCloseSessionWithError:(NSError*)error { + NOTIMPLEMENTED(); +} + @end // ImageCaptureDevice
diff --git a/components/sync/base/pref_names.cc b/components/sync/base/pref_names.cc index 6a90cbb50..291d4ce7 100644 --- a/components/sync/base/pref_names.cc +++ b/components/sync/base/pref_names.cc
@@ -28,6 +28,10 @@ const char kSyncKeepEverythingSynced[] = "sync.keep_everything_synced"; #if defined(OS_CHROMEOS) +// Boolean indicating that the user has enabled the Chrome OS system-setting +// sync feature. +const char kOsSyncFeatureEnabled[] = "sync.os_sync_feature_enabled"; + // Boolean specifying whether to automatically sync all Chrome OS specific data // types (including future ones). This includes types like printers, OS-only // settings, etc. If set, the individual type preferences can be ignored.
diff --git a/components/sync/base/pref_names.h b/components/sync/base/pref_names.h index ce39c2f..eae73ce 100644 --- a/components/sync/base/pref_names.h +++ b/components/sync/base/pref_names.h
@@ -18,6 +18,7 @@ extern const char kSyncKeepEverythingSynced[]; #if defined(OS_CHROMEOS) +extern const char kOsSyncFeatureEnabled[]; extern const char kSyncAllOsTypes[]; #endif
diff --git a/components/sync/base/sync_prefs.cc b/components/sync/base/sync_prefs.cc index 7a7af515..8c310b32 100644 --- a/components/sync/base/sync_prefs.cc +++ b/components/sync/base/sync_prefs.cc
@@ -282,6 +282,7 @@ RegisterTypeSelectedPref(registry, type); } #if defined(OS_CHROMEOS) + registry->RegisterBooleanPref(prefs::kOsSyncFeatureEnabled, false); registry->RegisterBooleanPref(prefs::kSyncAllOsTypes, true); for (UserSelectableOsType type : UserSelectableOsTypeSet::All()) { registry->RegisterBooleanPref(GetPrefNameForOsType(type), false); @@ -520,6 +521,16 @@ observer.OnPreferredDataTypesPrefChange(); } } + +bool SyncPrefs::GetOsSyncFeatureEnabled() const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + return pref_service_->GetBoolean(prefs::kOsSyncFeatureEnabled); +} + +void SyncPrefs::SetOsSyncFeatureEnabled(bool enabled) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + pref_service_->SetBoolean(prefs::kOsSyncFeatureEnabled, enabled); +} #endif // defined(OS_CHROMEOS) bool SyncPrefs::IsManaged() const {
diff --git a/components/sync/base/sync_prefs.h b/components/sync/base/sync_prefs.h index 74e8c13..273e4f3 100644 --- a/components/sync/base/sync_prefs.h +++ b/components/sync/base/sync_prefs.h
@@ -130,6 +130,8 @@ void SetSelectedOsTypes(bool sync_all_os_types, UserSelectableOsTypeSet registered_types, UserSelectableOsTypeSet selected_types); + bool GetOsSyncFeatureEnabled() const; + void SetOsSyncFeatureEnabled(bool enabled); #endif // Whether Sync is forced off by enterprise policy. Note that this only covers
diff --git a/components/sync/driver/sync_auth_manager.cc b/components/sync/driver/sync_auth_manager.cc index 060f597..3287a32e 100644 --- a/components/sync/driver/sync_auth_manager.cc +++ b/components/sync/driver/sync_auth_manager.cc
@@ -437,12 +437,14 @@ // Sign out of the old account (if any). if (!sync_account_.account_info.account_id.empty()) { sync_account_ = SyncAccountInfo(); + // Let the client (SyncService) know of the removed account *before* + // throwing away the access token, so it can do "unregister" tasks. + account_state_changed_callback_.Run(); // Also clear any pending request or auth errors we might have, since they // aren't meaningful anymore. partial_token_status_ = SyncTokenStatus(); ClearAccessTokenAndRequest(); SetLastAuthError(GoogleServiceAuthError::AuthErrorNone()); - account_state_changed_callback_.Run(); } // Sign in to the new account (if any).
diff --git a/components/sync/driver/sync_auth_manager_unittest.cc b/components/sync/driver/sync_auth_manager_unittest.cc index b971d59..df83ccbe 100644 --- a/components/sync/driver/sync_auth_manager_unittest.cc +++ b/components/sync/driver/sync_auth_manager_unittest.cc
@@ -136,6 +136,39 @@ EXPECT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id, second_account_id); } + +TEST_F(SyncAuthManagerTest, NotifiesOfSignoutBeforeAccessTokenIsGone) { + // Start out already signed in before the SyncAuthManager is created. + CoreAccountId account_id = + identity_env()->MakePrimaryAccountAvailable("test@email.com").account_id; + + base::MockCallback<AccountStateChangedCallback> account_state_changed; + base::MockCallback<CredentialsChangedCallback> credentials_changed; + auto auth_manager = + CreateAuthManager(account_state_changed.Get(), base::DoNothing()); + + auth_manager->RegisterForAuthNotifications(); + + ASSERT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id, + account_id); + + auth_manager->ConnectionOpened(); + + // Make sure an access token is available. + identity_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken( + "access_token", base::Time::Now() + base::TimeDelta::FromHours(1)); + ASSERT_EQ(auth_manager->GetCredentials().access_token, "access_token"); + + // Sign out of the account. + EXPECT_CALL(account_state_changed, Run()).WillOnce([&]() { + // At the time the callback gets run, the access token should still be here. + EXPECT_FALSE(auth_manager->GetCredentials().access_token.empty()); + }); + identity_env()->ClearPrimaryAccount(); + // After the signout is complete, the access token should be gone. + EXPECT_TRUE( + auth_manager->GetActiveAccountInfo().account_info.account_id.empty()); +} #endif // !defined(OS_CHROMEOS) // Unconsented primary accounts (aka secondary accounts) are only supported on
diff --git a/components/sync/driver/sync_user_settings.h b/components/sync/driver/sync_user_settings.h index f5c6d73..159dcba 100644 --- a/components/sync/driver/sync_user_settings.h +++ b/components/sync/driver/sync_user_settings.h
@@ -80,6 +80,11 @@ virtual void SetSelectedOsTypes(bool sync_all_os_types, UserSelectableOsTypeSet types) = 0; virtual UserSelectableOsTypeSet GetRegisteredSelectableOsTypes() const = 0; + + // Whether the OS sync feature is enabled. Implies the user has consented. + // Exists in this interface for easier mocking in tests. + virtual bool GetOsSyncFeatureEnabled() const = 0; + virtual void SetOsSyncFeatureEnabled(bool enabled) = 0; #endif // defined(OS_CHROMEOS) // Encryption state.
diff --git a/components/sync/driver/sync_user_settings_impl.cc b/components/sync/driver/sync_user_settings_impl.cc index 76426abb7..5c67c5b 100644 --- a/components/sync/driver/sync_user_settings_impl.cc +++ b/components/sync/driver/sync_user_settings_impl.cc
@@ -142,6 +142,14 @@ } return registered_types; } + +bool SyncUserSettingsImpl::GetOsSyncFeatureEnabled() const { + return prefs_->GetOsSyncFeatureEnabled(); +} + +void SyncUserSettingsImpl::SetOsSyncFeatureEnabled(bool enabled) { + prefs_->SetOsSyncFeatureEnabled(enabled); +} #endif // defined(OS_CHROMEOS) UserSelectableTypeSet SyncUserSettingsImpl::GetForcedTypes() const {
diff --git a/components/sync/driver/sync_user_settings_impl.h b/components/sync/driver/sync_user_settings_impl.h index 98f885a..d1fd467a6 100644 --- a/components/sync/driver/sync_user_settings_impl.h +++ b/components/sync/driver/sync_user_settings_impl.h
@@ -54,6 +54,9 @@ void SetSelectedOsTypes(bool sync_all_os_types, UserSelectableOsTypeSet types) override; UserSelectableOsTypeSet GetRegisteredSelectableOsTypes() const override; + + bool GetOsSyncFeatureEnabled() const override; + void SetOsSyncFeatureEnabled(bool enabled) override; #endif bool IsEncryptEverythingAllowed() const override;
diff --git a/components/sync/driver/sync_user_settings_mock.h b/components/sync/driver/sync_user_settings_mock.h index 2f002ce..c630d39 100644 --- a/components/sync/driver/sync_user_settings_mock.h +++ b/components/sync/driver/sync_user_settings_mock.h
@@ -38,6 +38,9 @@ MOCK_CONST_METHOD0(GetSelectedOsTypes, UserSelectableOsTypeSet()); MOCK_METHOD2(SetSelectedOsTypes, void(bool, UserSelectableOsTypeSet)); MOCK_CONST_METHOD0(GetRegisteredSelectableOsTypes, UserSelectableOsTypeSet()); + + MOCK_CONST_METHOD0(GetOsSyncFeatureEnabled, bool()); + MOCK_METHOD1(SetOsSyncFeatureEnabled, void(bool)); #endif MOCK_CONST_METHOD0(IsEncryptEverythingAllowed, bool());
diff --git a/components/sync/driver/test_sync_user_settings.cc b/components/sync/driver/test_sync_user_settings.cc index cc649939..b0fe7aa 100644 --- a/components/sync/driver/test_sync_user_settings.cc +++ b/components/sync/driver/test_sync_user_settings.cc
@@ -133,6 +133,14 @@ const { return UserSelectableOsTypeSet::All(); } + +bool TestSyncUserSettings::GetOsSyncFeatureEnabled() const { + return os_sync_feature_enabled_; +} + +void TestSyncUserSettings::SetOsSyncFeatureEnabled(bool enabled) { + os_sync_feature_enabled_ = enabled; +} #endif bool TestSyncUserSettings::IsEncryptEverythingAllowed() const {
diff --git a/components/sync/driver/test_sync_user_settings.h b/components/sync/driver/test_sync_user_settings.h index 2bb7ebf..6ad37d7f 100644 --- a/components/sync/driver/test_sync_user_settings.h +++ b/components/sync/driver/test_sync_user_settings.h
@@ -43,6 +43,9 @@ void SetSelectedOsTypes(bool sync_all_os_types, UserSelectableOsTypeSet types) override; UserSelectableOsTypeSet GetRegisteredSelectableOsTypes() const override; + + bool GetOsSyncFeatureEnabled() const override; + void SetOsSyncFeatureEnabled(bool enabled) override; #endif bool IsEncryptEverythingAllowed() const override; @@ -77,6 +80,7 @@ bool first_setup_complete_ = true; bool sync_everything_enabled_ = true; #if defined(OS_CHROMEOS) + bool os_sync_feature_enabled_ = true; bool sync_all_os_types_enabled_ = true; #endif
diff --git a/components/test/data/autofill_assistant/html/form_target_website.html b/components/test/data/autofill_assistant/html/form_target_website.html new file mode 100644 index 0000000..76c8546 --- /dev/null +++ b/components/test/data/autofill_assistant/html/form_target_website.html
@@ -0,0 +1,43 @@ +<html> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="robots" content="noindex, nofollow"> + <title>Form tests.</title> + </head> + <body> + <h3>Form filling</h3> + + <h4>Credit card</h4> + <div> + <form id="form1" action="https://example.com/" method="post"> + Name on card: <input type="text" id="name" name="name"/><br/> + Card Number: <input type="text" id="card_number" name="card_number"/><br/> + CVC: <input type="text" name="cv2_number" id="cv2_number"/><br/> + Expiry date: <select name="exp_month" id="exp_month"> + <option value="01">01</option> + <option value="02">02</option> + <option value="03">03</option> + <option value="04">04</option> + <option value="05">05</option> + <option value="06">06</option> + <option value="07">07</option> + <option value="08">08</option> + <option value="09">09</option> + <option value="10">10</option> + <option value="11">11</option> + <option value="12">12</option> + </select> + <select name="exp_year" id="exp_year"> + <option value="2019">2019</option> + <option value="2020">2020</option> + <option value="2021">2021</option> + <option value="2022">2022</option> + <option value="2023">2023</option> + <option value="2050">2050</option> + </select> + </form> + </div> + </body> +</html> +
diff --git a/components/url_formatter/spoof_checks/idn_spoof_checker.cc b/components/url_formatter/spoof_checks/idn_spoof_checker.cc index bc26d591..fdcdcde 100644 --- a/components/url_formatter/spoof_checks/idn_spoof_checker.cc +++ b/components/url_formatter/spoof_checks/idn_spoof_checker.cc
@@ -298,6 +298,11 @@ icelandic_characters_.containsSome(label_string)) return false; + // Disallow Latin Schwa (U+0259) for domains outside Azerbaijan's ccTLD (.az). + if (label_string.length() > 1 && top_level_domain != "az" && + label_string.indexOf("É™") != -1) + return false; + // If there's no script mixing, the input is regarded as safe without any // extra check unless it falls into one of three categories: // - contains Kana letter exceptions
diff --git a/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc b/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc index 981a4c0..4e8363f 100644 --- a/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc +++ b/components/url_formatter/spoof_checks/idn_spoof_checker_unittest.cc
@@ -1123,6 +1123,10 @@ {"xn--mnpqr-jta.com", L"mnðpqr.com", false}, {"xn--acdef-wva.is", L"aþcdef.is", true}, {"xn--mnpqr-jta.is", L"mnðpqr.is", true}, + + // U+0259 (É™) is only allowed under the .az TLD. + {"xn--xample-vyc.com", L"É™xample.com", false}, + {"xn--xample-vyc.az", L"É™xample.az", true}, }; // namespace namespace test {
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn index 7fe0b75a..18b3f6d 100644 --- a/components/viz/common/BUILD.gn +++ b/components/viz/common/BUILD.gn
@@ -124,10 +124,15 @@ public_deps = [ "//skia", + "//third_party/dawn/src/dawn:dawn_headers", ] deps = [ "//base", + "//third_party/dawn:libdawn_native", + "//third_party/dawn:libdawn_native_sources", + "//third_party/dawn/src/dawn:dawncpp", + "//third_party/dawn/src/dawn:libdawn_proc", ] } }
diff --git a/components/viz/common/display/overlay_strategy.cc b/components/viz/common/display/overlay_strategy.cc index 7dfdd63..1d647e8 100644 --- a/components/viz/common/display/overlay_strategy.cc +++ b/components/viz/common/display/overlay_strategy.cc
@@ -9,7 +9,7 @@ namespace viz { -std::vector<OverlayStrategy> ParseOverlayStategies( +std::vector<OverlayStrategy> ParseOverlayStrategies( const std::string& strategies_string) { std::vector<OverlayStrategy> strategies;
diff --git a/components/viz/common/display/overlay_strategy.h b/components/viz/common/display/overlay_strategy.h index d88cc31..bd8d68af 100644 --- a/components/viz/common/display/overlay_strategy.h +++ b/components/viz/common/display/overlay_strategy.h
@@ -26,7 +26,7 @@ // Parses a comma separated list of overlay strategy types and returns a list // of the corresponding OverlayStrategy enum values. -VIZ_COMMON_EXPORT std::vector<OverlayStrategy> ParseOverlayStategies( +VIZ_COMMON_EXPORT std::vector<OverlayStrategy> ParseOverlayStrategies( const std::string& strategies_string); } // namespace viz
diff --git a/components/viz/common/display/overlay_strategy_unittest.cc b/components/viz/common/display/overlay_strategy_unittest.cc index 7df3227..d0c1299 100644 --- a/components/viz/common/display/overlay_strategy_unittest.cc +++ b/components/viz/common/display/overlay_strategy_unittest.cc
@@ -16,13 +16,13 @@ namespace viz { TEST(ParseOverlayStrategiesTest, ParseEmptyList) { - std::vector<OverlayStrategy> strategies = ParseOverlayStategies(""); + std::vector<OverlayStrategy> strategies = ParseOverlayStrategies(""); EXPECT_THAT(strategies, IsEmpty()); } TEST(ParseOverlayStrategiesTest, ParseFullList) { std::vector<OverlayStrategy> strategies = - ParseOverlayStategies("single-fullscreen,single-on-top,underlay,cast"); + ParseOverlayStrategies("single-fullscreen,single-on-top,underlay,cast"); EXPECT_THAT(strategies, UnorderedElementsAre(OverlayStrategy::kFullscreen, OverlayStrategy::kSingleOnTop, @@ -32,7 +32,7 @@ TEST(ParseOverlayStrategiesTest, BadValue) { std::vector<OverlayStrategy> strategies = - ParseOverlayStategies("single-fullscreen,bad-value,underlay"); + ParseOverlayStrategies("single-fullscreen,bad-value,underlay"); // The string "bad-value" doesn't correspond to an overlay strategy so it // should be skipped.
diff --git a/components/viz/common/gpu/DEPS b/components/viz/common/gpu/DEPS index ba50fcbe2..5cbd28a 100644 --- a/components/viz/common/gpu/DEPS +++ b/components/viz/common/gpu/DEPS
@@ -7,6 +7,7 @@ "+gpu/command_buffer", "+gpu/GLES2/gl2extchromium.h", "+gpu/vulkan", + "+third_party/dawn/src/include", "+third_party/khronos/GLES2/gl2.h", "+third_party/skia/include/gpu", "+third_party/vulkan/include",
diff --git a/components/viz/common/gpu/dawn_context_provider.cc b/components/viz/common/gpu/dawn_context_provider.cc index 0321686f..38fa7cd0 100644 --- a/components/viz/common/gpu/dawn_context_provider.cc +++ b/components/viz/common/gpu/dawn_context_provider.cc
@@ -4,10 +4,28 @@ #include "components/viz/common/gpu/dawn_context_provider.h" +#include "base/logging.h" #include "base/memory/ptr_util.h" +#include "build/build_config.h" +#include "third_party/dawn/src/include/dawn/dawn_proc.h" namespace viz { +namespace { + +dawn_native::BackendType GetDefaultBackendType() { +#if defined(OS_WIN) + return dawn_native::BackendType::D3D12; +#elif defined(OS_LINUX) + return dawn_native::BackendType::Vulkan; +#else + NOTREACHED(); + return dawn_native::BackendType::Null; +#endif +} + +} // namespace + std::unique_ptr<DawnContextProvider> DawnContextProvider::Create() { auto context_provider = base::WrapUnique(new DawnContextProvider()); if (!context_provider->IsValid()) @@ -15,8 +33,25 @@ return context_provider; } -DawnContextProvider::DawnContextProvider() = default; +DawnContextProvider::DawnContextProvider() { + device_ = CreateDevice(GetDefaultBackendType()); + if (device_) + gr_context_ = GrContext::MakeDawn(device_); +} DawnContextProvider::~DawnContextProvider() = default; +dawn::Device DawnContextProvider::CreateDevice(dawn_native::BackendType type) { + instance_.DiscoverDefaultAdapters(); + DawnProcTable backend_procs = dawn_native::GetProcs(); + dawnProcSetProcs(&backend_procs); + + std::vector<dawn_native::Adapter> adapters = instance_.GetAdapters(); + for (dawn_native::Adapter adapter : adapters) { + if (adapter.GetBackendType() == type) + return adapter.CreateDevice(); + } + return nullptr; +} + } // namespace viz
diff --git a/components/viz/common/gpu/dawn_context_provider.h b/components/viz/common/gpu/dawn_context_provider.h index ef88a8a..b1d81b1 100644 --- a/components/viz/common/gpu/dawn_context_provider.h +++ b/components/viz/common/gpu/dawn_context_provider.h
@@ -7,7 +7,9 @@ #include "base/macros.h" #include "components/viz/common/viz_dawn_context_provider_export.h" +#include "third_party/dawn/src/include/dawn_native/DawnNative.h" #include "third_party/skia/include/gpu/GrContext.h" +#include "third_party/skia/include/gpu/dawn/GrDawnTypes.h" class GrContext; @@ -18,12 +20,17 @@ static std::unique_ptr<DawnContextProvider> Create(); ~DawnContextProvider(); + dawn::Device GetDevice() { return device_; } GrContext* GetGrContext() { return gr_context_.get(); } bool IsValid() { return !!gr_context_; } private: DawnContextProvider(); + dawn::Device CreateDevice(dawn_native::BackendType type); + + dawn_native::Instance instance_; + dawn::Device device_; sk_sp<GrContext> gr_context_; DISALLOW_COPY_AND_ASSIGN(DawnContextProvider);
diff --git a/components/viz/host/renderer_settings_creation.cc b/components/viz/host/renderer_settings_creation.cc index f17aa1f..cb69e08 100644 --- a/components/viz/host/renderer_settings_creation.cc +++ b/components/viz/host/renderer_settings_creation.cc
@@ -86,7 +86,7 @@ #if defined(USE_OZONE) if (command_line->HasSwitch(switches::kEnableHardwareOverlays)) { - renderer_settings.overlay_strategies = ParseOverlayStategies( + renderer_settings.overlay_strategies = ParseOverlayStrategies( command_line->GetSwitchValueASCII(switches::kEnableHardwareOverlays)); } else { auto& host_properties =
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn index 79aa878..bff4aa5 100644 --- a/components/viz/service/BUILD.gn +++ b/components/viz/service/BUILD.gn
@@ -6,6 +6,7 @@ import("//components/viz/viz.gni") import("//gpu/vulkan/features.gni") import("//media/gpu/args.gni") +import("//skia/features.gni") import("//testing/libfuzzer/fuzzer_test.gni") config("viz_service_implementation") { @@ -391,6 +392,21 @@ configs = [ "//build/config/linux:x11" ] deps += [ "//ui/gfx/x" ] } + + if (skia_use_dawn) { + sources += [ + "display_embedder/skia_output_device_dawn.cc", + "display_embedder/skia_output_device_dawn.h", + ] + + public_deps += [ "//third_party/dawn/src/dawn:dawn_headers" ] + + deps += [ + "//third_party/dawn:libdawn_native", + "//third_party/dawn:libdawn_native_sources", + "//third_party/dawn/src/dawn:dawncpp", + ] + } } viz_source_set("unit_tests") {
diff --git a/components/viz/service/display_embedder/DEPS b/components/viz/service/display_embedder/DEPS index 577b438e..38a3343 100644 --- a/components/viz/service/display_embedder/DEPS +++ b/components/viz/service/display_embedder/DEPS
@@ -31,6 +31,7 @@ "+mojo/public/cpp/bindings", "+mojo/public/cpp/system", "+skia", + "+third_party/dawn/src/include", "+third_party/khronos/GLES2/gl2.h", "+third_party/khronos/GLES2/gl2ext.h", "+third_party/skia",
diff --git a/components/viz/service/display_embedder/skia_output_device_dawn.cc b/components/viz/service/display_embedder/skia_output_device_dawn.cc new file mode 100644 index 0000000..b2153b8 --- /dev/null +++ b/components/viz/service/display_embedder/skia_output_device_dawn.cc
@@ -0,0 +1,121 @@ +// 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/viz/service/display_embedder/skia_output_device_dawn.h" + +#include "base/logging.h" +#include "build/build_config.h" +#include "components/viz/common/gpu/dawn_context_provider.h" + +#if defined(OS_WIN) +#include "third_party/dawn/src/include/dawn_native/D3D12Backend.h" +#elif defined(OS_LINUX) +#include "third_party/dawn/src/include/dawn_native/VulkanBackend.h" +#endif + +namespace viz { + +namespace { + +// Some Vulkan drivers do not support kRGB_888x_SkColorType. Always use +// kRGBA_8888_SkColorType instead and initialize surface to opaque as necessary. +constexpr SkColorType kSurfaceColorType = kRGBA_8888_SkColorType; +constexpr dawn::TextureFormat kSwapChainFormat = + dawn::TextureFormat::RGBA8Unorm; + +constexpr dawn::TextureUsage kUsage = + dawn::TextureUsage::OutputAttachment | dawn::TextureUsage::CopySrc; + +} // namespace + +SkiaOutputDeviceDawn::SkiaOutputDeviceDawn( + DawnContextProvider* context_provider, + gfx::AcceleratedWidget widget, + DidSwapBufferCompleteCallback did_swap_buffer_complete_callback) + : SkiaOutputDevice(/*need_swap_semaphore=*/false, + did_swap_buffer_complete_callback), + context_provider_(context_provider), + widget_(widget) { + capabilities_.supports_post_sub_buffer = false; +} + +SkiaOutputDeviceDawn::~SkiaOutputDeviceDawn() = default; + +bool SkiaOutputDeviceDawn::Reshape(const gfx::Size& size, + float device_scale_factor, + const gfx::ColorSpace& color_space, + bool has_alpha, + gfx::OverlayTransform transform) { + DCHECK_EQ(transform, gfx::OVERLAY_TRANSFORM_NONE); + + DiscardBackbuffer(); + size_ = size; + sk_color_space_ = color_space.ToSkColorSpace(); + + CreateSwapChainImplementation(); + dawn::SwapChainDescriptor desc; + desc.implementation = reinterpret_cast<int64_t>(&swap_chain_implementation_); + swap_chain_ = context_provider_->GetDevice().CreateSwapChain(&desc); + if (!swap_chain_) + return false; + swap_chain_.Configure(kSwapChainFormat, kUsage, size_.width(), + size_.height()); + + EnsureBackbuffer(); + return true; +} + +void SkiaOutputDeviceDawn::SwapBuffers( + BufferPresentedCallback feedback, + std::vector<ui::LatencyInfo> latency_info) { + StartSwapBuffers(std::move(feedback)); + swap_chain_.Present(texture_); + texture_ = swap_chain_.GetNextTexture(); + FinishSwapBuffers(gfx::SwapResult::SWAP_ACK, + gfx::Size(size_.width(), size_.height()), + std::move(latency_info)); +} + +SkSurface* SkiaOutputDeviceDawn::BeginPaint() { + GrDawnImageInfo info; + info.fTexture = texture_; + info.fFormat = kSwapChainFormat; + info.fLevelCount = 1; + GrBackendTexture backend_texture(size_.width(), size_.height(), info); + DCHECK(backend_texture.isValid()); + sk_surface_ = SkSurface::MakeFromBackendTextureAsRenderTarget( + context_provider_->GetGrContext(), backend_texture, + !capabilities_.flipped_output_surface ? kTopLeft_GrSurfaceOrigin + : kBottomLeft_GrSurfaceOrigin, + /*sampleCount=*/0, kSurfaceColorType, sk_color_space_, + /*surfaceProps=*/nullptr); + return sk_surface_.get(); +} + +void SkiaOutputDeviceDawn::EndPaint(const GrBackendSemaphore& semaphore) { + GrFlushInfo flush_info; + sk_surface_->flush(SkSurface::BackendSurfaceAccess::kPresent, flush_info); + sk_surface_.reset(); +} + +void SkiaOutputDeviceDawn::EnsureBackbuffer() { + if (swap_chain_) + texture_ = swap_chain_.GetNextTexture(); +} + +void SkiaOutputDeviceDawn::DiscardBackbuffer() { + texture_ = nullptr; +} + +void SkiaOutputDeviceDawn::CreateSwapChainImplementation() { +#if defined(OS_WIN) + swap_chain_implementation_ = dawn_native::d3d12::CreateNativeSwapChainImpl( + context_provider_->GetDevice().Get(), widget_); +#else + NOTREACHED(); + ALLOW_UNUSED_LOCAL(widget_); +#endif +} + +} // namespace viz
diff --git a/components/viz/service/display_embedder/skia_output_device_dawn.h b/components/viz/service/display_embedder/skia_output_device_dawn.h new file mode 100644 index 0000000..a39722b --- /dev/null +++ b/components/viz/service/display_embedder/skia_output_device_dawn.h
@@ -0,0 +1,62 @@ +// 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_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_DAWN_H_ +#define COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_DAWN_H_ + +#include "components/viz/service/display_embedder/skia_output_device.h" +#include "third_party/dawn/src/include/dawn/dawn_wsi.h" +#include "third_party/dawn/src/include/dawn/dawncpp.h" +#include "third_party/dawn/src/include/dawn_native/DawnNative.h" +#include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImageInfo.h" +#include "third_party/skia/include/gpu/GrBackendSurface.h" +#include "ui/gfx/native_widget_types.h" + +namespace viz { + +class DawnContextProvider; + +class SkiaOutputDeviceDawn : public SkiaOutputDevice { + public: + SkiaOutputDeviceDawn( + DawnContextProvider* context_provider, + gfx::AcceleratedWidget widget, + DidSwapBufferCompleteCallback did_swap_buffer_complete_callback); + ~SkiaOutputDeviceDawn() override; + + // SkiaOutputDevice implementation: + bool Reshape(const gfx::Size& size, + float device_scale_factor, + const gfx::ColorSpace& color_space, + bool has_alpha, + gfx::OverlayTransform transform) override; + void SwapBuffers(BufferPresentedCallback feedback, + std::vector<ui::LatencyInfo> latency_info) override; + SkSurface* BeginPaint() override; + void EndPaint(const GrBackendSemaphore& semaphore) override; + void EnsureBackbuffer() override; + void DiscardBackbuffer() override; + + private: + // Create a platform-specific swapchain implementation. + void CreateSwapChainImplementation(); + + DawnContextProvider* const context_provider_; + gfx::AcceleratedWidget widget_; + DawnSwapChainImplementation swap_chain_implementation_; + dawn::SwapChain swap_chain_; + dawn::Texture texture_; + sk_sp<SkSurface> sk_surface_; + + gfx::Size size_; + sk_sp<SkColorSpace> sk_color_space_; + GrBackendTexture backend_texture_; + + DISALLOW_COPY_AND_ASSIGN(SkiaOutputDeviceDawn); +}; + +} // namespace viz + +#endif // COMPONENTS_VIZ_SERVICE_DISPLAY_EMBEDDER_SKIA_OUTPUT_DEVICE_DAWN_H_
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency.h b/components/viz/service/display_embedder/skia_output_surface_dependency.h index f901706..2eb2156f 100644 --- a/components/viz/service/display_embedder/skia_output_surface_dependency.h +++ b/components/viz/service/display_embedder/skia_output_surface_dependency.h
@@ -44,6 +44,7 @@ namespace viz { +class DawnContextProvider; class VulkanContextProvider; // This class exists to allow SkiaOutputSurfaceImpl to ignore differences @@ -59,6 +60,7 @@ // These are client thread methods. All other methods should be called on // the GPU thread only. virtual bool IsUsingVulkan() = 0; + virtual bool IsUsingDawn() = 0; // Returns a new task execution sequence. Sequences should not outlive the // task executor. virtual std::unique_ptr<gpu::SingleTaskSequence> CreateSequence() = 0; @@ -71,6 +73,8 @@ virtual gpu::raster::GrShaderCache* GetGrShaderCache() = 0; // May return null. virtual VulkanContextProvider* GetVulkanContextProvider() = 0; + // May return null. + virtual DawnContextProvider* GetDawnContextProvider() = 0; virtual const gpu::GpuPreferences& GetGpuPreferences() = 0; virtual const gpu::GpuFeatureInfo& GetGpuFeatureInfo() = 0; virtual gpu::MailboxManager* GetMailboxManager() = 0;
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc index f90e12b2..83979b6 100644 --- a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.cc
@@ -33,6 +33,10 @@ return gpu_service_impl_->is_using_vulkan(); } +bool SkiaOutputSurfaceDependencyImpl::IsUsingDawn() { + return gpu_service_impl_->is_using_dawn(); +} + gpu::SharedImageManager* SkiaOutputSurfaceDependencyImpl::GetSharedImageManager() { return gpu_service_impl_->shared_image_manager(); @@ -62,6 +66,10 @@ return gpu_service_impl_->vulkan_context_provider(); } +DawnContextProvider* SkiaOutputSurfaceDependencyImpl::GetDawnContextProvider() { + return gpu_service_impl_->dawn_context_provider(); +} + const gpu::GpuPreferences& SkiaOutputSurfaceDependencyImpl::GetGpuPreferences() { return gpu_service_impl_->gpu_preferences();
diff --git a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h index 27d32cc9..a113658 100644 --- a/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_dependency_impl.h
@@ -26,12 +26,14 @@ std::unique_ptr<gpu::SingleTaskSequence> CreateSequence() override; bool IsUsingVulkan() override; + bool IsUsingDawn() override; gpu::SharedImageManager* GetSharedImageManager() override; gpu::SyncPointManager* GetSyncPointManager() override; const gpu::GpuDriverBugWorkarounds& GetGpuDriverBugWorkarounds() override; scoped_refptr<gpu::SharedContextState> GetSharedContextState() override; gpu::raster::GrShaderCache* GetGrShaderCache() override; VulkanContextProvider* GetVulkanContextProvider() override; + DawnContextProvider* GetDawnContextProvider() override; const gpu::GpuPreferences& GetGpuPreferences() override; const gpu::GpuFeatureInfo& GetGpuFeatureInfo() override; gpu::MailboxManager* GetMailboxManager() override;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.cc b/components/viz/service/display_embedder/skia_output_surface_impl.cc index 568a71a..95fdd006 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl.cc
@@ -31,6 +31,7 @@ #include "gpu/ipc/service/context_url.h" #include "gpu/ipc/single_task_sequence.h" #include "gpu/vulkan/buildflags.h" +#include "skia/buildflags.h" #include "ui/gfx/skia_util.h" #include "ui/gl/gl_context.h" #include "ui/gl/gl_gl_api_implementation.h" @@ -98,6 +99,41 @@ : OutputSurface::Type::kOpenGL; } +#if BUILDFLAG(SKIA_USE_DAWN) +// TODO(sgilhuly): Resolve conflicts with X11/X.h so that this can be moved to +// resource_format_utils.cc. +dawn::TextureFormat ToDawnFormat(ResourceFormat format) { + switch (format) { + case RGBA_8888: + case RGBX_8888: + return dawn::TextureFormat::RGBA8Unorm; + case BGRA_8888: + case BGRX_8888: + return dawn::TextureFormat::BGRA8Unorm; + case RED_8: + case ALPHA_8: + case LUMINANCE_8: + return dawn::TextureFormat::R8Unorm; + case RGBA_4444: + case RGB_565: + case BGR_565: + case RG_88: + case RGBA_F16: + case R16_EXT: + case RGBX_1010102: + case BGRX_1010102: + case YVU_420: + case YUV_420_BIPLANAR: + case ETC1: + case LUMINANCE_F16: + case P010: + break; + } + NOTREACHED() << "Unsupported format " << format; + return dawn::TextureFormat::Undefined; +} +#endif + } // namespace SkiaOutputSurfaceImpl::ScopedPaint::ScopedPaint( @@ -132,7 +168,6 @@ const RendererSettings& renderer_settings) : SkiaOutputSurface(GetOutputSurfaceType(deps.get())), dependency_(std::move(deps)), - is_using_vulkan_(dependency_->IsUsingVulkan()), renderer_settings_(renderer_settings) { DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } @@ -814,14 +849,7 @@ ResourceFormat resource_format, uint32_t gl_texture_target, const base::Optional<gpu::VulkanYCbCrInfo>& ycbcr_info) { - if (!is_using_vulkan_) { - DCHECK(!ycbcr_info); - // Convert internal format from GLES2 to platform GL. - unsigned int texture_storage_format = gpu::GetGrGLBackendTextureFormat( - impl_on_gpu_->GetFeatureInfo(), resource_format); - - return GrBackendFormat::MakeGL(texture_storage_format, gl_texture_target); - } else { + if (dependency_->IsUsingVulkan()) { #if BUILDFLAG(ENABLE_VULKAN) if (!ycbcr_info) { // YCbCr info is required for YUV images. @@ -836,11 +864,22 @@ ->GetVulkanPhysicalDevice(), VK_IMAGE_TILING_OPTIMAL, ycbcr_info); return GrBackendFormat::MakeVk(gr_ycbcr_info); -#else - NOTREACHED(); - return GrBackendFormat(); #endif + } else if (dependency_->IsUsingDawn()) { +#if BUILDFLAG(SKIA_USE_DAWN) + dawn::TextureFormat format = ToDawnFormat(resource_format); + return GrBackendFormat::MakeDawn(format); +#endif + } else { + DCHECK(!ycbcr_info); + // Convert internal format from GLES2 to platform GL. + unsigned int texture_storage_format = gpu::GetGrGLBackendTextureFormat( + impl_on_gpu_->GetFeatureInfo(), resource_format); + + return GrBackendFormat::MakeGL(texture_storage_format, gl_texture_target); } + NOTREACHED(); + return GrBackendFormat(); } void SkiaOutputSurfaceImpl::SwapBuffers(OutputSurfaceFrame frame) {
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl.h b/components/viz/service/display_embedder/skia_output_surface_impl.h index 0af491dc..e2a4960 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl.h
@@ -199,7 +199,6 @@ uint64_t sync_fence_release_ = 0; std::unique_ptr<SkiaOutputSurfaceDependency> dependency_; - const bool is_using_vulkan_; UpdateVSyncParametersCallback update_vsync_parameters_callback_; GpuVSyncCallback gpu_vsync_callback_; bool is_displayed_as_overlay_ = false;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index 56975ad2..8db3c24 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -9,6 +9,7 @@ #include "base/bind_helpers.h" #include "base/callback_helpers.h" #include "base/command_line.h" +#include "base/debug/alias.h" #include "base/optional.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread_task_runner_handle.h" @@ -46,6 +47,7 @@ #include "gpu/ipc/common/gpu_client_ids.h" #include "gpu/ipc/common/gpu_surface_lookup.h" #include "gpu/vulkan/buildflags.h" +#include "skia/buildflags.h" #include "skia/ext/image_operations.h" #include "third_party/skia/include/core/SkPixelRef.h" #include "third_party/skia/include/private/SkDeferredDisplayList.h" @@ -63,7 +65,7 @@ #include "components/viz/service/display_embedder/skia_output_device_vulkan.h" #endif -#if BUILDFLAG(ENABLE_VULKAN) && defined(USE_X11) +#if (BUILDFLAG(ENABLE_VULKAN) || BUILDFLAG(SKIA_USE_DAWN)) && defined(USE_X11) #include "components/viz/service/display_embedder/skia_output_device_x11.h" #endif @@ -73,6 +75,11 @@ #include "ui/ozone/public/surface_factory_ozone.h" #endif +#if BUILDFLAG(SKIA_USE_DAWN) +#include "components/viz/common/gpu/dawn_context_provider.h" +#include "components/viz/service/display_embedder/skia_output_device_dawn.h" +#endif + namespace viz { namespace { @@ -625,6 +632,7 @@ shared_image_representation_factory_( CreateSharedImageRepresentationFactory(dependency_)), vulkan_context_provider_(dependency_->GetVulkanContextProvider()), + dawn_context_provider_(dependency_->GetDawnContextProvider()), renderer_settings_(renderer_settings), sequence_id_(sequence_id), did_swap_buffer_complete_callback_( @@ -891,9 +899,14 @@ DCHECK(offscreen.surface()); } else { #if DCHECK_IS_ON() + // TODO(crbug.com/1022304): Remove aliasing after figuring out how + // characterizations are different. SkSurfaceCharacterization characterization; - DCHECK(offscreen.surface()->characterize(&characterization) && - characterization == ddl->characterization()); + DCHECK(offscreen.surface()->characterize(&characterization)); + base::debug::Alias(&characterization); + SkSurfaceCharacterization ddl_characterization = ddl->characterization(); + base::debug::Alias(&ddl_characterization); + DCHECK(characterization == ddl_characterization); #endif } { @@ -962,8 +975,8 @@ base::BindOnce([](std::vector<std::unique_ptr<SkDeferredDisplayList>>) {}, std::move(destroy_after_swap_))); - bool use_gl_renderer_copier = - !is_using_vulkan() && !features::IsUsingSkiaForGLReadback(); + bool use_gl_renderer_copier = !is_using_vulkan() && !is_using_dawn() && + !features::IsUsingSkiaForGLReadback(); if (use_gl_renderer_copier) gpu::ContextUrl::SetActiveUrl(copier_active_url_); @@ -1283,8 +1296,16 @@ ->CreatePlatformWindowSurface(dependency_->GetSurfaceHandle()); #endif - if (!(is_using_vulkan() ? InitializeForVulkan() : InitializeForGL())) - return false; + if (is_using_vulkan()) { + if (!InitializeForVulkan()) + return false; + } else if (is_using_dawn()) { + if (!InitializeForDawn()) + return false; + } else { + if (!InitializeForGL()) + return false; + } max_resource_cache_bytes_ = context_state_->max_resource_cache_bytes(); return true; } @@ -1378,6 +1399,33 @@ return true; } +bool SkiaOutputSurfaceImplOnGpu::InitializeForDawn() { + context_state_ = dependency_->GetSharedContextState(); + DCHECK(context_state_); +#if BUILDFLAG(SKIA_USE_DAWN) + if (dependency_->IsOffscreen()) { + output_device_ = std::make_unique<SkiaOutputDeviceOffscreen>( + context_state_, false /* flipped */, + renderer_settings_.requires_alpha_channel, + did_swap_buffer_complete_callback_); + supports_alpha_ = renderer_settings_.requires_alpha_channel; + } else { +#if defined(USE_X11) + // TODO(sgilhuly): Set up a Vulkan swapchain so that Linux can also use + // SkiaOutputDeviceDawn. + output_device_ = std::make_unique<SkiaOutputDeviceX11>( + context_state_, dependency_->GetSurfaceHandle(), + did_swap_buffer_complete_callback_); +#else + output_device_ = std::make_unique<SkiaOutputDeviceDawn>( + dawn_context_provider_, dependency_->GetSurfaceHandle(), + did_swap_buffer_complete_callback_); +#endif + } +#endif + return true; +} + bool SkiaOutputSurfaceImplOnGpu::MakeCurrent(bool need_fbo0) { if (!is_using_vulkan()) { if (context_state_->context_lost())
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index f3b5952..852c5a97 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -60,9 +60,10 @@ namespace viz { +class DawnContextProvider; class DirectContextProvider; -class ImageContextImpl; class GLRendererCopier; +class ImageContextImpl; class SkiaOutputSurfaceDependency; class TextureDeleter; class VulkanContextProvider; @@ -205,6 +206,7 @@ bool Initialize(); bool InitializeForGL(); bool InitializeForVulkan(); + bool InitializeForDawn(); // Make context current for GL, and return false if the context is lost. // It will do nothing when Vulkan is used. @@ -224,6 +226,10 @@ return !!vulkan_context_provider_ && gpu_preferences_.gr_context_type == gpu::GrContextType::kVulkan; } + bool is_using_dawn() const { + return !!dawn_context_provider_ && + gpu_preferences_.gr_context_type == gpu::GrContextType::kDawn; + } SkSurface* output_sk_surface() const { return scoped_output_device_paint_->sk_surface(); @@ -235,6 +241,7 @@ std::unique_ptr<gpu::SharedImageRepresentationFactory> shared_image_representation_factory_; VulkanContextProvider* const vulkan_context_provider_; + DawnContextProvider* const dawn_context_provider_; const RendererSettings renderer_settings_; // This is only used to lazily create DirectContextProviderDelegate for // readback using GLRendererCopier.
diff --git a/components/viz/service/gl/DEPS b/components/viz/service/gl/DEPS index a24294a..4402b88 100644 --- a/components/viz/service/gl/DEPS +++ b/components/viz/service/gl/DEPS
@@ -15,6 +15,7 @@ "+media/gpu", "+media/mojo", "+mojo/public/cpp", + "+skia/buildflags.h", "+services/viz/privileged/mojom", "+ui/gl", ]
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc index d38dfac5..8ac4e0e 100644 --- a/components/viz/service/gl/gpu_service_impl.cc +++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -50,6 +50,7 @@ #include "media/gpu/ipc/service/media_gpu_channel_manager.h" #include "media/mojo/services/mojo_video_encode_accelerator_provider.h" #include "mojo/public/cpp/bindings/self_owned_receiver.h" +#include "skia/buildflags.h" #include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h" #include "third_party/skia/include/gpu/gl/GrGLInterface.h" @@ -89,6 +90,10 @@ #include "ui/base/cocoa/quartz_util.h" #endif +#if BUILDFLAG(SKIA_USE_DAWN) +#include "components/viz/common/gpu/dawn_context_provider.h" +#endif + namespace viz { namespace { @@ -180,6 +185,19 @@ } #endif +#if BUILDFLAG(SKIA_USE_DAWN) + if (gpu_preferences_.gr_context_type == gpu::GrContextType::kDawn) { + dawn_context_provider_ = DawnContextProvider::Create(); + if (dawn_context_provider_) { + gpu_info_.oop_rasterization_supported = true; + gpu_feature_info_.status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] = + gpu::kGpuFeatureStatusEnabled; + } else { + DLOG(WARNING) << "Failed to create Dawn context provider."; + } + } +#endif + #if BUILDFLAG(USE_VAAPI) image_decode_accelerator_worker_ = media::VaapiImageDecodeAcceleratorWorker::Create(); @@ -330,7 +348,7 @@ gpu_memory_buffer_factory_.get(), gpu_feature_info_, std::move(activity_flags), std::move(default_offscreen_surface), image_decode_accelerator_worker_.get(), vulkan_context_provider(), - metal_context_provider_.get()); + metal_context_provider_.get(), dawn_context_provider()); media_gpu_channel_manager_.reset( new media::MediaGpuChannelManager(gpu_channel_manager_.get()));
diff --git a/components/viz/service/gl/gpu_service_impl.h b/components/viz/service/gl/gpu_service_impl.h index 7919309..50d2003 100644 --- a/components/viz/service/gl/gpu_service_impl.h +++ b/components/viz/service/gl/gpu_service_impl.h
@@ -38,6 +38,7 @@ #include "mojo/public/cpp/bindings/shared_remote.h" #include "services/viz/privileged/mojom/gl/gpu_host.mojom.h" #include "services/viz/privileged/mojom/gl/gpu_service.mojom.h" +#include "skia/buildflags.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "ui/gfx/native_widget_types.h" @@ -69,6 +70,7 @@ class VulkanContextProvider; class MetalContextProvider; +class DawnContextProvider; // This runs in the GPU process, and communicates with the gpu host (which is // the window server) over the mojom APIs. This is responsible for setting up @@ -268,6 +270,16 @@ VulkanContextProvider* vulkan_context_provider() { return nullptr; } #endif +#if BUILDFLAG(SKIA_USE_DAWN) + bool is_using_dawn() const { return !!dawn_context_provider_; } + DawnContextProvider* dawn_context_provider() { + return dawn_context_provider_.get(); + } +#else + bool is_using_dawn() const { return false; } + DawnContextProvider* dawn_context_provider() { return nullptr; } +#endif + void set_oopd_enabled() { oopd_enabled_ = true; } private: @@ -344,6 +356,9 @@ scoped_refptr<VulkanContextProvider> vulkan_context_provider_; #endif std::unique_ptr<MetalContextProvider> metal_context_provider_; +#if BUILDFLAG(SKIA_USE_DAWN) + std::unique_ptr<DawnContextProvider> dawn_context_provider_; +#endif std::unique_ptr<gpu::GpuMemoryBufferFactory> gpu_memory_buffer_factory_;
diff --git a/content/browser/accessibility/accessibility_tree_formatter_base.cc b/content/browser/accessibility/accessibility_tree_formatter_base.cc index 0340968f..90ac4e5 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_base.cc +++ b/content/browser/accessibility/accessibility_tree_formatter_base.cc
@@ -52,10 +52,8 @@ formatter = Create(); base::string16 accessibility_contents_utf16; formatter->SetPropertyFilters(property_filters); - std::unique_ptr<base::DictionaryValue> dict = - static_cast<AccessibilityTreeFormatterBase*>(formatter.get()) - ->BuildAccessibilityTree(ax_mgr->GetRoot()); - formatter->FormatAccessibilityTree(*dict, &accessibility_contents_utf16); + formatter->FormatAccessibilityTree(ax_mgr->GetRoot(), + &accessibility_contents_utf16); return accessibility_contents_utf16; } @@ -97,11 +95,12 @@ return false; } -AccessibilityTreeFormatterBase::AccessibilityTreeFormatterBase() = default; +AccessibilityTreeFormatterBase::AccessibilityTreeFormatterBase() + : show_ids_(false) {} -AccessibilityTreeFormatterBase::~AccessibilityTreeFormatterBase() = default; +AccessibilityTreeFormatterBase::~AccessibilityTreeFormatterBase() {} -void AccessibilityTreeFormatterBase::FormatAccessibilityTreeForTesting( +void AccessibilityTreeFormatterBase::FormatAccessibilityTree( BrowserAccessibility* root, base::string16* contents) { std::unique_ptr<base::DictionaryValue> dict = BuildAccessibilityTree(root);
diff --git a/content/browser/accessibility/accessibility_tree_formatter_base.h b/content/browser/accessibility/accessibility_tree_formatter_base.h index 56e7244e..7b1f6b5 100644 --- a/content/browser/accessibility/accessibility_tree_formatter_base.h +++ b/content/browser/accessibility/accessibility_tree_formatter_base.h
@@ -66,14 +66,13 @@ virtual std::unique_ptr<base::DictionaryValue> BuildAccessibilityTree( BrowserAccessibility* root) = 0; - void FormatAccessibilityTreeForTesting(BrowserAccessibility* root, - base::string16* contents); - // AccessibilityTreeFormatter overrides. void AddDefaultFilters( std::vector<PropertyFilter>* property_filters) override; std::unique_ptr<base::DictionaryValue> FilterAccessibilityTree( const base::DictionaryValue& dict) override; + void FormatAccessibilityTree(BrowserAccessibility* root, + base::string16* contents) override; void FormatAccessibilityTree(const base::DictionaryValue& tree_node, base::string16* contents) override; void SetPropertyFilters( @@ -150,7 +149,7 @@ std::vector<NodeFilter> node_filters_; // Whether or not node ids should be included in the dump. - bool show_ids_ = false; + bool show_ids_; DISALLOW_COPY_AND_ASSIGN(AccessibilityTreeFormatterBase); };
diff --git a/content/browser/accessibility/accessibility_win_browsertest.cc b/content/browser/accessibility/accessibility_win_browsertest.cc index cd80daa..af04bfe 100644 --- a/content/browser/accessibility/accessibility_win_browsertest.cc +++ b/content/browser/accessibility/accessibility_win_browsertest.cc
@@ -38,7 +38,6 @@ #include "content/public/browser/web_contents.h" #include "content/public/common/url_constants.h" #include "content/public/test/accessibility_notification_waiter.h" -#include "content/public/test/browser_accessibility.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" #include "content/test/content_browser_test_utils_internal.h" @@ -129,9 +128,9 @@ DISALLOW_COPY_AND_ASSIGN(AccessibilityWinBrowserTest); }; -AccessibilityWinBrowserTest::AccessibilityWinBrowserTest() = default; +AccessibilityWinBrowserTest::AccessibilityWinBrowserTest() {} -AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() = default; +AccessibilityWinBrowserTest::~AccessibilityWinBrowserTest() {} base::string16 AccessibilityWinBrowserTest::PrintAXTree() const { std::unique_ptr<AccessibilityTreeFormatter> formatter( @@ -142,8 +141,11 @@ L"*", AccessibilityTreeFormatter::PropertyFilter::ALLOW)}); base::string16 str; - TestBrowserAccessibility::FormatAccessibilityTree( - formatter.get(), GetRootAccessibilityNode(shell()->web_contents()), &str); + formatter->FormatAccessibilityTree( + static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetRootBrowserAccessibilityManager() + ->GetRoot(), + &str); return str; }
diff --git a/content/browser/accessibility/browser_accessibility_android.cc b/content/browser/accessibility/browser_accessibility_android.cc index f67d71a..22302d7 100644 --- a/content/browser/accessibility/browser_accessibility_android.cc +++ b/content/browser/accessibility/browser_accessibility_android.cc
@@ -525,7 +525,8 @@ } } - if (text.empty() && (ui::IsLink(GetRole()) || ui::IsImage(GetRole())) && + if (text.empty() && + (ui::IsLink(GetRole()) || ui::IsImageOrVideo(GetRole())) && !HasExplicitlyEmptyName()) { base::string16 url = GetString16Attribute(ax::mojom::StringAttribute::kUrl); text = ui::AXUrlBaseText(url); @@ -1700,7 +1701,7 @@ } base::string16 BrowserAccessibilityAndroid::GetTargetUrl() const { - if (ui::IsImage(GetRole()) || ui::IsLink(GetRole())) + if (ui::IsImageOrVideo(GetRole()) || ui::IsLink(GetRole())) return GetString16Attribute(ax::mojom::StringAttribute::kUrl); return {}; @@ -1723,7 +1724,7 @@ } bool BrowserAccessibilityAndroid::HasImage() const { - if (ui::IsImage(GetRole())) + if (ui::IsImageOrVideo(GetRole())) return true; for (auto it = InternalChildrenBegin(); it != InternalChildrenEnd(); ++it) { @@ -1749,7 +1750,7 @@ for (auto it = InternalChildrenBegin(); it != InternalChildrenEnd(); ++it) { BrowserAccessibility* child = it.get(); if (child->GetRole() != ax::mojom::Role::kStaticText && - !ui::IsImage(child->GetRole())) { + !ui::IsImageOrVideo(child->GetRole())) { return false; } }
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc index 8a61098..a93abd7 100644 --- a/content/browser/accessibility/browser_accessibility_com_win.cc +++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -1590,19 +1590,10 @@ return E_NOINTERFACE; } - int32_t ia_role = accessibility->MSAARole(); + ax::mojom::Role role = accessibility->owner()->GetRole(); + if (iid == IID_IAccessibleImage) { - if (ia_role != ROLE_SYSTEM_GRAPHIC) { - *object = nullptr; - return E_NOINTERFACE; - } - } else if (iid == IID_IAccessibleTable || iid == IID_IAccessibleTable2) { - if (!ui::IsTableLike(accessibility->owner()->GetRole())) { - *object = nullptr; - return E_NOINTERFACE; - } - } else if (iid == IID_IAccessibleTableCell) { - if (!ui::IsCellOrTableHeader(accessibility->owner()->GetRole())) { + if (!ui::IsImage(role)) { *object = nullptr; return E_NOINTERFACE; } @@ -1612,7 +1603,7 @@ return E_NOINTERFACE; } } else if (iid == IID_ISimpleDOMDocument) { - if (ia_role != ROLE_SYSTEM_DOCUMENT) { + if (!ui::IsDocument(role)) { *object = nullptr; return E_NOINTERFACE; }
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.cc b/content/browser/accessibility/dump_accessibility_browsertest_base.cc index 55b6b10..d7078fd9 100644 --- a/content/browser/accessibility/dump_accessibility_browsertest_base.cc +++ b/content/browser/accessibility/dump_accessibility_browsertest_base.cc
@@ -31,7 +31,6 @@ #include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" #include "content/public/test/accessibility_notification_waiter.h" -#include "content/public/test/browser_accessibility.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" @@ -134,9 +133,11 @@ PropertyFilter(base::ASCIIToUTF16("*"), PropertyFilter::ALLOW)); formatter->SetPropertyFilters(property_filters); formatter->set_show_ids(true); + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); base::string16 ax_tree_dump; - TestBrowserAccessibility::FormatAccessibilityTree( - formatter.get(), GetRootAccessibilityNode(shell()->web_contents()), + formatter->FormatAccessibilityTree( + web_contents->GetRootBrowserAccessibilityManager()->GetRoot(), &ax_tree_dump); return ax_tree_dump; }
diff --git a/content/browser/accessibility/dump_accessibility_browsertest_base.h b/content/browser/accessibility/dump_accessibility_browsertest_base.h index 5577b91..cbea701b 100644 --- a/content/browser/accessibility/dump_accessibility_browsertest_base.h +++ b/content/browser/accessibility/dump_accessibility_browsertest_base.h
@@ -5,7 +5,6 @@ #ifndef CONTENT_BROWSER_ACCESSIBILITY_DUMP_ACCESSIBILITY_BROWSERTEST_BASE_H_ #define CONTENT_BROWSER_ACCESSIBILITY_DUMP_ACCESSIBILITY_BROWSERTEST_BASE_H_ -#include <memory> #include <string> #include <vector> @@ -17,8 +16,6 @@ namespace content { -class BrowserAccessibility; - // Base class for an accessibility browsertest that takes an HTML file as // input, loads it into a tab, dumps some accessibility data in text format, // then compares that text to an expectation file in the same directory.
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index 50b8c8808..85c4bf68 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -23,7 +23,6 @@ #include "content/public/common/content_paths.h" #include "content/public/common/content_switches.h" #include "content/public/test/accessibility_notification_waiter.h" -#include "content/public/test/browser_accessibility.h" #include "content/public/test/content_browser_test_utils.h" #include "content/shell/browser/shell.h" #include "ui/accessibility/accessibility_switches.h" @@ -148,8 +147,10 @@ formatter->SetPropertyFilters(property_filters_); formatter->SetNodeFilters(node_filters_); base::string16 actual_contents_utf16; - TestBrowserAccessibility::FormatAccessibilityTree( - formatter.get(), GetRootAccessibilityNode(shell()->web_contents()), + WebContentsImpl* web_contents = + static_cast<WebContentsImpl*>(shell()->web_contents()); + formatter->FormatAccessibilityTree( + web_contents->GetRootBrowserAccessibilityManager()->GetRoot(), &actual_contents_utf16); std::string actual_contents = base::UTF16ToUTF8(actual_contents_utf16); return base::SplitString(actual_contents, "\n", base::KEEP_WHITESPACE,
diff --git a/content/browser/accessibility/one_shot_accessibility_tree_search.cc b/content/browser/accessibility/one_shot_accessibility_tree_search.cc index 41b49ab..6229835 100644 --- a/content/browser/accessibility/one_shot_accessibility_tree_search.cc +++ b/content/browser/accessibility/one_shot_accessibility_tree_search.cc
@@ -294,7 +294,7 @@ bool AccessibilityGraphicPredicate(BrowserAccessibility* start, BrowserAccessibility* node) { - return ui::IsImage(node->GetRole()); + return ui::IsImageOrVideo(node->GetRole()); } bool AccessibilityHeadingPredicate(BrowserAccessibility* start,
diff --git a/content/browser/back_forward_cache_browsertest.cc b/content/browser/back_forward_cache_browsertest.cc index adecb5d..5d17142c 100644 --- a/content/browser/back_forward_cache_browsertest.cc +++ b/content/browser/back_forward_cache_browsertest.cc
@@ -327,6 +327,34 @@ base::Optional<SkColor> color_; }; +class DOMContentLoadedObserver : public WebContentsObserver { + public: + explicit DOMContentLoadedObserver(RenderFrameHostImpl* render_frame_host) + : WebContentsObserver( + WebContents::FromRenderFrameHost(render_frame_host)), + render_frame_host_(render_frame_host) {} + + void DOMContentLoaded(RenderFrameHost* render_frame_host) override { + if (render_frame_host_ == render_frame_host) + run_loop_.Quit(); + } + + void Wait() { + if (render_frame_host_->dom_content_loaded()) + run_loop_.Quit(); + run_loop_.Run(); + } + + private: + RenderFrameHostImpl* render_frame_host_; + base::RunLoop run_loop_; +}; + +void WaitForDOMContentLoaded(RenderFrameHostImpl* rfh) { + DOMContentLoadedObserver observer(rfh); + observer.Wait(); +} + } // namespace // Navigate from A to B and go back. @@ -1445,6 +1473,10 @@ // The navigation finishes while the image is still loading. navigation_manager.WaitForNavigationFinished(); + // Wait for the document to load DOM to ensure that kLoading is not + // one of the reasons why the document wasn't cached. + WaitForDOMContentLoaded(current_frame_host()); + RenderFrameDeletedObserver delete_observer_rfh_a(current_frame_host()); // 2) Navigate away. @@ -3652,6 +3684,32 @@ EXPECT_TRUE(observer.did_fire()); } +// Check that back-forward cache is disabled when PermissionService is used. +IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, PermissionServiceContext) { + content::BackForwardCacheDisabledTester tester; + ASSERT_TRUE(embedded_test_server()->Start()); + const GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html")); + const GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html")); + + // 1) Navigate to A. + EXPECT_TRUE(NavigateToURL(shell(), url_a)); + auto* rfh = current_frame_host(); + int process_id = rfh->GetProcess()->GetID(); + int frame_routing_id = rfh->GetRoutingID(); + + // 2) Invoke PermissionService. + EXPECT_TRUE(ExecJs(rfh, R"( + navigator.permissions.query({ name: "geolocation" }) + )")); + + // 3) Navigate to B. + EXPECT_TRUE(NavigateToURL(shell(), url_b)); + + // 4) Check that back-forward cache is disabled for A. + EXPECT_TRUE(tester.IsDisabledForFrameWithReason(process_id, frame_routing_id, + "PermissionServiceContext")); +} + IN_PROC_BROWSER_TEST_F(BackForwardCacheBrowserTest, SetsThemeColorWhenRestoredFromCache) { ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc index b2759ee9..81209f6 100644 --- a/content/browser/frame_host/navigation_request.cc +++ b/content/browser/frame_host/navigation_request.cc
@@ -1303,8 +1303,7 @@ modified_request_headers_.Clear(); removed_request_headers_.clear(); - // TODO(zetamoo): Refactor NavigationThrottleRunner to accept one argument. - throttle_runner_ = base::WrapUnique(new NavigationThrottleRunner(this, this)); + throttle_runner_ = base::WrapUnique(new NavigationThrottleRunner(this)); #if defined(OS_ANDROID) navigation_handle_proxy_ = std::make_unique<NavigationHandleProxy>(this); @@ -1823,8 +1822,7 @@ } // https://mikewest.github.io/corpp/#process-navigation-response - if (base::FeatureList::IsEnabled( - network::features::kCrossOriginEmbedderPolicy) && + if (base::FeatureList::IsEnabled(network::features::kCrossOriginIsolation) && render_frame_host_) { auto cross_origin_embedder_policy = network::mojom::CrossOriginEmbedderPolicy::kNone;
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h index 7ee3b27..f3e8b9b 100644 --- a/content/browser/frame_host/navigation_request.h +++ b/content/browser/frame_host/navigation_request.h
@@ -72,10 +72,11 @@ // ResourceDispatcherHost (that lives on the IO thread). // TODO(clamy): Describe the interactions between the UI and IO thread during // the navigation following its refactoring. -class CONTENT_EXPORT NavigationRequest : public NavigationHandle, - public NavigationURLLoaderDelegate, - NavigationThrottleRunner::Delegate, - private RenderProcessHostObserver { +class CONTENT_EXPORT NavigationRequest + : public NavigationHandle, + public NavigationURLLoaderDelegate, + public NavigationThrottleRunner::Delegate, + private RenderProcessHostObserver { public: // Keeps track of the various stages of a NavigationRequest. enum NavigationState {
diff --git a/content/browser/frame_host/navigation_throttle_runner.cc b/content/browser/frame_host/navigation_throttle_runner.cc index 972ba307..f426a33 100644 --- a/content/browser/frame_host/navigation_throttle_runner.cc +++ b/content/browser/frame_host/navigation_throttle_runner.cc
@@ -58,9 +58,8 @@ } // namespace -NavigationThrottleRunner::NavigationThrottleRunner(Delegate* delegate, - NavigationHandle* handle) - : delegate_(delegate), handle_(handle) {} +NavigationThrottleRunner::NavigationThrottleRunner(Delegate* delegate) + : delegate_(delegate) {} NavigationThrottleRunner::~NavigationThrottleRunner() = default; @@ -91,43 +90,48 @@ std::vector<std::unique_ptr<NavigationThrottle>> testing_throttles = std::move(throttles_); - throttles_ = NavigationRequest::From(handle_) - ->GetDelegate() - ->CreateThrottlesForNavigation(handle_); + // The NavigationRequest associated with the NavigationThrottles this + // NavigationThrottleRunner manages. + // Unit tests that do not use NavigationRequest should never call + // RegisterNavigationThrottles as this function expects |delegate_| to be a + // NavigationRequest. + NavigationRequest* request = static_cast<NavigationRequest*>(delegate_); + + throttles_ = request->GetDelegate()->CreateThrottlesForNavigation(request); // Enforce rules for WebUI navigations. - AddThrottle(WebUINavigationThrottle::CreateThrottleForNavigation(handle_)); + AddThrottle(WebUINavigationThrottle::CreateThrottleForNavigation(request)); // Check for renderer-inititated main frame navigations to blocked URL schemes // (data, filesystem). This is done early as it may block the main frame // navigation altogether. AddThrottle( - BlockedSchemeNavigationThrottle::CreateThrottleForNavigation(handle_)); + BlockedSchemeNavigationThrottle::CreateThrottleForNavigation(request)); - AddThrottle(AncestorThrottle::MaybeCreateThrottleFor(handle_)); - AddThrottle(FormSubmissionThrottle::MaybeCreateThrottleFor(handle_)); + AddThrottle(AncestorThrottle::MaybeCreateThrottleFor(request)); + AddThrottle(FormSubmissionThrottle::MaybeCreateThrottleFor(request)); // Check for mixed content. This is done after the AncestorThrottle and the // FormSubmissionThrottle so that when folks block mixed content with a CSP // policy, they don't get a warning. They'll still get a warning in the // console about CSP blocking the load. AddThrottle( - MixedContentNavigationThrottle::CreateThrottleForNavigation(handle_)); + MixedContentNavigationThrottle::CreateThrottleForNavigation(request)); // Handle Origin Policy (if enabled) - AddThrottle(OriginPolicyThrottle::MaybeCreateThrottleFor(handle_)); + AddThrottle(OriginPolicyThrottle::MaybeCreateThrottleFor(request)); // Block certain requests that are not permitted for portals. - AddThrottle(PortalNavigationThrottle::MaybeCreateThrottleFor(handle_)); + AddThrottle(PortalNavigationThrottle::MaybeCreateThrottleFor(request)); for (auto& throttle : - devtools_instrumentation::CreateNavigationThrottles(handle_)) { + devtools_instrumentation::CreateNavigationThrottles(request)) { AddThrottle(std::move(throttle)); } // Delay navigation for an ablation study (if needed). AddThrottle(HistoryNavigationAblationStudyNavigationThrottle:: - MaybeCreateForNavigation(handle_)); + MaybeCreateForNavigation(request)); // Insert all testing NavigationThrottles last. throttles_.insert(throttles_.end(), @@ -161,7 +165,7 @@ return; } TRACE_EVENT_ASYNC_STEP_INTO0( - "navigation", "NavigationHandle", handle_, + "navigation", "NavigationHandle", delegate_, base::StringPrintf("%s: %s: %d", GetEventName(current_event_), throttles_[i]->GetNameForLogging(), result.action()));
diff --git a/content/browser/frame_host/navigation_throttle_runner.h b/content/browser/frame_host/navigation_throttle_runner.h index fc388d82..b4772a45 100644 --- a/content/browser/frame_host/navigation_throttle_runner.h +++ b/content/browser/frame_host/navigation_throttle_runner.h
@@ -36,7 +36,7 @@ NavigationThrottle::ThrottleCheckResult result) = 0; }; - NavigationThrottleRunner(Delegate* delegate, NavigationHandle* handle); + NavigationThrottleRunner(Delegate* delegate); ~NavigationThrottleRunner(); // Will call the appropriate NavigationThrottle function based on |event| on @@ -70,14 +70,6 @@ Delegate* delegate_; - // The NavigationHandle associated with the NavigationThrottles this - // NavigationThrottleRunner manages. - // Note: |handle_| is not defined as a NavigationRequest* so that a - // MockNavigationHandle can be used in unit_tests. Unit tests that use a - // MockNavigationHandle should never call RegisterNavigationThrottles as this - // function expects |handle_| to be a NavigationRequest instead. - NavigationHandle* handle_; - // A list of Throttles registered for this navigation. std::vector<std::unique_ptr<NavigationThrottle>> throttles_;
diff --git a/content/browser/frame_host/navigation_throttle_runner_unittest.cc b/content/browser/frame_host/navigation_throttle_runner_unittest.cc index 01e6492..fc86076 100644 --- a/content/browser/frame_host/navigation_throttle_runner_unittest.cc +++ b/content/browser/frame_host/navigation_throttle_runner_unittest.cc
@@ -60,7 +60,7 @@ void SetUp() override { RenderViewHostTestHarness::SetUp(); - runner_ = std::make_unique<NavigationThrottleRunner>(this, &handle_); + runner_ = std::make_unique<NavigationThrottleRunner>(this); } void Resume() { runner_->CallResumeForTesting(); }
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc index 311644f..c7c0091 100644 --- a/content/browser/frame_host/render_frame_host_impl.cc +++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -2352,12 +2352,13 @@ return top_document_url; } -void RenderFrameHostImpl::SetOriginOfNewFrame( +void RenderFrameHostImpl::SetOriginAndNetworkIsolationKeyOfNewFrame( const url::Origin& new_frame_creator) { // This method should only be called for *new* frames, that haven't committed // a navigation yet. DCHECK(!has_committed_any_navigation_); DCHECK(GetLastCommittedOrigin().opaque()); + DCHECK(network_isolation_key_.IsEmpty()); // Calculate and set |new_frame_origin|. bool new_frame_should_be_sandboxed = @@ -2367,6 +2368,8 @@ url::Origin new_frame_origin = new_frame_should_be_sandboxed ? new_frame_creator.DeriveNewOpaqueOrigin() : new_frame_creator; + network_isolation_key_ = net::NetworkIsolationKey( + ComputeTopFrameOrigin(new_frame_origin), new_frame_origin); SetLastCommittedOrigin(new_frame_origin); } @@ -2391,9 +2394,11 @@ frame_tree_node_->render_manager()->CreateProxiesForChildFrame(child.get()); // When the child is added, it hasn't committed any navigation yet - its - // initial empty document should inherit the origin of its parent (the origin - // may change after the first commit). See also https://crbug.com/932067. - child->current_frame_host()->SetOriginOfNewFrame(GetLastCommittedOrigin()); + // initial empty document should inherit the origin and network isolation key + // of its parent (the origin may change after the first commit). See also + // https://crbug.com/932067. + child->current_frame_host()->SetOriginAndNetworkIsolationKeyOfNewFrame( + GetLastCommittedOrigin()); children_.push_back(std::move(child)); return children_.back().get(); @@ -4369,14 +4374,16 @@ RenderFrameHostImpl* main_frame = new_window->GetMainFrame(); // When the popup is created, it hasn't committed any navigation yet - its - // initial empty document should inherit the origin of its opener (the origin - // may change after the first commit). See also https://crbug.com/932067. + // initial empty document should inherit the origin and network isolation key + // of its opener (the origin may change after the first commit). See also + // https://crbug.com/932067. // // Note that that origin of the new frame might depend on sandbox flags. // Checking sandbox flags of the new frame should be safe at this point, // because the flags should be already inherited by the CreateNewWindow call // above. - main_frame->SetOriginOfNewFrame(GetLastCommittedOrigin()); + main_frame->SetOriginAndNetworkIsolationKeyOfNewFrame( + GetLastCommittedOrigin()); if (main_frame->waiting_for_init_) { // Need to check |waiting_for_init_| as some paths inside CreateNewWindow @@ -5303,6 +5310,7 @@ network_isolation_key_ = net::NetworkIsolationKey( ComputeTopFrameOrigin(frame_origin), frame_origin); } + DCHECK(network_isolation_key_.IsFullyPopulated()); std::unique_ptr<blink::URLLoaderFactoryBundleInfo> subresource_loader_factories;
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h index 6665ae1f..f8924d67 100644 --- a/content/browser/frame_host/render_frame_host_impl.h +++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -1730,10 +1730,12 @@ // Update this frame's last committed origin. void SetLastCommittedOrigin(const url::Origin& origin); - // Set the |last_committed_origin_| of |this| frame, inheriting the origin - // from |new_frame_creator| as appropriate (e.g. depending on whether |this| - // frame should be sandboxed / should have an opaque origin instead). - void SetOriginOfNewFrame(const url::Origin& new_frame_creator); + // Set the |last_committed_origin_| and |network_isolation_key_| of |this| + // frame, inheriting the origin from |new_frame_creator| as appropriate + // (e.g. depending on whether |this| frame should be sandboxed / should have + // an opaque origin instead). + void SetOriginAndNetworkIsolationKeyOfNewFrame( + const url::Origin& new_frame_creator); // Called when a navigation commits succesfully to |url|. This will update // |last_committed_site_url_| with the site URL corresponding to |url|. @@ -2462,7 +2464,9 @@ // Network isolation key to be used for subresources from the currently // committed navigation. This is specific to a document and should be reset on - // every document commit. + // every cross-document commit. When a new frame is created, the new frame + // inherits the network isolation key from the creator frame, similarly to the + // last committed origin. net::NetworkIsolationKey network_isolation_key_; // Hold onto hashes of the last |kMaxCookieSameSiteDeprecationUrls| cookie
diff --git a/content/browser/frame_host/render_frame_host_impl_browsertest.cc b/content/browser/frame_host/render_frame_host_impl_browsertest.cc index 8f7ee167..04a8a76f5 100644 --- a/content/browser/frame_host/render_frame_host_impl_browsertest.cc +++ b/content/browser/frame_host/render_frame_host_impl_browsertest.cc
@@ -1852,6 +1852,151 @@ EXPECT_EQ(url::Origin::Create(kMainFrameURL), child->current_origin()); } +namespace { +void CheckURLOriginAndNetworkIsolationKey( + FrameTreeNode* node, + GURL url, + url::Origin origin, + net::NetworkIsolationKey network_isolation_key) { + EXPECT_EQ(url, node->current_url()); + EXPECT_EQ(origin, node->current_origin()); + EXPECT_EQ(network_isolation_key, + node->current_frame_host()->network_isolation_key()); +} +} // namespace + +IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, + NetworkIsolationKeyInitialEmptyDocumentIframe) { + GURL main_frame_url(embedded_test_server()->GetURL("/title1.html")); + url::Origin main_frame_origin = url::Origin::Create(main_frame_url); + net::NetworkIsolationKey expected_main_frame_key = + net::NetworkIsolationKey(main_frame_origin, main_frame_origin); + + GURL subframe_url_one("about:blank"); + GURL subframe_url_two("about:blank#foo"); + GURL subframe_url_three( + embedded_test_server()->GetURL("foo.com", "/title2.html")); + url::Origin subframe_origin_three = url::Origin::Create(subframe_url_three); + net::NetworkIsolationKey expected_subframe_key_three = + net::NetworkIsolationKey(main_frame_origin, subframe_origin_three); + + // Main frame navigation. + ASSERT_TRUE(NavigateToURL(shell(), main_frame_url)); + + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetFrameTree() + ->root(); + CheckURLOriginAndNetworkIsolationKey(root, main_frame_url, main_frame_origin, + expected_main_frame_key); + + // Create iframe. + ASSERT_TRUE(ExecuteScript(shell(), R"( + var f = document.createElement('iframe'); + f.id = 'myiframe'; + document.body.append(f); + )")); + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + + ASSERT_EQ(1u, root->child_count()); + FrameTreeNode* child = root->child_at(0u); + CheckURLOriginAndNetworkIsolationKey( + child, subframe_url_one, main_frame_origin, expected_main_frame_key); + EXPECT_EQ(root->current_frame_host()->GetProcess(), + child->current_frame_host()->GetProcess()); + + // Same-document navigation of iframe. + ASSERT_TRUE(ExecuteScript(shell(), R"( + let iframe = document.querySelector('#myiframe'); + iframe.contentWindow.location.hash = 'foo'; + )")); + + EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); + + CheckURLOriginAndNetworkIsolationKey( + child, subframe_url_two, main_frame_origin, expected_main_frame_key); + EXPECT_EQ(root->current_frame_host()->GetProcess(), + child->current_frame_host()->GetProcess()); + + // Cross-document navigation of iframe. + TestFrameNavigationObserver commit_observer(child->current_frame_host()); + std::string subframe_script_three = JsReplace( + "iframe = document.querySelector('#myiframe');" + "iframe.contentWindow.location.href = $1;", + subframe_url_three); + ASSERT_TRUE(ExecuteScript(shell(), subframe_script_three)); + commit_observer.WaitForCommit(); + + CheckURLOriginAndNetworkIsolationKey(child, subframe_url_three, + subframe_origin_three, + expected_subframe_key_three); + if (AreAllSitesIsolatedForTesting()) { + EXPECT_NE(root->current_frame_host()->GetProcess(), + child->current_frame_host()->GetProcess()); + } +} + +IN_PROC_BROWSER_TEST_F(RenderFrameHostImplBrowserTest, + NetworkIsolationKeyInitialEmptyDocumentPopup) { + GURL main_frame_url(embedded_test_server()->GetURL("/title1.html")); + url::Origin main_frame_origin = url::Origin::Create(main_frame_url); + net::NetworkIsolationKey expected_main_frame_key = + net::NetworkIsolationKey(main_frame_origin, main_frame_origin); + + GURL popup_url_one("about:blank"); + GURL popup_url_two("about:blank#foo"); + GURL popup_url_three( + embedded_test_server()->GetURL("foo.com", "/title2.html")); + url::Origin popup_origin_three = url::Origin::Create(popup_url_three); + net::NetworkIsolationKey expected_popup_key_three = + net::NetworkIsolationKey(popup_origin_three, popup_origin_three); + + // Main frame navigation. + ASSERT_TRUE(NavigateToURL(shell(), main_frame_url)); + + FrameTreeNode* root = static_cast<WebContentsImpl*>(shell()->web_contents()) + ->GetFrameTree() + ->root(); + CheckURLOriginAndNetworkIsolationKey(root, main_frame_url, main_frame_origin, + expected_main_frame_key); + + // Create popup. + WebContentsAddedObserver popup_observer; + ASSERT_TRUE(ExecuteScript(shell(), "var w = window.open();")); + WebContents* popup = popup_observer.GetWebContents(); + + FrameTreeNode* popup_frame = + static_cast<RenderFrameHostImpl*>(popup->GetMainFrame()) + ->frame_tree_node(); + CheckURLOriginAndNetworkIsolationKey( + popup_frame, popup_url_one, main_frame_origin, expected_main_frame_key); + EXPECT_EQ(root->current_frame_host()->GetProcess(), + popup_frame->current_frame_host()->GetProcess()); + + // Same-document navigation of popup. + ASSERT_TRUE(ExecuteScript(shell(), "w.location.hash = 'foo';")); + EXPECT_TRUE(WaitForLoadStop(popup)); + + CheckURLOriginAndNetworkIsolationKey( + popup_frame, popup_url_two, main_frame_origin, expected_main_frame_key); + EXPECT_EQ(root->current_frame_host()->GetProcess(), + popup_frame->current_frame_host()->GetProcess()); + + // Cross-document navigation of popup. + TestFrameNavigationObserver commit_observer( + popup_frame->current_frame_host()); + ASSERT_TRUE(ExecuteScript( + shell(), JsReplace("w.location.href = $1;", popup_url_three))); + commit_observer.WaitForCommit(); + + CheckURLOriginAndNetworkIsolationKey(popup_frame, popup_url_three, + popup_origin_three, + expected_popup_key_three); + if (AreAllSitesIsolatedForTesting()) { + EXPECT_NE(root->current_frame_host()->GetProcess(), + popup_frame->current_frame_host()->GetProcess()); + } +} + // Verify that if the UMA histograms are correctly recording if interface // provider requests are getting dropped because they racily arrive from the // previously active document (after the next navigation already committed).
diff --git a/content/browser/permissions/permission_service_context.cc b/content/browser/permissions/permission_service_context.cc index c3ab8129..d41f739 100644 --- a/content/browser/permissions/permission_service_context.cc +++ b/content/browser/permissions/permission_service_context.cc
@@ -9,6 +9,7 @@ #include "base/bind.h" #include "content/browser/permissions/permission_controller_impl.h" #include "content/browser/permissions/permission_service_impl.h" +#include "content/public/browser/back_forward_cache.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/permission_controller.h" @@ -149,6 +150,14 @@ if (render_frame_host != render_frame_host_) return; + if (!services_.empty() || !subscriptions_.empty()) { + // |services_| and |subscriptions_| are destroyed here, so the page + // functionality might be broken if we restore the page from back-forward + // cache. Disable back-forward cache for this frame to ensure that this + // would not happen. + content::BackForwardCache::DisableForRenderFrameHost( + render_frame_host_, "PermissionServiceContext"); + } services_.Clear(); subscriptions_.clear(); }
diff --git a/content/browser/site_per_process_hit_test_browsertest.cc b/content/browser/site_per_process_hit_test_browsertest.cc index 24f6c1c..b00ee2c 100644 --- a/content/browser/site_per_process_hit_test_browsertest.cc +++ b/content/browser/site_per_process_hit_test_browsertest.cc
@@ -5598,9 +5598,8 @@ EXPECT_NEAR(point.y(), params.y, kHitTestTolerance); } -#if defined(OS_ANDROID) || defined(OS_WIN) +#if defined(OS_ANDROID) // High DPI tests don't work properly on Android, which has fixed scale factor. -// Windows is disabled because of https://crbug.com/545547. #define MAYBE_CreateContextMenuTest DISABLED_CreateContextMenuTest #else #define MAYBE_CreateContextMenuTest CreateContextMenuTest
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index b50158e..49f725c3 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -1050,9 +1050,21 @@ return TestResourceLoadHelper(url, sub_frame, worker); } + // Loads 3p.com/script on |popup| opened from page |url| and returns whether + // the script was cached or not. + bool TestResourceLoadFromPopup(const GURL& url, const GURL& popup) { + DCHECK(popup.is_valid()); + return TestResourceLoadHelper(url, popup, GURL(), true); + } + + // Loads 3p.com/script on page |url|. If |new_frame| is valid, it is loaded + // from a new frame with that url; otherwise, it is loaded from the main + // frame. This new frame is a popup if |use_popup|; otherwise, it is a + // subframe. The load is optionally performed by |worker| if it's valid. bool TestResourceLoadHelper(const GURL& url, - const GURL& sub_frame, - const GURL& worker) { + const GURL& new_frame, + const GURL& worker, + bool use_popup = false) { DCHECK(url.is_valid()); // Clear the in-memory cache held by the current process: @@ -1063,9 +1075,6 @@ shell()->web_contents()->GetMainFrame(), "test"); EXPECT_TRUE(NavigateToURL(shell(), GetWebUIURL(kChromeUIGpuHost))); - // Observe network requests. - ResourceLoadObserver observer(shell()); - // In the case of a redirect, the observed URL will be different from // what NavigateToURL(...) expects. if (base::StartsWith(url.path(), "/redirect", base::CompareCase::SENSITIVE)) @@ -1078,11 +1087,23 @@ RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>(host_to_load_resource); - // If there is supposed to be a subframe, create it. - if (sub_frame.is_valid()) { - host_to_load_resource = CreateSubframe(sub_frame); + Shell* shell_to_observe = shell(); + + if (new_frame.is_valid()) { + // If there is supposed to be a subframe or popup, create it. + if (use_popup) { + shell_to_observe = OpenPopup(main_frame, new_frame, ""); + host_to_load_resource = + static_cast<WebContentsImpl*>(shell_to_observe->web_contents()) + ->GetMainFrame(); + } else { + host_to_load_resource = CreateSubframe(new_frame); + } } + // Observe network requests. + ResourceLoadObserver observer(shell_to_observe); + GURL resource = GenURL("3p.com", "/script"); // If there is supposed to be a worker to load this resource, create it. @@ -1104,14 +1125,16 @@ RenderFrameHostImpl* frame_host = static_cast<RenderFrameHostImpl*>(host_to_load_resource); url::Origin frame_origin; - if (sub_frame.is_empty()) { + if (new_frame.is_empty()) { frame_origin = top_frame_origin; } else { - frame_origin = url::Origin::Create(sub_frame); - // TODO(crbug.com/888079) in about:blank currently committed origin is - // different from the origin at the time of CommitNavigation. - if (!frame_origin.opaque()) { - // Modify to take redirects into account. + frame_origin = url::Origin::Create(new_frame); + if (use_popup && !frame_origin.opaque()) { + // The popup is in a new WebContents, so its top_frame_origin is also + // new unless it is blank. + top_frame_origin = frame_origin; + } else { + // Take redirects and initially empty subframes/popups into account. frame_origin = frame_host->GetLastCommittedOrigin(); } } @@ -1403,6 +1426,19 @@ // (a.com, a.com) which is already in the cache. GURL blank_url(url::kAboutBlankURL); EXPECT_TRUE(TestResourceLoad(GenURL("a.com", "/title1.html"), blank_url)); + + // Load the resource from a popup window that points to about:blank. The + // resource is cached because the resource load is using the original main + // frame's URLLoaderFactory and the original main frame's factory has the NIK + // set to (a.com, a.com) which is already in the cache. + EXPECT_TRUE( + TestResourceLoadFromPopup(GenURL("a.com", "/title1.html"), blank_url)); + + // Load the resource from a popup window that points to a new origin. The + // resource is not cached because the resource load is using a NIK set to + // (g.com, g.com). + EXPECT_FALSE(TestResourceLoadFromPopup(GenURL("a.com", "/title1.html"), + GenURL("g.com", "/title1.html"))); } IN_PROC_BROWSER_TEST_F(WebContentsSplitCacheBrowserTestDisabled,
diff --git a/content/public/browser/accessibility_tree_formatter.h b/content/public/browser/accessibility_tree_formatter.h index 21077c5..55c3c9f2 100644 --- a/content/public/browser/accessibility_tree_formatter.h +++ b/content/public/browser/accessibility_tree_formatter.h
@@ -27,6 +27,8 @@ namespace content { +class BrowserAccessibility; + class AccessibilityTestExpectationsLocator { public: // Suffix of the expectation file corresponding to html file. @@ -125,6 +127,9 @@ virtual std::unique_ptr<base::DictionaryValue> FilterAccessibilityTree( const base::DictionaryValue& dict) = 0; + // Dumps a BrowserAccessibility tree into a string. + virtual void FormatAccessibilityTree(BrowserAccessibility* root, + base::string16* contents) = 0; virtual void FormatAccessibilityTree(const base::DictionaryValue& tree_node, base::string16* contents) = 0;
diff --git a/content/public/test/browser_accessibility.h b/content/public/test/browser_accessibility.h deleted file mode 100644 index 5a85afe..0000000 --- a/content/public/test/browser_accessibility.h +++ /dev/null
@@ -1,29 +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. - -#ifndef CONTENT_PUBLIC_TEST_BROWSER_ACCESSIBILITY_H_ -#define CONTENT_PUBLIC_TEST_BROWSER_ACCESSIBILITY_H_ - -#include "ui/accessibility/platform/ax_platform_node_delegate.h" - -namespace content { - -class AccessibilityTreeFormatter; - -// A class that exposes BrowserAccessibility for testing in a controlled manner. -// Additional methods can be added to expose methods from BrowserAccessibility, -// as long as the methods do not expose non-public content/ classes. -class TestBrowserAccessibility : public ui::AXPlatformNodeDelegate { - public: - // Dumps a BrowserAccessibility tree into a string. - static void FormatAccessibilityTree(AccessibilityTreeFormatter* formatter, - TestBrowserAccessibility* root, - base::string16* contents); - - ~TestBrowserAccessibility() override; -}; - -} // namespace content - -#endif // CONTENT_PUBLIC_TEST_BROWSER_ACCESSIBILITY_H_
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index c244b17..76736796 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -89,7 +89,6 @@ #include "content/public/test/test_fileapi_operation_waiter.h" #include "content/public/test/test_launcher.h" #include "content/public/test/test_navigation_observer.h" -#include "content/test/browser_accessibility.h" #include "content/test/did_commit_navigation_interceptor.h" #include "ipc/ipc_security_test_util.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -2027,42 +2026,39 @@ return manager->SnapshotAXTreeForTesting(); } -TestBrowserAccessibility* GetRootAccessibilityNode(WebContents* web_contents) { +BrowserAccessibility* GetRootAccessibilityNode(WebContents* web_contents) { WebContentsImpl* web_contents_impl = static_cast<WebContentsImpl*>(web_contents); BrowserAccessibilityManager* manager = web_contents_impl->GetRootBrowserAccessibilityManager(); - return manager ? ToTestBrowserAccessibility(manager->GetRoot()) : nullptr; + return manager ? manager->GetRoot() : nullptr; } FindAccessibilityNodeCriteria::FindAccessibilityNodeCriteria() = default; FindAccessibilityNodeCriteria::~FindAccessibilityNodeCriteria() = default; -TestBrowserAccessibility* FindAccessibilityNode( +BrowserAccessibility* FindAccessibilityNode( WebContents* web_contents, const FindAccessibilityNodeCriteria& criteria) { - TestBrowserAccessibility* root = GetRootAccessibilityNode(web_contents); + BrowserAccessibility* root = GetRootAccessibilityNode(web_contents); CHECK(root); return FindAccessibilityNodeInSubtree(root, criteria); } -TestBrowserAccessibility* FindAccessibilityNodeInSubtree( - TestBrowserAccessibility* node, +BrowserAccessibility* FindAccessibilityNodeInSubtree( + BrowserAccessibility* node, const FindAccessibilityNodeCriteria& criteria) { - BrowserAccessibility* node_internal = FromTestBrowserAccessibility(node); if ((!criteria.name || - node_internal->GetStringAttribute(ax::mojom::StringAttribute::kName) == + node->GetStringAttribute(ax::mojom::StringAttribute::kName) == criteria.name.value()) && - (!criteria.role || node_internal->GetRole() == criteria.role.value())) { + (!criteria.role || node->GetRole() == criteria.role.value())) { return node; } - for (unsigned int i = 0; i < node_internal->PlatformChildCount(); ++i) { - TestBrowserAccessibility* child = - ToTestBrowserAccessibility(node_internal->PlatformGetChild(i)); - TestBrowserAccessibility* result = - FindAccessibilityNodeInSubtree(child, criteria); + for (unsigned int i = 0; i < node->PlatformChildCount(); ++i) { + BrowserAccessibility* result = + FindAccessibilityNodeInSubtree(node->PlatformGetChild(i), criteria); if (result) return result; } @@ -2072,7 +2068,7 @@ #if defined(OS_WIN) template <typename T> Microsoft::WRL::ComPtr<T> QueryInterfaceFromNode( - TestBrowserAccessibility* browser_accessibility) { + BrowserAccessibility* browser_accessibility) { Microsoft::WRL::ComPtr<T> result; EXPECT_HRESULT_SUCCEEDED( browser_accessibility->GetNativeViewAccessible()->QueryInterface( @@ -2082,7 +2078,7 @@ void UiaGetPropertyValueVtArrayVtUnknownValidate( PROPERTYID property_id, - TestBrowserAccessibility* target_browser_accessibility, + BrowserAccessibility* target_browser_accessibility, const std::vector<std::string>& expected_names) { ASSERT_NE(nullptr, target_browser_accessibility); @@ -3158,7 +3154,7 @@ // exposing them in the header. class EvictionStateWaiter : public DelegatedFrameHost::Observer { public: - explicit EvictionStateWaiter(DelegatedFrameHost* delegated_frame_host) + EvictionStateWaiter(DelegatedFrameHost* delegated_frame_host) : delegated_frame_host_(delegated_frame_host) { delegated_frame_host_->AddObserverForTesting(this); }
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index eeb3447..cdb6bc7 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -89,6 +89,7 @@ namespace content { +class BrowserAccessibility; class BrowserContext; struct FrameVisualProperties; class FrameTreeNode; @@ -99,7 +100,6 @@ class RenderWidgetHost; class RenderWidgetHostView; class ScopedAllowRendererCrashes; -class TestBrowserAccessibility; class WebContents; // Navigates |web_contents| to |url|, blocking until the navigation finishes. @@ -909,7 +909,7 @@ ui::AXTreeUpdate GetAccessibilityTreeSnapshot(WebContents* web_contents); // Returns the root accessibility node for the given WebContents. -TestBrowserAccessibility* GetRootAccessibilityNode(WebContents* web_contents); +BrowserAccessibility* GetRootAccessibilityNode(WebContents* web_contents); // Finds an accessibility node matching the given criteria. struct FindAccessibilityNodeCriteria { @@ -918,18 +918,18 @@ base::Optional<ax::mojom::Role> role; base::Optional<std::string> name; }; -TestBrowserAccessibility* FindAccessibilityNode( +BrowserAccessibility* FindAccessibilityNode( WebContents* web_contents, const FindAccessibilityNodeCriteria& criteria); -TestBrowserAccessibility* FindAccessibilityNodeInSubtree( - TestBrowserAccessibility* node, +BrowserAccessibility* FindAccessibilityNodeInSubtree( + BrowserAccessibility* node, const FindAccessibilityNodeCriteria& criteria); #if defined(OS_WIN) // Retrieve the specified interface from an accessibility node. template <typename T> Microsoft::WRL::ComPtr<T> QueryInterfaceFromNode( - TestBrowserAccessibility* browser_accessibility); + BrowserAccessibility* browser_accessibility); // Call GetPropertyValue with the given UIA property id with variant type // VT_ARRAY | VT_UNKNOWN on the target browser accessibility node to retrieve @@ -937,7 +937,7 @@ // automation elements with the expected names. void UiaGetPropertyValueVtArrayVtUnknownValidate( PROPERTYID property_id, - TestBrowserAccessibility* target_browser_accessibility, + BrowserAccessibility* target_browser_accessibility, const std::vector<std::string>& expected_names); #endif
diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index a2a157c..58de9ee 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc
@@ -1073,11 +1073,13 @@ return; GetChannel()->AddListenerTaskRunner( - routing_id, frame->GetTaskRunner(blink::TaskType::kInternalFreezableIPC)); + routing_id, + frame->GetTaskRunner(blink::TaskType::kInternalNavigationAssociated)); unfreezable_message_filter_->AddListenerUnfreezableTaskRunner( routing_id, - frame->GetTaskRunner(blink::TaskType::kInternalNavigationAssociated)); + frame->GetTaskRunner( + blink::TaskType::kInternalNavigationAssociatedUnfreezable)); scoped_refptr<PendingFrameCreate> create(it->second); frame->BindFrame(it->second->browser_info(), it->second->TakeFrameReceiver());
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index 950424b..f496c51 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -99,7 +99,6 @@ "../public/test/background_sync_test_util.h", "../public/test/blink_test_environment.cc", "../public/test/blink_test_environment.h", - "../public/test/browser_accessibility.h", "../public/test/browser_side_navigation_test_utils.cc", "../public/test/browser_side_navigation_test_utils.h", "../public/test/browser_task_environment.cc", @@ -233,8 +232,6 @@ "../public/test/web_contents_tester.h", "appcache_test_helper.cc", "appcache_test_helper.h", - "browser_accessibility.cc", - "browser_accessibility.h", "content_browser_sanity_checker.cc", "content_browser_sanity_checker.h", "content_test_suite.cc",
diff --git a/content/test/browser_accessibility.cc b/content/test/browser_accessibility.cc deleted file mode 100644 index 61bd0f2..0000000 --- a/content/test/browser_accessibility.cc +++ /dev/null
@@ -1,33 +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 "content/test/browser_accessibility.h" - -#include "content/browser/accessibility/accessibility_tree_formatter_base.h" - -namespace content { - -// static -void TestBrowserAccessibility::FormatAccessibilityTree( - AccessibilityTreeFormatter* formatter, - TestBrowserAccessibility* root, - base::string16* contents) { - auto* formatter_internal = - static_cast<AccessibilityTreeFormatterBase*>(formatter); - BrowserAccessibility* root_internal = FromTestBrowserAccessibility(root); - formatter_internal->FormatAccessibilityTreeForTesting(root_internal, - contents); -} - -TestBrowserAccessibility* ToTestBrowserAccessibility( - BrowserAccessibility* browser_accessibility) { - return reinterpret_cast<TestBrowserAccessibility*>(browser_accessibility); -} - -BrowserAccessibility* FromTestBrowserAccessibility( - TestBrowserAccessibility* test_browser_accessibility) { - return reinterpret_cast<BrowserAccessibility*>(test_browser_accessibility); -} - -} // namespace content
diff --git a/content/test/browser_accessibility.h b/content/test/browser_accessibility.h deleted file mode 100644 index cba2d37..0000000 --- a/content/test/browser_accessibility.h +++ /dev/null
@@ -1,23 +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. - -#ifndef CONTENT_TEST_BROWSER_ACCESSIBILITY_H_ -#define CONTENT_TEST_BROWSER_ACCESSIBILITY_H_ - -#include "content/public/test/browser_accessibility.h" - -namespace content { - -class BrowserAccessibility; - -// Helper functions that are implementation details that should not be exposed -// via content/public/test/browser_accessibility.h. -TestBrowserAccessibility* ToTestBrowserAccessibility( - BrowserAccessibility* browser_accessibility); -BrowserAccessibility* FromTestBrowserAccessibility( - TestBrowserAccessibility* test_browser_accessibility); - -} // namespace content - -#endif // CONTENT_TEST_BROWSER_ACCESSIBILITY_H_
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index 21297a3..27caa3e 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -178,31 +178,7 @@ crbug.com/974380 [ mac ] Pixel_OffscreenCanvasUnaccelerated2DGPUCompositingWorker [ Skip ] crbug.com/974383 [ mac ] Pixel_CanvasDisplayLinearRGBAccelerated2D [ Skip ] -# Fails on Intel -crbug.com/991289 [ linux skia-renderer intel ] Pixel_CSS3DBlueBox [ Skip ] - # Fails when the browser features SkiaRenderer & Vulkan are enabled on Android -crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_2DCanvasWebGL [ Failure ] -crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_BackgroundImage [ Skip ] -crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_Canvas2DRedBox [ Skip ] -crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_Canvas2DUntagged [ Skip ] -crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_CanvasDisplayLinearRGBAccelerated2D [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvas2DResizeOnWorker [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasAccelerated2D [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasAccelerated2DWorker [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasTransferAfterStyleResize [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasTransferBeforeStyleResize [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasTransferToImageBitmap [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasTransferToImageBitmapWorker [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasWebGLDefault [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasWebGLDefaultWorker [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-vulkan ] Pixel_OffscreenCanvasWebglResizeOnWorker [ Skip ] -crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_WebGLGreenTriangle_AA_Alpha [ Skip ] -crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_WebGLGreenTriangle_AA_NoAlpha [ Skip ] -crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_WebGLGreenTriangle_NoAA_Alpha [ Skip ] -crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_WebGLGreenTriangle_NoAA_NoAlpha [ Skip ] -crbug.com/969864 [ android skia-renderer use-vulkan ] Pixel_WebGLTransparentGreenTriangle_NoAlpha_ImplicitClear [ Skip ] -crbug.com/985070 [ android android-chromium skia-renderer use-vulkan qualcomm-adreno-(tm)-540 ] Pixel_CanvasLowLatencyWebGL [ Skip ] crbug.com/991289 [ android skia-renderer use-vulkan ] Pixel_CSS3DBlueBox [ Skip ] crbug.com/991291 [ android android-chromium skia-renderer use-vulkan ] Pixel_Video_Context_Loss_VP9 [ Skip ] crbug.com/991291 [ android skia-renderer use-vulkan ] Pixel_Video_MP4 [ Skip ] @@ -214,10 +190,6 @@ # Fails when the browser features SkiaRenderer & GL are enabled on Android. # The more specific matching criteria is to prevent collisions with other expectations. -crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_BackgroundImage [ Skip ] -crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_CanvasDisplayLinearRGBAccelerated2D [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-gl no-use-vulkan ] Pixel_OffscreenCanvasTransferAfterStyleResize [ Skip ] -crbug.com/969864 [ android android-chromium skia-renderer use-gl no-use-vulkan ] Pixel_OffscreenCanvasTransferBeforeStyleResize [ Skip ] crbug.com/1008456 [ android android-chromium skia-renderer use-gl no-use-vulkan ] Pixel_Video_Context_Loss_VP9 [ Skip ] crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_Video_MP4 [ Skip ] crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_Video_MP4_FourColors_Aspect_4x3 [ Skip ] @@ -225,7 +197,6 @@ crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_Video_MP4_FourColors_Rot_270 [ Skip ] crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_Video_MP4_FourColors_Rot_90 [ Skip ] crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_Video_VP9 [ Skip ] -crbug.com/969864 [ android skia-renderer use-gl no-use-vulkan ] Pixel_WebGL2_BlitFramebuffer_Result_Displayed [ Skip ] # Fails on Android SkiaRenderer, both GL and Vulkan crbug.com/1008450 [ android skia-renderer ] Pixel_Video_BackdropFilter [ Skip ]
diff --git a/google_apis/gaia/core_account_id.cc b/google_apis/gaia/core_account_id.cc index 0fc8c41..2661218 100644 --- a/google_apis/gaia/core_account_id.cc +++ b/google_apis/gaia/core_account_id.cc
@@ -22,9 +22,11 @@ CoreAccountId::CoreAccountId(const std::string& id) : id(id) {} +#if defined(OS_CHROMEOS) || defined(OS_ANDROID) CoreAccountId::operator std::string() const { return id; } +#endif bool CoreAccountId::empty() const { return id.empty();
diff --git a/google_apis/gaia/core_account_id.h b/google_apis/gaia/core_account_id.h index 0558754..886d228 100644 --- a/google_apis/gaia/core_account_id.h +++ b/google_apis/gaia/core_account_id.h
@@ -9,6 +9,8 @@ #include <string> #include <vector> +#include "build/build_config.h" + // Represent the id of an account for interaction with GAIA. It is // currently implicitly convertible to and from std::string to allow // progressive migration of the code (see https://crbug.com/959157 @@ -22,6 +24,7 @@ CoreAccountId& operator=(const CoreAccountId&); CoreAccountId& operator=(CoreAccountId&&) noexcept; +#if defined(OS_CHROMEOS) || defined(OS_ANDROID) // Those implicit constructor and conversion operator allow to // progressively migrate the code to use this struct. Removing // them is tracked by https://crbug.com/959161 @@ -29,6 +32,11 @@ CoreAccountId(std::string&& id); CoreAccountId(const std::string& id); operator std::string() const; +#else + explicit CoreAccountId(const char* id); + explicit CoreAccountId(std::string&& id); + explicit CoreAccountId(const std::string& id); +#endif // Checks if the account is valid or not. // TODO(triploblastic): Possibly rename of remove this after
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn index d9196676..6d276672 100644 --- a/gpu/command_buffer/service/BUILD.gn +++ b/gpu/command_buffer/service/BUILD.gn
@@ -374,7 +374,10 @@ } if (skia_use_dawn) { - deps += [ "//components/viz/common:dawn_context_provider" ] + deps += [ + "//components/viz/common:dawn_context_provider", + "//third_party/dawn/src/dawn:libdawn", + ] } if (is_android) {
diff --git a/gpu/command_buffer/service/service_utils.cc b/gpu/command_buffer/service/service_utils.cc index 7f62b05c..cf85ba5 100644 --- a/gpu/command_buffer/service/service_utils.cc +++ b/gpu/command_buffer/service/service_utils.cc
@@ -12,6 +12,7 @@ #include "gpu/command_buffer/service/context_group.h" #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/config/gpu_finch_features.h" +#include "skia/buildflags.h" #include "ui/gl/gl_switches.h" #include "ui/gl/gl_utils.h" @@ -179,8 +180,10 @@ << "GrContextType is Metal, but Metal is not enabled."; gpu_preferences.gr_context_type = GrContextType::kMetal; #endif +#if BUILDFLAG(SKIA_USE_DAWN) } else if (value == switches::kGrContextTypeDawn) { gpu_preferences.gr_context_type = GrContextType::kDawn; +#endif } else { NOTREACHED() << "Invalid GrContextType."; gpu_preferences.gr_context_type = GrContextType::kGL;
diff --git a/gpu/command_buffer/service/shared_image_factory.cc b/gpu/command_buffer/service/shared_image_factory.cc index 769a9d90..8d2c5e13 100644 --- a/gpu/command_buffer/service/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image_factory.cc
@@ -80,7 +80,8 @@ shared_image_manager_(shared_image_manager), memory_tracker_(std::make_unique<MemoryTypeTracker>(memory_tracker)), using_vulkan_(context_state && context_state->GrContextIsVulkan()), - using_metal_(context_state && context_state->GrContextIsMetal()) { + using_metal_(context_state && context_state->GrContextIsMetal()), + using_dawn_(context_state && context_state->GrContextIsDawn()) { bool use_gl = gl::GetGLImplementation() != gl::kGLImplementationNone; if (use_gl) { gl_backing_factory_ = std::make_unique<SharedImageBackingFactoryGLTexture>( @@ -164,13 +165,14 @@ } // Currently we only perform data uploads via two paths, - // |gl_backing_factory_| for GL and |wrapped_sk_image_factory_| for Vulkan. + // |gl_backing_factory_| for GL and |wrapped_sk_image_factory_| for Vulkan and + // Dawn. // TODO(ericrk): Make this generic in the future. bool allow_legacy_mailbox = false; SharedImageBackingFactory* factory = nullptr; if (backing_factory_for_testing_) { factory = backing_factory_for_testing_; - } else if (!using_vulkan_) { + } else if (!using_vulkan_ && !using_dawn_) { allow_legacy_mailbox = true; factory = gl_backing_factory_.get(); } else {
diff --git a/gpu/command_buffer/service/shared_image_factory.h b/gpu/command_buffer/service/shared_image_factory.h index 87ded985..5dc0255 100644 --- a/gpu/command_buffer/service/shared_image_factory.h +++ b/gpu/command_buffer/service/shared_image_factory.h
@@ -121,6 +121,7 @@ std::unique_ptr<MemoryTypeTracker> memory_tracker_; const bool using_vulkan_; const bool using_metal_; + const bool using_dawn_; // The set of SharedImages which have been created (and are being kept alive) // by this factory.
diff --git a/gpu/command_buffer/service/wrapped_sk_image.cc b/gpu/command_buffer/service/wrapped_sk_image.cc index f142405..7a05f31 100644 --- a/gpu/command_buffer/service/wrapped_sk_image.cc +++ b/gpu/command_buffer/service/wrapped_sk_image.cc
@@ -18,6 +18,7 @@ #include "gpu/command_buffer/service/shared_image_backing.h" #include "gpu/command_buffer/service/shared_image_representation.h" #include "gpu/command_buffer/service/skia_utils.h" +#include "skia/buildflags.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkSurfaceProps.h" @@ -201,6 +202,14 @@ tracing_id_ = reinterpret_cast<uint64_t>(image_info.fImage); break; } +#if BUILDFLAG(SKIA_USE_DAWN) + case GrBackendApi::kDawn: { + GrDawnImageInfo image_info; + if (backend_texture.getDawnImageInfo(&image_info)) + tracing_id_ = reinterpret_cast<uint64_t>(image_info.fTexture.Get()); + break; + } +#endif default: NOTREACHED(); return false;
diff --git a/ios/chrome/browser/crash_report/crash_restore_helper.mm b/ios/chrome/browser/crash_report/crash_restore_helper.mm index e1118f9..efa4575 100644 --- a/ios/chrome/browser/crash_report/crash_restore_helper.mm +++ b/ios/chrome/browser/crash_report/crash_restore_helper.mm
@@ -13,7 +13,7 @@ #include "components/infobars/core/infobar.h" #include "components/infobars/core/infobar_manager.h" #include "components/sessions/core/tab_restore_service.h" -#include "components/sessions/ios/ios_live_tab.h" +#include "components/sessions/ios/ios_restore_live_tab.h" #include "components/strings/grit/components_chromium_strings.h" #include "components/strings/grit/components_google_chrome_strings.h" #include "components/strings/grit/components_strings.h" @@ -326,12 +326,10 @@ web::WebState::CreateParams params(_browserState); for (CRWSessionStorage* session in sessions) { - std::unique_ptr<web::WebState> webState = - web::WebState::CreateWithStorageSession(params, session); + auto live_tab = std::make_unique<sessions::RestoreIOSLiveTab>(session); // Add all tabs at the 0 position as the position is relative to an old // tabModel. - tabRestoreService->CreateHistoricalTab( - sessions::IOSLiveTab::GetForWebState(webState.get()), 0); + tabRestoreService->CreateHistoricalTab(live_tab.get(), 0); } return; }
diff --git a/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc b/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc index c1a404d..418b641e8 100644 --- a/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc +++ b/ios/chrome/browser/dom_distiller/dom_distiller_service_factory.cc
@@ -33,10 +33,12 @@ std::unique_ptr<dom_distiller::DistillerFactory> distiller_factory, std::unique_ptr<dom_distiller::DistillerPageFactory> distiller_page_factory, - std::unique_ptr<dom_distiller::DistilledPagePrefs> distilled_page_prefs) + std::unique_ptr<dom_distiller::DistilledPagePrefs> distilled_page_prefs, + std::unique_ptr<dom_distiller::DistillerUIHandle> distiller_ui_handle) : DomDistillerService(std::move(distiller_factory), std::move(distiller_page_factory), - std::move(distilled_page_prefs)) {} + std::move(distilled_page_prefs), + std::move(distiller_ui_handle)) {} ~DomDistillerKeyedService() override {} @@ -88,7 +90,8 @@ return std::make_unique<DomDistillerKeyedService>( std::move(distiller_factory), std::move(distiller_page_factory), - std::move(distilled_page_prefs)); + std::move(distilled_page_prefs), + /* distiller_ui_handle */ nullptr); } web::BrowserState* DomDistillerServiceFactory::GetBrowserStateToUse(
diff --git a/ios/chrome/browser/signin/authentication_service.h b/ios/chrome/browser/signin/authentication_service.h index f14dc1b..17b6026 100644 --- a/ios/chrome/browser/signin/authentication_service.h +++ b/ios/chrome/browser/signin/authentication_service.h
@@ -139,7 +139,7 @@ // is only updated when the app is in foreground and used to detect // if any change occurred while the app was in background. // See HaveAccountsChangesWhileInBackground(). - std::vector<std::string> GetLastKnownAccountsFromForeground(); + std::vector<CoreAccountId> GetLastKnownAccountsFromForeground(); // Returns the cached MDM infos associated with |identity|. If the cache // is stale for |identity|, the entry might be removed. @@ -222,7 +222,7 @@ bool is_reloading_credentials_ = false; // Map between account IDs and their associated MDM error. - mutable std::map<std::string, NSDictionary*> cached_mdm_infos_; + mutable std::map<CoreAccountId, NSDictionary*> cached_mdm_infos_; ScopedObserver<ios::ChromeIdentityService, ios::ChromeIdentityService::Observer>
diff --git a/ios/chrome/browser/signin/authentication_service.mm b/ios/chrome/browser/signin/authentication_service.mm index 2fa22201..7487758 100644 --- a/ios/chrome/browser/signin/authentication_service.mm +++ b/ios/chrome/browser/signin/authentication_service.mm
@@ -54,8 +54,9 @@ constexpr char kFakeAccountIdForRemovedAccount[] = "0000000000000"; // Returns the account id associated with |identity|. -std::string ChromeIdentityToAccountID(signin::IdentityManager* identity_manager, - ChromeIdentity* identity) { +CoreAccountId ChromeIdentityToAccountID( + signin::IdentityManager* identity_manager, + ChromeIdentity* identity) { std::string gaia_id = base::SysNSStringToUTF8([identity gaiaID]); auto maybe_account = identity_manager @@ -152,7 +153,7 @@ // Clear signin errors on the accounts that had a specific MDM device status. // This will trigger services to fetch data for these accounts again. using std::swap; - std::map<std::string, NSDictionary*> cached_mdm_infos; + std::map<CoreAccountId, NSDictionary*> cached_mdm_infos; swap(cached_mdm_infos_, cached_mdm_infos); if (!cached_mdm_infos.empty()) { @@ -201,7 +202,7 @@ // Load accounts from preference before synchronizing the accounts with // the system, otherwiser we would never detect any changes to the list // of accounts. - std::vector<std::string> last_foreground_accounts = + std::vector<CoreAccountId> last_foreground_accounts = GetLastKnownAccountsFromForeground(); std::sort(last_foreground_accounts.begin(), last_foreground_accounts.end()); @@ -214,7 +215,7 @@ std::vector<CoreAccountInfo> current_accounts_info = identity_manager_->GetAccountsWithRefreshTokens(); - std::vector<std::string> current_accounts; + std::vector<CoreAccountId> current_accounts; for (const CoreAccountInfo& account_info : current_accounts_info) current_accounts.push_back(account_info.account_id); std::sort(current_accounts.begin(), current_accounts.end()); @@ -239,11 +240,11 @@ return; } - std::vector<std::string> account_ids = GetLastKnownAccountsFromForeground(); + std::vector<CoreAccountId> account_ids = GetLastKnownAccountsFromForeground(); std::vector<base::Value> accounts_pref_value; - for (const std::string& account_id : account_ids) { + for (const auto& account_id : account_ids) { if (identity_manager_->HasAccountWithRefreshToken(account_id)) { - accounts_pref_value.emplace_back(account_id); + accounts_pref_value.emplace_back(account_id.id); } else { // The account for |email| was removed since the last application cold // start. Insert |kFakeAccountIdForRemovedAccount| to ensure @@ -268,16 +269,16 @@ base::Value(std::move(accounts_pref_value))); } -std::vector<std::string> +std::vector<CoreAccountId> AuthenticationService::GetLastKnownAccountsFromForeground() { const base::Value* accounts_pref = pref_service_->GetList(prefs::kSigninLastAccounts); - std::vector<std::string> accounts; + std::vector<CoreAccountId> accounts; for (const auto& value : accounts_pref->GetList()) { DCHECK(value.is_string()); DCHECK(!value.GetString().empty()); - accounts.push_back(value.GetString()); + accounts.push_back(CoreAccountId(value.GetString())); } return accounts; }
diff --git a/ios/chrome/browser/signin/authentication_service_unittest.mm b/ios/chrome/browser/signin/authentication_service_unittest.mm index 8aa0116b..f799280 100644 --- a/ios/chrome/browser/signin/authentication_service_unittest.mm +++ b/ios/chrome/browser/signin/authentication_service_unittest.mm
@@ -65,6 +65,10 @@ ProfileSyncServiceFactory::GetForBrowserState(browser_state)); } +CoreAccountId GetAccountId(ChromeIdentity* identity) { + return CoreAccountId(base::SysNSStringToUTF8([identity gaiaID])); +} + } // namespace class AuthenticationServiceTest : public PlatformTest { @@ -112,7 +116,7 @@ authentication_service()->StoreKnownAccountsWhileInForeground(); } - std::vector<std::string> GetLastKnownAccountsFromForeground() { + std::vector<CoreAccountId> GetLastKnownAccountsFromForeground() { return authentication_service()->GetLastKnownAccountsFromForeground(); } @@ -134,14 +138,13 @@ } void SetCachedMDMInfo(ChromeIdentity* identity, NSDictionary* user_info) { - authentication_service() - ->cached_mdm_infos_[base::SysNSStringToUTF8([identity gaiaID])] = + authentication_service()->cached_mdm_infos_[GetAccountId(identity)] = user_info; } bool HasCachedMDMInfo(ChromeIdentity* identity) { return authentication_service()->cached_mdm_infos_.count( - base::SysNSStringToUTF8([identity gaiaID])) > 0; + GetAccountId(identity)) > 0; } AuthenticationService* authentication_service() { @@ -249,7 +252,7 @@ TEST_F(AuthenticationServiceTest, StoreAndGetAccountsInPrefs) { // Profile starts empty. - std::vector<std::string> accounts = GetLastKnownAccountsFromForeground(); + std::vector<CoreAccountId> accounts = GetLastKnownAccountsFromForeground(); EXPECT_TRUE(accounts.empty()); // Sign in. @@ -261,8 +264,8 @@ StoreKnownAccountsWhileInForeground(); accounts = GetLastKnownAccountsFromForeground(); ASSERT_EQ(2u, accounts.size()); - EXPECT_EQ("foo2ID", accounts[0]); - EXPECT_EQ("fooID", accounts[1]); + EXPECT_EQ(CoreAccountId("foo2ID"), accounts[0]); + EXPECT_EQ(CoreAccountId("fooID"), accounts[1]); } TEST_F(AuthenticationServiceTest, @@ -281,8 +284,8 @@ identity_manager()->GetAccountsWithRefreshTokens(); std::sort(accounts.begin(), accounts.end(), account_compare_func); ASSERT_EQ(2u, accounts.size()); - EXPECT_EQ("foo2ID", accounts[0].account_id); - EXPECT_EQ("fooID", accounts[1].account_id); + EXPECT_EQ(CoreAccountId("foo2ID"), accounts[0].account_id); + EXPECT_EQ(CoreAccountId("fooID"), accounts[1].account_id); // Simulate a switching to background and back to foreground, triggering a // credentials reload. @@ -294,9 +297,9 @@ accounts = identity_manager()->GetAccountsWithRefreshTokens(); std::sort(accounts.begin(), accounts.end(), account_compare_func); ASSERT_EQ(3u, accounts.size()); - EXPECT_EQ("foo2ID", accounts[0].account_id); - EXPECT_EQ("foo3ID", accounts[1].account_id); - EXPECT_EQ("fooID", accounts[2].account_id); + EXPECT_EQ(CoreAccountId("foo2ID"), accounts[0].account_id); + EXPECT_EQ(CoreAccountId("foo3ID"), accounts[1].account_id); + EXPECT_EQ(CoreAccountId("fooID"), accounts[2].account_id); } TEST_F(AuthenticationServiceTest, HaveAccountsChanged_Default) { @@ -429,7 +432,7 @@ GoogleServiceAuthError error( GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); signin::UpdatePersistentErrorOfRefreshTokenForAccount( - identity_manager(), base::SysNSStringToUTF8([identity(0) gaiaID]), error); + identity_manager(), GetAccountId(identity(0)), error); // MDM error for |identity_| is being cleared and the error state of refresh // token will be updated. @@ -482,7 +485,7 @@ GoogleServiceAuthError error( GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); signin::UpdatePersistentErrorOfRefreshTokenForAccount( - identity_manager(), base::SysNSStringToUTF8([identity(0) gaiaID]), error); + identity_manager(), GetAccountId(identity(0)), error); NSDictionary* user_info1 = @{ @"foo" : @1 }; ON_CALL(*identity_service(), GetMDMDeviceStatus(user_info1)) @@ -518,7 +521,7 @@ GoogleServiceAuthError error( GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); signin::UpdatePersistentErrorOfRefreshTokenForAccount( - identity_manager(), base::SysNSStringToUTF8([identity(0) gaiaID]), error); + identity_manager(), GetAccountId(identity(0)), error); NSDictionary* user_info1 = @{ @"foo" : @1 }; ON_CALL(*identity_service(), GetMDMDeviceStatus(user_info1)) @@ -576,7 +579,7 @@ GoogleServiceAuthError error( GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); signin::UpdatePersistentErrorOfRefreshTokenForAccount( - identity_manager(), base::SysNSStringToUTF8([identity(0) gaiaID]), error); + identity_manager(), GetAccountId(identity(0)), error); NSDictionary* user_info = [NSDictionary dictionary]; SetCachedMDMInfo(identity(0), user_info);
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm index e24f8db..08034bb 100644 --- a/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm +++ b/ios/chrome/browser/ui/authentication/authentication_flow_performer.mm
@@ -336,9 +336,9 @@ - (BOOL)shouldHandleMergeCaseForIdentity:(ChromeIdentity*)identity browserState: (ios::ChromeBrowserState*)browserState { - std::string lastSignedInAccountId = - browserState->GetPrefs()->GetString(prefs::kGoogleServicesLastAccountId); - std::string currentSignedInAccountId = + CoreAccountId lastSignedInAccountId( + browserState->GetPrefs()->GetString(prefs::kGoogleServicesLastAccountId)); + CoreAccountId currentSignedInAccountId = IdentityManagerFactory::GetForBrowserState(browserState) ->PickAccountIdForAccount( base::SysNSStringToUTF8([identity gaiaID]),
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 832f6888..469025fa 100644 --- a/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm +++ b/ios/chrome/browser/ui/authentication/chrome_signin_view_controller.mm
@@ -259,7 +259,7 @@ int consent_confirmation_id = showAccountsSettings ? openSettingsStringId : [self acceptSigninButtonStringId]; - std::string account_id = + CoreAccountId account_id = IdentityManagerFactory::GetForBrowserState(self.browserState) ->PickAccountIdForAccount( base::SysNSStringToUTF8([_selectedIdentity gaiaID]),
diff --git a/ios/chrome/browser/ui/browser_view/BUILD.gn b/ios/chrome/browser/ui/browser_view/BUILD.gn index c1e3bacc..2e39d51 100644 --- a/ios/chrome/browser/ui/browser_view/BUILD.gn +++ b/ios/chrome/browser/ui/browser_view/BUILD.gn
@@ -229,7 +229,6 @@ "//ios/chrome/test:block_cleanup_test", "//ios/chrome/test:test_support", "//ios/net", - "//ios/testing:ocmock_support", "//ios/web/public", "//ios/web/public/deprecated", "//ios/web/public/test",
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm index 1918b7f..a36f392 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_helper_unittest.mm
@@ -16,7 +16,6 @@ #include "ios/chrome/browser/browser_state/test_chrome_browser_state.h" #import "ios/chrome/browser/ui/toolbar/test/toolbar_test_navigation_manager.h" #import "ios/chrome/browser/ui/toolbar/test/toolbar_test_web_state.h" -#import "ios/testing/ocmock_complex_type_helper.h" #import "ios/web/public/test/fakes/test_navigation_manager.h" #import "ios/web/public/test/fakes/test_web_state.h" #include "ios/web/public/test/test_web_thread.h"
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm index 347a6c8..2fcfcdc 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
@@ -33,7 +33,6 @@ #import "ios/chrome/browser/web_state_list/web_usage_enabler/web_state_list_web_usage_enabler_factory.h" #include "ios/chrome/test/block_cleanup_test.h" #include "ios/chrome/test/ios_chrome_scoped_testing_local_state.h" -#import "ios/testing/ocmock_complex_type_helper.h" #include "ios/web/public/test/web_task_environment.h" #import "ios/web/public/web_state.h" #include "testing/gmock/include/gmock/gmock.h" @@ -53,37 +52,12 @@ notifyToolbar:(BOOL)notifyToolbar; @end -@interface BVCTestTabModel : OCMockComplexTypeHelper -- (instancetype)init NS_DESIGNATED_INITIALIZER; -@property(nonatomic, assign) ios::ChromeBrowserState* browserState; -@property(nonatomic, readonly) WebStateList* webStateList; -@end - -@implementation BVCTestTabModel { - FakeWebStateListDelegate _webStateListDelegate; - std::unique_ptr<WebStateList> _webStateList; -} - -- (instancetype)init { - if ((self = [super - initWithRepresentedObject:[OCMockObject - niceMockForClass:[TabModel class]]])) { - _webStateList = std::make_unique<WebStateList>(&_webStateListDelegate); - } - return self; -} - -- (WebStateList*)webStateList { - return _webStateList.get(); -} -@end - #pragma mark - namespace { class BrowserViewControllerTest : public BlockCleanupTest { public: - BrowserViewControllerTest() {} + BrowserViewControllerTest() : web_state_list_(&web_state_list_delegate_) {} protected: void SetUp() override { @@ -102,8 +76,13 @@ chrome_browser_state_ = test_cbs_builder.Build(); // Set up mock TabModel. - id tabModel = [[BVCTestTabModel alloc] init]; - [tabModel setBrowserState:chrome_browser_state_.get()]; + id tabModel = [OCMockObject niceMockForClass:[TabModel class]]; + OCMStub([tabModel webStateList]).andReturn(&web_state_list_); + OCMStub([tabModel browserState]) + .andReturn( + // As OCMock compare types as string, the cast is required otherwise + // it will complain that the value has an incompatible type. + static_cast<ios::ChromeBrowserState*>(chrome_browser_state_.get())); // Enable web usage for the mock TabModel's WebStateList. WebStateListWebUsageEnabler* enabler = @@ -190,6 +169,8 @@ web::WebTaskEnvironment task_environment_; IOSChromeScopedTestingLocalState local_state_; std::unique_ptr<TestChromeBrowserState> chrome_browser_state_; + FakeWebStateListDelegate web_state_list_delegate_; + WebStateList web_state_list_; TabModel* tabModel_; std::unique_ptr<Browser> browser_; BrowserViewControllerHelper* bvcHelper_;
diff --git a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm index b6343fc..30805d6a 100644 --- a/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm +++ b/ios/chrome/browser/ui/reading_list/reading_list_table_view_controller.mm
@@ -84,7 +84,6 @@ // Whether the table view is being edited by the swipe-to-delete button. @property(nonatomic, readonly, getter=isEditingWithSwipe) BOOL editingWithSwipe; // Whether to remove empty sections after editing is reset to NO. -// TODO (crbug.com/1010836): remove when dropping iOS 12. @property(nonatomic, assign) BOOL needsSectionCleanupAfterEditing; @end @@ -140,7 +139,6 @@ if (!editing) { self.editingWithToolbarButtons = NO; if (self.needsSectionCleanupAfterEditing) { - [self removeEmptySections]; self.needsSectionCleanupAfterEditing = NO; } } @@ -244,22 +242,15 @@ forRowAtIndexPath:(NSIndexPath*)indexPath { DCHECK_EQ(editingStyle, UITableViewCellEditingStyleDelete); base::RecordAction(base::UserMetricsAction("MobileReadingListDeleteEntry")); - - if (@available(iOS 13, *)) { - [self deleteItemsAtIndexPaths:@[ indexPath ] - endEditing:YES - removeEmptySections:YES]; - } else { - // On IOS 12, the UIKit animation for the swipe-to-delete gesture throws an - // exception if the section of the deleted item is removed before the - // animation is finished. To prevent this from happening, record that - // cleanup is needed and remove the section when self.tableView.editing is - // reset to NO when the animation finishes. - self.needsSectionCleanupAfterEditing = YES; - [self deleteItemsAtIndexPaths:@[ indexPath ] - endEditing:NO - removeEmptySections:NO]; - } + // The UIKit animation for the swipe-to-delete gesture throws an exception if + // the section of the deleted item is removed before the animation is + // finished. To prevent this from happening, record that cleanup is needed + // and remove the section when self.tableView.editing is reset to NO when the + // animation finishes. + self.needsSectionCleanupAfterEditing = YES; + [self deleteItemsAtIndexPaths:@[ indexPath ] + endEditing:NO + removeEmptySections:NO]; } #pragma mark - UITableViewDelegate
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn index 7f99aaab..20598217 100644 --- a/ios/web/BUILD.gn +++ b/ios/web/BUILD.gn
@@ -206,6 +206,7 @@ "//ios/web/js_messaging:unittests", "//ios/web/security:unittests", "//ios/web/session:unittests", + "//ios/web/test:packed_resources", "//ios/web/web_view:unittests", ] @@ -345,11 +346,10 @@ configs += [ "//build/config/compiler:enable_arc" ] testonly = true sources = [ - "public/test/crw_mock_web_state_delegate.h", - "public/test/crw_mock_web_state_delegate.mm", + "public/test/crw_fake_web_state_delegate.h", + "public/test/crw_fake_web_state_delegate.mm", ] deps = [ - "//ios/testing:ocmock_support", "//ios/web", ] }
diff --git a/ios/web/public/test/crw_mock_web_state_delegate.h b/ios/web/public/test/crw_fake_web_state_delegate.h similarity index 88% rename from ios/web/public/test/crw_mock_web_state_delegate.h rename to ios/web/public/test/crw_fake_web_state_delegate.h index 429e6b7..2e4df225 100644 --- a/ios/web/public/test/crw_mock_web_state_delegate.h +++ b/ios/web/public/test/crw_fake_web_state_delegate.h
@@ -2,15 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_ -#define IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_ +#ifndef IOS_WEB_PUBLIC_TEST_CRW_FAKE_WEB_STATE_DELEGATE_H_ +#define IOS_WEB_PUBLIC_TEST_CRW_FAKE_WEB_STATE_DELEGATE_H_ -#import "ios/testing/ocmock_complex_type_helper.h" #import "ios/web/public/web_state_delegate_bridge.h" // Stub implementation for CRWWebStateDelegate protocol. -@interface CRWMockWebStateDelegate - : OCMockComplexTypeHelper<CRWWebStateDelegate> +@interface CRWFakeWebStateDelegate : NSObject <CRWWebStateDelegate> + // web::WebState::OpenURLParams in |webState:openURLWithParams:| call. @property(nonatomic, readonly) const web::WebState::OpenURLParams* openURLParams; @@ -51,4 +50,4 @@ @end -#endif // IOS_WEB_PUBLIC_TEST_CRW_MOCK_WEB_STATE_DELEGATE_H_ +#endif // IOS_WEB_PUBLIC_TEST_CRW_FAKE_WEB_STATE_DELEGATE_H_
diff --git a/ios/web/public/test/crw_mock_web_state_delegate.mm b/ios/web/public/test/crw_fake_web_state_delegate.mm similarity index 97% rename from ios/web/public/test/crw_mock_web_state_delegate.mm rename to ios/web/public/test/crw_fake_web_state_delegate.mm index b99a58d..5895391 100644 --- a/ios/web/public/test/crw_mock_web_state_delegate.mm +++ b/ios/web/public/test/crw_fake_web_state_delegate.mm
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#import "ios/web/public/test/crw_mock_web_state_delegate.h" +#import "ios/web/public/test/crw_fake_web_state_delegate.h" #import "ios/web/public/ui/context_menu_params.h" #import "ios/web/public/web_state.h" @@ -11,7 +11,7 @@ #error "This file requires ARC support." #endif -@implementation CRWMockWebStateDelegate { +@implementation CRWFakeWebStateDelegate { // Backs up the property with the same name. std::unique_ptr<web::WebState::OpenURLParams> _openURLParams; // Backs up the property with the same name.
diff --git a/ios/web/web_state/web_state_delegate_bridge_unittest.mm b/ios/web/web_state/web_state_delegate_bridge_unittest.mm index 86d08f74..f5af0987 100644 --- a/ios/web/web_state/web_state_delegate_bridge_unittest.mm +++ b/ios/web/web_state/web_state_delegate_bridge_unittest.mm
@@ -10,10 +10,11 @@ #include "base/bind.h" #include "base/strings/utf_string_conversions.h" -#import "ios/web/public/test/crw_mock_web_state_delegate.h" +#import "ios/web/public/test/crw_fake_web_state_delegate.h" #import "ios/web/public/test/fakes/test_web_state.h" #import "ios/web/public/ui/context_menu_params.h" #include "testing/platform_test.h" +#import "third_party/ocmock/OCMock/OCMock.h" #import "third_party/ocmock/gtest_support.h" #include "ui/base/page_transition_types.h" @@ -25,6 +26,7 @@ // any optional methods. @interface TestEmptyWebStateDelegate : NSObject<CRWWebStateDelegate> @end + @implementation TestEmptyWebStateDelegate @end @@ -36,10 +38,7 @@ void SetUp() override { PlatformTest::SetUp(); - id originalMockDelegate = - [OCMockObject niceMockForProtocol:@protocol(CRWWebStateDelegate)]; - delegate_ = [[CRWMockWebStateDelegate alloc] - initWithRepresentedObject:originalMockDelegate]; + delegate_ = [[CRWFakeWebStateDelegate alloc] init]; empty_delegate_ = [[TestEmptyWebStateDelegate alloc] init]; bridge_.reset(new WebStateDelegateBridge(delegate_)); @@ -47,11 +46,10 @@ } void TearDown() override { - EXPECT_OCMOCK_VERIFY((OCMockObject*)delegate_); PlatformTest::TearDown(); } - CRWMockWebStateDelegate* delegate_; + CRWFakeWebStateDelegate* delegate_; id empty_delegate_; std::unique_ptr<WebStateDelegateBridge> bridge_; std::unique_ptr<WebStateDelegateBridge> empty_delegate_bridge_;
diff --git a/media/audio/virtual_audio_input_stream.cc b/media/audio/virtual_audio_input_stream.cc index 373b3c0..317fc621 100644 --- a/media/audio/virtual_audio_input_stream.cc +++ b/media/audio/virtual_audio_input_stream.cc
@@ -17,9 +17,9 @@ VirtualAudioInputStream::VirtualAudioInputStream( const AudioParameters& params, const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner, - const AfterCloseCallback& after_close_cb) + AfterCloseCallback after_close_cb) : worker_task_runner_(worker_task_runner), - after_close_cb_(after_close_cb), + after_close_cb_(std::move(after_close_cb)), callback_(NULL), params_(params), mixer_(params_, params_, false), @@ -123,9 +123,7 @@ // here. The callback is moved to a stack-local first since |this| could be // destroyed during Run(). if (after_close_cb_) { - const AfterCloseCallback cb = after_close_cb_; - after_close_cb_.Reset(); - cb.Run(this); + std::move(after_close_cb_).Run(this); } }
diff --git a/media/audio/virtual_audio_input_stream.h b/media/audio/virtual_audio_input_stream.h index aaceaa34..03e8fc33114 100644 --- a/media/audio/virtual_audio_input_stream.h +++ b/media/audio/virtual_audio_input_stream.h
@@ -34,7 +34,7 @@ class MEDIA_EXPORT VirtualAudioInputStream : public AudioInputStream { public: // Callback invoked just after VirtualAudioInputStream is closed. - typedef base::Callback<void(VirtualAudioInputStream* vais)> + typedef base::OnceCallback<void(VirtualAudioInputStream* vais)> AfterCloseCallback; // Construct a target for audio loopback which mixes multiple data streams @@ -44,7 +44,7 @@ VirtualAudioInputStream( const AudioParameters& params, const scoped_refptr<base::SingleThreadTaskRunner>& worker_task_runner, - const AfterCloseCallback& after_close_cb); + AfterCloseCallback after_close_cb); ~VirtualAudioInputStream() override;
diff --git a/media/audio/virtual_audio_output_stream.cc b/media/audio/virtual_audio_output_stream.cc index 7bba9df..2575b1c 100644 --- a/media/audio/virtual_audio_output_stream.cc +++ b/media/audio/virtual_audio_output_stream.cc
@@ -14,10 +14,14 @@ namespace media { VirtualAudioOutputStream::VirtualAudioOutputStream( - const AudioParameters& params, VirtualAudioInputStream* target, - const AfterCloseCallback& after_close_cb) - : params_(params), target_input_stream_(target), - after_close_cb_(after_close_cb), callback_(NULL), volume_(1.0f) { + const AudioParameters& params, + VirtualAudioInputStream* target, + AfterCloseCallback after_close_cb) + : params_(params), + target_input_stream_(target), + after_close_cb_(std::move(after_close_cb)), + callback_(nullptr), + volume_(1.0f) { DCHECK(params_.IsValid()); DCHECK(target); @@ -59,9 +63,7 @@ // here. The callback is moved to a stack-local first since |this| could be // destroyed during Run(). if (after_close_cb_) { - const AfterCloseCallback cb = after_close_cb_; - after_close_cb_.Reset(); - cb.Run(this); + std::move(after_close_cb_).Run(this); } }
diff --git a/media/audio/virtual_audio_output_stream.h b/media/audio/virtual_audio_output_stream.h index 706097b..57fbedf 100644 --- a/media/audio/virtual_audio_output_stream.h +++ b/media/audio/virtual_audio_output_stream.h
@@ -26,14 +26,14 @@ public AudioConverter::InputCallback { public: // Callback invoked just after VirtualAudioOutputStream is closed. - typedef base::Callback<void(VirtualAudioOutputStream* vaos)> + typedef base::OnceCallback<void(VirtualAudioOutputStream* vaos)> AfterCloseCallback; // Construct an audio loopback pathway to the given |target| (not owned). // |target| must outlive this instance. VirtualAudioOutputStream(const AudioParameters& params, VirtualAudioInputStream* target, - const AfterCloseCallback& after_close_cb); + AfterCloseCallback after_close_cb); ~VirtualAudioOutputStream() override;
diff --git a/media/audio/virtual_audio_output_stream_unittest.cc b/media/audio/virtual_audio_output_stream_unittest.cc index 320b789..0c1d424 100644 --- a/media/audio/virtual_audio_output_stream_unittest.cc +++ b/media/audio/virtual_audio_output_stream_unittest.cc
@@ -34,7 +34,7 @@ : VirtualAudioInputStream( kParams, worker_task_runner, - base::Bind(&base::DeletePointer<VirtualAudioInputStream>)) {} + base::BindOnce(&base::DeletePointer<VirtualAudioInputStream>)) {} ~MockVirtualAudioInputStream() override = default; MOCK_METHOD2(AddInputProvider, @@ -92,9 +92,8 @@ base::Unretained(input_stream))); VirtualAudioOutputStream* const output_stream = new VirtualAudioOutputStream( - kParams, - input_stream, - base::Bind(&base::DeletePointer<VirtualAudioOutputStream>)); + kParams, input_stream, + base::BindOnce(&base::DeletePointer<VirtualAudioOutputStream>)); EXPECT_CALL(*input_stream, AddInputProvider(output_stream, _)).Times(kCycles); EXPECT_CALL(*input_stream, RemoveInputProvider(output_stream, _))
diff --git a/media/capture/video/chromeos/camera_device_delegate.cc b/media/capture/video/chromeos/camera_device_delegate.cc index 2988da43..9e13371 100644 --- a/media/capture/video/chromeos/camera_device_delegate.cc +++ b/media/capture/video/chromeos/camera_device_delegate.cc
@@ -591,6 +591,8 @@ still_capture_stream->height = blob_height; still_capture_stream->format = cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_BLOB; + // Set usage flag to allow HAL adapter to identify a still capture stream. + still_capture_stream->usage = cros::mojom::GRALLOC_USAGE_STILL_CAPTURE; still_capture_stream->data_space = 0; still_capture_stream->rotation = cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0; @@ -620,6 +622,9 @@ reprocessing_stream_output->height = max_yuv_height; reprocessing_stream_output->format = cros::mojom::HalPixelFormat::HAL_PIXEL_FORMAT_YCbCr_420_888; + // Set usage flag to allow HAL adapter to identify a still capture stream. + reprocessing_stream_output->usage = + cros::mojom::GRALLOC_USAGE_STILL_CAPTURE; reprocessing_stream_output->data_space = 0; reprocessing_stream_output->rotation = cros::mojom::Camera3StreamRotation::CAMERA3_STREAM_ROTATION_0;
diff --git a/media/capture/video/chromeos/mojom/camera3.mojom b/media/capture/video/chromeos/mojom/camera3.mojom index 801ad08..15a2ab0 100644 --- a/media/capture/video/chromeos/mojom/camera3.mojom +++ b/media/capture/video/chromeos/mojom/camera3.mojom
@@ -18,6 +18,15 @@ const uint32 GRALLOC_USAGE_HW_COMPOSER = 0x00000800; const uint32 GRALLOC_USAGE_HW_CAMERA_WRITE = 0x00020000; const uint32 GRALLOC_USAGE_HW_CAMERA_READ = 0x00040000; +// A private gralloc usage flag to force allocation of YUV420 buffer. This +// usage flag is only valid when allocating HAL_PIXEL_FORMAT_YCbCr_420_888 +// flexible YUV buffers. +const uint32 GRALLOC_USAGE_FORCE_I420 = 0x10000000; +// Setting this flag means this stream is intended for still capture. We're +// using the usage flag as an indicator for an output stream that can be split +// into a new HAL request for Zero-Shutter Lag (ZSL). See crrev.com/c/1877636 +// for the CL that does the aforementioned things. +const uint32 GRALLOC_USAGE_STILL_CAPTURE = 0x20000000; [Extensible] enum HalPixelFormat {
diff --git a/media/capture/video/chromeos/request_manager.cc b/media/capture/video/chromeos/request_manager.cc index f13d089..bfee794 100644 --- a/media/capture/video/chromeos/request_manager.cc +++ b/media/capture/video/chromeos/request_manager.cc
@@ -255,6 +255,18 @@ AddOrUpdateMetadataEntry(settings, std::move(e)); } +void RequestManager::SetZeroShutterLag(cros::mojom::CameraMetadataPtr* settings, + bool enabled) { + std::vector<uint8_t> control_enable_zsl = {static_cast<uint8_t>(enabled)}; + cros::mojom::CameraMetadataEntryPtr e = + cros::mojom::CameraMetadataEntry::New(); + e->tag = cros::mojom::CameraMetadataTag::ANDROID_CONTROL_ENABLE_ZSL; + e->type = cros::mojom::EntryType::TYPE_BYTE; + e->count = 1; + e->data = control_enable_zsl; + AddOrUpdateMetadataEntry(settings, std::move(e)); +} + void RequestManager::PrepareCaptureRequest() { DCHECK(ipc_task_runner_->BelongsToCurrentThread()); @@ -441,6 +453,7 @@ *settings = std::move(take_photo_settings_queue_.front()); SetJpegOrientation(settings); } + SetZeroShutterLag(settings, true); take_photo_settings_queue_.pop(); return true; }
diff --git a/media/capture/video/chromeos/request_manager.h b/media/capture/video/chromeos/request_manager.h index 4afd5af..6efa94a 100644 --- a/media/capture/video/chromeos/request_manager.h +++ b/media/capture/video/chromeos/request_manager.h
@@ -220,6 +220,10 @@ void SetSensorTimestamp(cros::mojom::CameraMetadataPtr* settings, uint64_t shutter_timestamp); + // Puts availability of Zero Shutter Lag into the metadata. + void SetZeroShutterLag(cros::mojom::CameraMetadataPtr* settings, + bool enabled); + // Prepares a capture request by mixing repeating request with one-shot // request if it exists. If there are reprocess requests in the queue, just // build the reprocess capture request without mixing the repeating request.
diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 81cc982b..ff23df07 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc
@@ -1045,6 +1045,22 @@ stream->traffic_annotation()); } +bool SpdySession::GreasedFramesEnabled() const { + return greased_http2_frame_.has_value(); +} + +void SpdySession::EnqueueGreasedFrame(const base::WeakPtr<SpdyStream>& stream) { + if (availability_state_ == STATE_DRAINING) + return; + + EnqueueWrite( + stream->priority(), + static_cast<spdy::SpdyFrameType>(greased_http2_frame_.value().type), + std::make_unique<GreasedBufferProducer>( + stream, &greased_http2_frame_.value(), buffered_spdy_framer_.get()), + stream, stream->traffic_annotation()); +} + int SpdySession::ConfirmHandshake(CompletionOnceCallback callback) { int rv = ERR_IO_PENDING; if (!in_confirm_handshake_) { @@ -2698,6 +2714,15 @@ std::make_unique<SimpleBufferProducer>(std::move(buffer)), base::WeakPtr<SpdyStream>(), kSpdySessionCommandsTrafficAnnotation); + if (greased_http2_frame_ && frame_type == spdy::SpdyFrameType::SETTINGS) { + EnqueueWrite( + priority, + static_cast<spdy::SpdyFrameType>(greased_http2_frame_.value().type), + std::make_unique<GreasedBufferProducer>(base::WeakPtr<SpdyStream>(), + &greased_http2_frame_.value(), + buffered_spdy_framer_.get()), + base::WeakPtr<SpdyStream>(), kSpdySessionCommandsTrafficAnnotation); + } } void SpdySession::EnqueueWrite( @@ -2711,15 +2736,6 @@ write_queue_.Enqueue(priority, frame_type, std::move(producer), stream, traffic_annotation); - if (greased_http2_frame_ && (frame_type == spdy::SpdyFrameType::SETTINGS || - frame_type == spdy::SpdyFrameType::HEADERS)) { - write_queue_.Enqueue( - priority, - static_cast<spdy::SpdyFrameType>(greased_http2_frame_.value().type), - std::make_unique<GreasedBufferProducer>( - stream, &greased_http2_frame_.value(), buffered_spdy_framer_.get()), - stream, traffic_annotation); - } MaybePostWriteLoop(); }
diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h index 750e983..6e9ed3fe 100644 --- a/net/spdy/spdy_session.h +++ b/net/spdy/spdy_session.h
@@ -400,6 +400,14 @@ spdy::SpdyFrameType frame_type, std::unique_ptr<SpdyBufferProducer> producer); + // Returns true if this session is configured to send greased HTTP/2 frames. + // For more details on greased frames, see + // https://tools.ietf.org/html/draft-bishop-httpbis-grease-00. + bool GreasedFramesEnabled() const; + + // Send greased frame, that is, a frame of reserved type. + void EnqueueGreasedFrame(const base::WeakPtr<SpdyStream>& stream); + // Runs the handshake to completion to confirm the handshake with the server. // If ERR_IO_PENDING is returned, then when the handshake is confirmed, // |callback| will be called.
diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc index 9b45f47..a185381 100644 --- a/net/spdy/spdy_session_unittest.cc +++ b/net/spdy/spdy_session_unittest.cc
@@ -6004,7 +6004,7 @@ EXPECT_FALSE(session_); } -TEST_F(SpdySessionTest, GreaseFrameType) { +TEST_F(SpdySessionTest, GreaseFrameTypeAfterSettings) { const uint8_t type = 0x0b; const uint8_t flags = 0xcc; const std::string payload("foo"); @@ -6032,63 +6032,107 @@ CombineFrames({&preface, &settings_frame}); // Greased frame sent on stream 0 after initial SETTINGS frame. - const char kRawFrameData0[] = { + const char kRawFrameData[] = { 0x00, 0x00, 0x03, // length 0x0b, // type 0xcc, // flags 0x00, 0x00, 0x00, 0x00, // stream ID 'f', 'o', 'o' // payload }; - spdy::SpdySerializedFrame grease0(const_cast<char*>(kRawFrameData0), - base::size(kRawFrameData0), - /* owns_buffer = */ false); - spdy::SpdySerializedFrame req( - spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY)); - - // Greased frame sent on stream 1 after request. - const char kRawFrameData1[] = { - 0x00, 0x00, 0x03, // length - 0x0b, // type - 0xcc, // flags - 0x00, 0x00, 0x00, 0x01, // stream ID - 'f', 'o', 'o' // payload - }; - spdy::SpdySerializedFrame grease1(const_cast<char*>(kRawFrameData1), - base::size(kRawFrameData1), - /* owns_buffer = */ false); + spdy::SpdySerializedFrame grease(const_cast<char*>(kRawFrameData), + base::size(kRawFrameData), + /* owns_buffer = */ false); MockWrite writes[] = {CreateMockWrite(combined_frame, 0), - CreateMockWrite(grease0, 1), CreateMockWrite(req, 2), - CreateMockWrite(grease1, 3)}; + CreateMockWrite(grease, 1)}; - spdy::SpdySerializedFrame resp( - spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); - spdy::SpdySerializedFrame body(spdy_util_.ConstructSpdyDataFrame(1, true)); - - MockRead reads[] = {CreateMockRead(resp, 4), CreateMockRead(body, 5), - MockRead(ASYNC, 0, 6)}; + MockRead reads[] = {MockRead(ASYNC, 0, 2)}; SequencedSocketData data(reads, writes); session_deps_.socket_factory->AddSocketDataProvider(&data); AddSSLSocketData(); - CreateNetworkSession(); SpdySessionPoolPeer pool_peer(spdy_session_pool_); pool_peer.SetEnableSendingInitialData(true); CreateSpdySession(); + base::RunLoop().RunUntilIdle(); - base::WeakPtr<SpdyStream> stream = CreateStreamSynchronously( + EXPECT_TRUE(data.AllWriteDataConsumed()); + EXPECT_TRUE(data.AllReadDataConsumed()); +} + +TEST_F(SpdySessionTest, GreaseFrameTypeOnRequestStream) { + const uint8_t type = 0x0b; + const uint8_t flags = 0xcc; + const std::string payload("foo"); + session_deps_.greased_http2_frame = + base::Optional<net::SpdySessionPool::GreasedHttp2Frame>( + {type, flags, payload}); + + // No greased frame is sent after a HEADERS frame with END_STREAM set. + spdy::SpdySerializedFrame req1( + spdy_util_.ConstructSpdyGet(nullptr, 0, 1, DEFAULT_PRIORITY)); + + // A greased frame is sent between the HEADERS and the DATA frame. + spdy::SpdySerializedFrame req2(spdy_util_.ConstructSpdyPost( + kDefaultUrl, 3, kBodyDataSize, LOWEST, nullptr, 0)); + const char kRawFrameData[] = { + 0x00, 0x00, 0x03, // length + 0x0b, // type + 0xcc, // flags + 0x00, 0x00, 0x00, 0x03, // stream ID + 'f', 'o', 'o' // payload + }; + spdy::SpdySerializedFrame grease(const_cast<char*>(kRawFrameData), + base::size(kRawFrameData), + /* owns_buffer = */ false); + spdy::SpdySerializedFrame request_body( + spdy_util_.ConstructSpdyDataFrame(3, kBodyDataStringPiece, true)); + + MockWrite writes[] = {CreateMockWrite(req1, 0), CreateMockWrite(req2, 1), + CreateMockWrite(grease, 2), + CreateMockWrite(request_body, 3)}; + + spdy::SpdySerializedFrame resp1( + spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); + spdy::SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true)); + spdy::SpdySerializedFrame resp2( + spdy_util_.ConstructSpdyGetReply(nullptr, 0, 3)); + spdy::SpdySerializedFrame body2(spdy_util_.ConstructSpdyDataFrame(3, true)); + + MockRead reads[] = {CreateMockRead(resp1, 4), CreateMockRead(body1, 5), + CreateMockRead(resp2, 6), CreateMockRead(body2, 7), + MockRead(ASYNC, 0, 8)}; + + SequencedSocketData data(reads, writes); + session_deps_.socket_factory->AddSocketDataProvider(&data); + AddSSLSocketData(); + CreateNetworkSession(); + CreateSpdySession(); + + base::WeakPtr<SpdyStream> stream1 = CreateStreamSynchronously( SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, DEFAULT_PRIORITY, NetLogWithSource()); - test::StreamDelegateDoNothing delegate(stream); - stream->SetDelegate(&delegate); + test::StreamDelegateDoNothing delegate1(stream1); + stream1->SetDelegate(&delegate1); - stream->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl), - NO_MORE_DATA_TO_SEND); + stream1->SendRequestHeaders(spdy_util_.ConstructGetHeaderBlock(kDefaultUrl), + NO_MORE_DATA_TO_SEND); - EXPECT_THAT(delegate.WaitForClose(), IsOk()); + base::WeakPtr<SpdyStream> stream2 = CreateStreamSynchronously( + SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, DEFAULT_PRIORITY, + NetLogWithSource()); + test::StreamDelegateWithBody delegate2(stream2, kBodyDataStringPiece); + stream2->SetDelegate(&delegate2); + + stream2->SendRequestHeaders( + spdy_util_.ConstructPostHeaderBlock(kDefaultUrl, kBodyDataSize), + MORE_DATA_TO_SEND); + + EXPECT_THAT(delegate1.WaitForClose(), IsOk()); + EXPECT_THAT(delegate2.WaitForClose(), IsOk()); base::RunLoop().RunUntilIdle();
diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc index 8df8a74d..3cc8b2e6 100644 --- a/net/spdy/spdy_stream.cc +++ b/net/spdy/spdy_stream.cc
@@ -867,6 +867,10 @@ &SpdyStream::OnWriteBufferConsumed, GetWeakPtr(), payload_size)); } + if (session_->GreasedFramesEnabled()) { + session_->EnqueueGreasedFrame(GetWeakPtr()); + } + session_->EnqueueStreamWrite( GetWeakPtr(), spdy::SpdyFrameType::DATA, std::make_unique<SimpleBufferProducer>(std::move(data_buffer)));
diff --git a/services/network/cross_origin_resource_policy.cc b/services/network/cross_origin_resource_policy.cc index 02e62e4..da99aad 100644 --- a/services/network/cross_origin_resource_policy.cc +++ b/services/network/cross_origin_resource_policy.cc
@@ -43,7 +43,7 @@ if (header_value == "same-site") return CrossOriginResourcePolicy::kSameSite; - if (base::FeatureList::IsEnabled(features::kCrossOriginEmbedderPolicy) && + if (base::FeatureList::IsEnabled(features::kCrossOriginIsolation) && header_value == "cross-origin") { return CrossOriginResourcePolicy::kCrossOrigin; } @@ -126,7 +126,7 @@ // COEP https://mikewest.github.io/corpp/#corp-check if ((policy == kNoHeader || policy == kParsingError) && embedder_policy == mojom::CrossOriginEmbedderPolicy::kRequireCorp) { - DCHECK(base::FeatureList::IsEnabled(features::kCrossOriginEmbedderPolicy)); + DCHECK(base::FeatureList::IsEnabled(features::kCrossOriginIsolation)); policy = kSameOrigin; }
diff --git a/services/network/cross_origin_resource_policy_unittest.cc b/services/network/cross_origin_resource_policy_unittest.cc index 8ac408b..f4952f2 100644 --- a/services/network/cross_origin_resource_policy_unittest.cc +++ b/services/network/cross_origin_resource_policy_unittest.cc
@@ -70,14 +70,14 @@ TEST(CrossOriginResourcePolicyTest, CrossSiteHeaderWithCOEP) { base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(features::kCrossOriginEmbedderPolicy); + feature_list.InitAndEnableFeature(features::kCrossOriginIsolation); EXPECT_EQ(CrossOriginResourcePolicy::kCrossOrigin, ParseHeader("Cross-Origin-Resource-Policy: cross-origin")); } TEST(CrossOriginResourcePolicyTest, CrossSiteHeaderWithoutCOEP) { base::test::ScopedFeatureList feature_list; - feature_list.InitAndDisableFeature(features::kCrossOriginEmbedderPolicy); + feature_list.InitAndDisableFeature(features::kCrossOriginIsolation); EXPECT_EQ(CrossOriginResourcePolicy::kParsingError, ParseHeader("Cross-Origin-Resource-Policy: cross-origin")); } @@ -125,7 +125,7 @@ TEST(CrossOriginResourcePolicyTest, WithCOEP) { base::test::ScopedFeatureList feature_list; - feature_list.InitAndEnableFeature(features::kCrossOriginEmbedderPolicy); + feature_list.InitAndEnableFeature(features::kCrossOriginIsolation); ResourceResponseInfo corp_none; ResourceResponseInfo corp_same_origin;
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc index bc9a4bb..f1153a9b 100644 --- a/services/network/public/cpp/features.cc +++ b/services/network/public/cpp/features.cc
@@ -96,9 +96,12 @@ "ProactivelyThrottleLowPriorityRequests", base::FEATURE_DISABLED_BY_DEFAULT}; +// This is for Cross-Origin-Opener-Policy (COOP) and +// Cross-Origin-Embedder-Policy (COEP). +// https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e // https://github.com/mikewest/corpp -const base::Feature kCrossOriginEmbedderPolicy{ - "CrossOriginEmbedderPolicy", base::FEATURE_DISABLED_BY_DEFAULT}; +const base::Feature kCrossOriginIsolation{"CrossOriginIsolation", + base::FEATURE_DISABLED_BY_DEFAULT}; // When kBlockNonSecureExternalRequests is enabled, requests initiated from a // pubic network may only target a private network if the initiating context
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h index 87fc8bf..4cb8acf8 100644 --- a/services/network/public/cpp/features.h +++ b/services/network/public/cpp/features.h
@@ -41,7 +41,7 @@ COMPONENT_EXPORT(NETWORK_CPP) extern const base::Feature kProactivelyThrottleLowPriorityRequests; COMPONENT_EXPORT(NETWORK_CPP) -extern const base::Feature kCrossOriginEmbedderPolicy; +extern const base::Feature kCrossOriginIsolation; COMPONENT_EXPORT(NETWORK_CPP) extern const base::Feature kBlockNonSecureExternalRequests; COMPONENT_EXPORT(NETWORK_CPP)
diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 99da57ad..83f7628 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn
@@ -497,6 +497,7 @@ "//third_party/libwebp:libwebp_webp", ] public_deps = [ + ":buildflags", ":skia_core_and_effects", ] if (skia_use_dawn) {
diff --git a/testing/buildbot/chromium.gpu.fyi.json b/testing/buildbot/chromium.gpu.fyi.json index f479590..34dae91 100644 --- a/testing/buildbot/chromium.gpu.fyi.json +++ b/testing/buildbot/chromium.gpu.fyi.json
@@ -6752,6 +6752,7 @@ { "args": [ "--use-vulkan=native", + "--gr-context-type=vulkan", "--disable-vulkan-fallback-to-gl-for-testing", "--enable-features=UseSkiaRenderer", "--test-launcher-filter-file=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_content_browsertests.filter",
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index de79137..62828bc 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -3862,6 +3862,7 @@ 'vulkan_content_browsertests': { 'args': [ '--use-vulkan=native', + '--gr-context-type=vulkan', '--disable-vulkan-fallback-to-gl-for-testing', '--enable-features=UseSkiaRenderer', '--test-launcher-filter-file=../../testing/buildbot/filters/gpu.skiarenderer_vulkan_content_browsertests.filter',
diff --git a/third_party/blink/common/http/structured_header.cc b/third_party/blink/common/http/structured_header.cc index 6cf1ffd..329349f9 100644 --- a/third_party/blink/common/http/structured_header.cc +++ b/third_party/blink/common/http/structured_header.cc
@@ -8,6 +8,7 @@ #include <utility> #include "base/base64.h" +#include "base/containers/flat_set.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -20,38 +21,56 @@ #define LCALPHA "abcdefghijklmnopqrstuvwxyz" #define UCALPHA "ABCDEFGHIJKLMNOPQRSTUVWXYZ" // https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.9 +// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-13#section-3.7 constexpr char kTokenChars[] = DIGIT UCALPHA LCALPHA "_-.:%*/"; // https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.1 -constexpr char kKeyChars[] = DIGIT LCALPHA "_-"; +constexpr char kKeyChars09[] = DIGIT LCALPHA "_-"; +// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-13#section-3.1 +constexpr char kKeyChars13[] = DIGIT LCALPHA "_-*"; #undef DIGIT #undef LCALPHA #undef UCALPHA // https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09#section-3.8 +// https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-13#section-3.6 bool IsPrintableASCII(char c) { return ' ' <= c && c <= '~'; // 0x20 (' ') to 0x7E ('~') } -// Parser for (a subset of) Structured Headers for HTTP defined in [SH]. -// [SH] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09 +// Parser for (a subset of) Structured Headers for HTTP defined in [SH09] and +// [SH13]. [SH09] compatibility is retained for use by Web Packaging, and can be +// removed once that spec is updated, and users have migrated to new headers. +// [SH09] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-09 +// [SH13] https://tools.ietf.org/html/draft-ietf-httpbis-header-structure-13 class StructuredHeaderParser { public: - explicit StructuredHeaderParser(const base::StringPiece& str) : input_(str) { - // [SH] 4.2. Step 1. Discard any leading OWS from input_string. + enum DraftVersion { + kDraft09, + kDraft13, + }; + explicit StructuredHeaderParser(const base::StringPiece& str, + DraftVersion version) + : input_(str), version_(version) { + // [SH09] 4.2 Step 1. + // [SH13] 4.2 Step 2. + // Discard any leading OWS from input_string. SkipWhitespaces(); } // Callers should call this after ReadSomething(), to check if parser has // consumed all the input successfully. bool FinishParsing() { - // [SH] 4.2 Step 7. Discard any leading OWS from input_string. + // [SH09] 4.2 Step 7. [SH13] 4.2 Step 6. + // Discard any leading OWS from input_string. SkipWhitespaces(); - // [SH] 4.2 Step 8. If input_string is not empty, fail parsing. + // [SH09] 4.2 Step 8. [SH13] 4.2 Step 7. + // If input_string is not empty, fail parsing. return input_.empty(); } - // Parses a List of Lists ([SH] 4.2.4). + // Parses a List of Lists ([SH09] 4.2.4). base::Optional<ListOfLists> ReadListOfLists() { + DCHECK_EQ(version_, kDraft09); ListOfLists result; while (true) { std::vector<Item> inner_list; @@ -74,7 +93,26 @@ return result; } - // Parses an Item ([SH] 4.2.7). + // Parses a List ([SH13] 4.2.1). + base::Optional<List> ReadList() { + DCHECK_EQ(version_, kDraft13); + List members; + while (!input_.empty()) { + base::Optional<ParameterizedMember> member(ReadParameterizedMember()); + if (!member) + return base::nullopt; + members.push_back(std::move(*member)); + SkipWhitespaces(); + if (!ConsumeChar(',')) + break; + SkipWhitespaces(); + if (input_.empty()) + return base::nullopt; + } + return members; + } + + // Parses an Item ([SH09] 4.2.7, [SH13] 4.2.3). // Currently only limited types (non-negative integers, strings, tokens and // byte sequences) are supported. // TODO(1011101): Add support for other types. @@ -96,8 +134,9 @@ } } - // Parses a Parameterised List ([SH] 4.2.5). + // Parses a Parameterised List ([SH09] 4.2.5). base::Optional<ParameterisedList> ReadParameterisedList() { + DCHECK_EQ(version_, kDraft09); ParameterisedList items; while (true) { base::Optional<ParameterisedIdentifier> item = @@ -113,8 +152,9 @@ } private: - // Parses a Parameterised Identifier ([SH] 4.2.6). + // Parses a Parameterised Identifier ([SH09] 4.2.6). base::Optional<ParameterisedIdentifier> ReadParameterisedIdentifier() { + DCHECK_EQ(version_, kDraft09); base::Optional<Item> primary_identifier = ReadToken(); if (!primary_identifier) return base::nullopt; @@ -147,13 +187,84 @@ std::move(parameters)); } - // Parses a Key ([SH] 4.2.2). + // Parses a Parameterized Member ([SH13] 4.2.1.1). + base::Optional<ParameterizedMember> ReadParameterizedMember() { + DCHECK_EQ(version_, kDraft13); + std::vector<Item> member; + bool member_is_inner_list = ConsumeChar('('); + if (member_is_inner_list) { + base::Optional<std::vector<Item>> inner_list = ReadInnerList(); + if (!inner_list) + return base::nullopt; + member = std::move(*inner_list); + } else { + base::Optional<Item> item = ReadItem(); + if (!item) + return base::nullopt; + member.push_back(std::move(*item)); + } + + ParameterizedMember::Parameters parameters; + base::flat_set<std::string> keys; + + SkipWhitespaces(); + while (ConsumeChar(';')) { + SkipWhitespaces(); + + base::Optional<std::string> name = ReadKey(); + if (!name) + return base::nullopt; + bool is_duplicate_key = !keys.insert(*name).second; + if (is_duplicate_key) { + DVLOG(1) << "ReadParameterizedMember: duplicated parameter: " << *name; + return base::nullopt; + } + + Item value; + if (ConsumeChar('=')) { + auto item = ReadItem(); + if (!item) + return base::nullopt; + value = std::move(*item); + } + parameters.emplace_back(std::move(*name), std::move(value)); + SkipWhitespaces(); + } + return ParameterizedMember(std::move(member), member_is_inner_list, + std::move(parameters)); + } + + // Parses an Inner List ([SH13] 4.2.1.2). + // Note that the initial '(' character should already have been consumed by + // the caller to determine that this is in fact an inner list. + base::Optional<std::vector<Item>> ReadInnerList() { + DCHECK_EQ(version_, kDraft13); + std::vector<Item> inner_list; + while (true) { + SkipWhitespaces(); + if (ConsumeChar(')')) { + return inner_list; + } + auto item = ReadItem(); + if (!item) + return base::nullopt; + inner_list.push_back(std::move(*item)); + if (input_.empty() || (input_.front() != ' ' && input_.front() != ')')) + return base::nullopt; + } + NOTREACHED(); + return base::nullopt; + } + + // Parses a Key ([SH09] 4.2.2, [SH13] 4.2.1.3). base::Optional<std::string> ReadKey() { if (input_.empty() || !base::IsAsciiLower(input_.front())) { LogParseError("ReadKey", "lcalpha"); return base::nullopt; } - size_t len = input_.find_first_not_of(kKeyChars); + const char* allowed_chars = + (version_ == kDraft09 ? kKeyChars09 : kKeyChars13); + size_t len = input_.find_first_not_of(allowed_chars); if (len == base::StringPiece::npos) len = input_.size(); std::string key(input_.substr(0, len)); @@ -161,7 +272,7 @@ return key; } - // Parses a Token ([SH] 4.2.10). + // Parses a Token ([SH09] 4.2.10, [SH13] 4.2.6). base::Optional<Item> ReadToken() { if (input_.empty() || !base::IsAsciiAlpha(input_.front())) { LogParseError("ReadToken", "ALPHA"); @@ -175,7 +286,7 @@ return Item(std::move(token), Item::kTokenType); } - // Parses a Number ([SH] 4.2.8). + // Parses a Number ([SH09] 4.2.8, [SH13] 4.2.4). // Currently only supports non-negative integers. base::Optional<Item> ReadNumber() { size_t i = 0; @@ -198,7 +309,7 @@ return Item(n); } - // Parses a String ([SH] 4.2.9). + // Parses a String ([SH09] 4.2.9, [SH13] 4.2.5). base::Optional<Item> ReadString() { std::string s; if (!ConsumeChar('"')) { @@ -237,7 +348,7 @@ return s; } - // Parses a Byte Sequence ([SH] 4.2.11). + // Parses a Byte Sequence ([SH09] 4.2.11, [SH13] 4.2.7). base::Optional<Item> ReadByteSequence() { if (!ConsumeChar('*')) { LogParseError("ReadByteSequence", "'*'"); @@ -281,6 +392,8 @@ } base::StringPiece input_; + DraftVersion version_; + DISALLOW_COPY_AND_ASSIGN(StructuredHeaderParser); }; @@ -314,6 +427,22 @@ } } +ParameterizedMember::ParameterizedMember(const ParameterizedMember&) = default; +ParameterizedMember& ParameterizedMember::operator=( + const ParameterizedMember&) = default; +ParameterizedMember::ParameterizedMember(std::vector<Item> id, + bool member_is_inner_list, + const Parameters& ps) + : member(std::move(id)), + member_is_inner_list(member_is_inner_list), + params(ps) {} +ParameterizedMember::ParameterizedMember(std::vector<Item> id, + const Parameters& ps) + : member(std::move(id)), member_is_inner_list(true), params(ps) {} +ParameterizedMember::ParameterizedMember(Item id, const Parameters& ps) + : member({std::move(id)}), member_is_inner_list(false), params(ps) {} +ParameterizedMember::~ParameterizedMember() = default; + ParameterisedIdentifier::ParameterisedIdentifier( const ParameterisedIdentifier&) = default; ParameterisedIdentifier& ParameterisedIdentifier::operator=( @@ -323,7 +452,7 @@ ParameterisedIdentifier::~ParameterisedIdentifier() = default; base::Optional<Item> ParseItem(const base::StringPiece& str) { - StructuredHeaderParser parser(str); + StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft09); base::Optional<Item> item = parser.ReadItem(); if (item && parser.FinishParsing()) return item; @@ -332,7 +461,7 @@ base::Optional<ParameterisedList> ParseParameterisedList( const base::StringPiece& str) { - StructuredHeaderParser parser(str); + StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft09); base::Optional<ParameterisedList> param_list = parser.ReadParameterisedList(); if (param_list && parser.FinishParsing()) return param_list; @@ -340,12 +469,20 @@ } base::Optional<ListOfLists> ParseListOfLists(const base::StringPiece& str) { - StructuredHeaderParser parser(str); + StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft09); base::Optional<ListOfLists> list_of_lists = parser.ReadListOfLists(); if (list_of_lists && parser.FinishParsing()) return list_of_lists; return base::nullopt; } +base::Optional<List> ParseList(const base::StringPiece& str) { + StructuredHeaderParser parser(str, StructuredHeaderParser::kDraft13); + base::Optional<List> list = parser.ReadList(); + if (list && parser.FinishParsing()) + return list; + return base::nullopt; +} + } // namespace http_structured_header } // namespace blink
diff --git a/third_party/blink/common/http/structured_header_unittest.cc b/third_party/blink/common/http/structured_header_unittest.cc index 4e9848e..8c4598e 100644 --- a/third_party/blink/common/http/structured_header_unittest.cc +++ b/third_party/blink/common/http/structured_header_unittest.cc
@@ -10,6 +10,27 @@ namespace blink { namespace http_structured_header { +namespace { + +// Helpers to make test cases clearer + +Item Token(std::string value) { + return Item(value, Item::kTokenType); +} + +std::pair<std::string, Item> Param(std::string key) { + return std::make_pair(key, Item()); +} + +std::pair<std::string, Item> Param(std::string key, int64_t value) { + return std::make_pair(key, Item(value)); +} + +std::pair<std::string, Item> Param(std::string key, std::string value) { + return std::make_pair(key, Item(value)); +} + +} // namespace // Test cases are taken from https://github.com/httpwg/structured-header-tests. @@ -20,15 +41,12 @@ const base::Optional<Item> expected; // nullopt if parse error is expected } cases[] = { // Item - {"basic token - item", "a_b-c.d3:f%00/*", - Item("a_b-c.d3:f%00/*", Item::kTokenType)}, - {"token with capitals - item", "fooBar", - Item("fooBar", Item::kTokenType)}, - {"token starting with capitals - item", "FooBar", - Item("FooBar", Item::kTokenType)}, + {"basic token - item", "a_b-c.d3:f%00/*", Token("a_b-c.d3:f%00/*")}, + {"token with capitals - item", "fooBar", Token("fooBar")}, + {"token starting with capitals - item", "FooBar", Token("FooBar")}, {"bad token - item", "abc$%!", base::nullopt}, - {"leading whitespace", " foo", Item("foo", Item::kTokenType)}, - {"trailing whitespace", "foo ", Item("foo", Item::kTokenType)}, + {"leading whitespace", " foo", Token("foo")}, + {"trailing whitespace", "foo ", Token("foo")}, // Number {"basic integer", "42", Item(42)}, {"zero integer", "0", Item(0)}, @@ -73,16 +91,74 @@ {"abruptly ending string quote", "\"foo \\", base::nullopt}, }; for (const auto& c : cases) { + SCOPED_TRACE(c.name); base::Optional<Item> result = ParseItem(c.raw); - if (c.expected) { - EXPECT_TRUE(result.has_value()) << c.name; - EXPECT_EQ(*result, c.expected) << c.name; - } else { - EXPECT_FALSE(result.has_value()) << c.name; - } + EXPECT_EQ(result, c.expected); } } +// For Structured Headers Draft 13 +TEST(StructuredHeaderTest, ParseList) { + struct ListTestCase { + const char* name; + const char* raw; + const base::Optional<List> expected; // nullopt if parse error is expected. + } cases[] = { + // Basic lists + {"basic list", "1, 42", {{{Item(1), {}}, {Item(42), {}}}}}, + {"empty list", "", List()}, + {"single item list", "42", {{{Item(42), {}}}}}, + {"no whitespace list", "1, 42", {{{Item(1), {}}, {Item(42), {}}}}}, + {"trailing comma list", "1, 42,", base::nullopt}, + {"empty item list", "1,,42", base::nullopt}, + // Lists of lists + {"basic list of lists", + "(1 2), (42 43)", + {{{{Item(1), Item(2)}, {}}, {{Item(42), Item(43)}, {}}}}}, + {"single item list of lists", + "(42)", + {{{std::vector<Item>{Item(42)}, {}}}}}, + {"empty item list of lists", "()", {{{std::vector<Item>(), {}}}}}, + {"empty middle item list of lists", + "(1),(),(42)", + {{{std::vector<Item>{Item(1)}, {}}, + {std::vector<Item>(), {}}, + {std::vector<Item>{Item(42)}, {}}}}}, + {"extra whitespace list of lists", + "(1 42)", + {{{{Item(1), Item(42)}, {}}}}}, + {"no trailing parenthesis list of lists", "(1 42", base::nullopt}, + {"no trailing parenthesis middle list of lists", "(1 2, (42 43)", + base::nullopt}, + // Parameterized Lists + {"basic parameterised list", + "abc_123;a=1;b=2; cdef_456, ghi;q=\"9\";r=\"w\"", + {{{Token("abc_123"), {Param("a", 1), Param("b", 2), Param("cdef_456")}}, + {Token("ghi"), {Param("q", "9"), Param("r", "w")}}}}}, + {"single item parameterised list", + "text/html;q=1", + {{{Token("text/html"), {Param("q", 1)}}}}}, + {"no whitespace parameterised list", + "text/html,text/plain;q=1", + {{{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}}}, + {"whitespace before = parameterised list", "text/html, text/plain;q =1", + base::nullopt}, + {"whitespace after = parameterised list", "text/html, text/plain;q= 1", + base::nullopt}, + {"extra whitespace param-list", + "text/html , text/plain ; q=1", + {{{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}}}, + {"empty item parameterised list", "text/html,,text/plain;q=1", + base::nullopt}, + }; + for (const auto& c : cases) { + SCOPED_TRACE(c.name); + base::Optional<List> result = ParseList(c.raw); + EXPECT_EQ(result, c.expected); + } +} + +// For Structured Headers Draft 9 TEST(StructuredHeaderTest, ParseListOfLists) { struct TestCase { const char* name; @@ -110,21 +186,18 @@ {"empty inner item list of lists", "1;;2,42", {}}, }; for (const auto& c : cases) { + SCOPED_TRACE(c.name); base::Optional<ListOfLists> result = ParseListOfLists(c.raw); if (!c.expected.empty()) { - EXPECT_TRUE(result.has_value()) << c.name; - EXPECT_EQ(*result, c.expected) << c.name; + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(*result, c.expected); } else { - EXPECT_FALSE(result.has_value()) << c.name; + EXPECT_FALSE(result.has_value()); } } } -inline bool operator==(const ParameterisedIdentifier& lhs, - const ParameterisedIdentifier& rhs) { - return lhs.identifier == rhs.identifier && lhs.params == rhs.params; -} - +// For Structured Headers Draft 9 TEST(StructuredHeaderTest, ParseParameterisedList) { struct TestCase { const char* name; @@ -134,26 +207,23 @@ {"basic param-list", "abc_123;a=1;b=2; cdef_456, ghi;q=\"9\";r=\"w\"", { - {Item("abc_123", Item::kTokenType), - {{"a", Item(1)}, {"b", Item(2)}, {"cdef_456", {}}}}, - {Item("ghi", Item::kTokenType), - {{"q", Item("9")}, {"r", Item("w")}}}, + {Token("abc_123"), + {Param("a", 1), Param("b", 2), Param("cdef_456")}}, + {Token("ghi"), {Param("q", "9"), Param("r", "w")}}, }}, {"empty param-list", "", {}}, {"single item param-list", "text/html;q=1", - {{Item("text/html", Item::kTokenType), {{"q", Item(1)}}}}}, + {{Token("text/html"), {Param("q", 1)}}}}, {"empty param-list", "", {}}, {"no whitespace param-list", "text/html,text/plain;q=1", - {{Item("text/html", Item::kTokenType), {}}, - {Item("text/plain", Item::kTokenType), {{"q", Item(1)}}}}}, + {{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}}, {"whitespace before = param-list", "text/html, text/plain;q =1", {}}, {"whitespace after = param-list", "text/html, text/plain;q= 1", {}}, {"extra whitespace param-list", "text/html , text/plain ; q=1", - {{Item("text/html", Item::kTokenType), {}}, - {Item("text/plain", Item::kTokenType), {{"q", Item(1)}}}}}, + {{Token("text/html"), {}}, {Token("text/plain"), {Param("q", 1)}}}}, {"duplicate key", "abc;a=1;b=2;a=1", {}}, {"numeric key", "abc;a=1;1b=2;c=1", {}}, {"uppercase key", "abc;a=1;B=2;c=1", {}}, @@ -168,16 +238,17 @@ {"leading comma", ",abc;a=1", {}}, }; for (const auto& c : cases) { + SCOPED_TRACE(c.name); base::Optional<ParameterisedList> result = ParseParameterisedList(c.raw); if (c.expected.empty()) { - EXPECT_FALSE(result.has_value()) << c.name; + EXPECT_FALSE(result.has_value()); continue; } - EXPECT_TRUE(result.has_value()) << c.name; - EXPECT_EQ(result->size(), c.expected.size()) << c.name; + EXPECT_TRUE(result.has_value()); + EXPECT_EQ(result->size(), c.expected.size()); if (result->size() == c.expected.size()) { for (size_t i = 0; i < c.expected.size(); ++i) - EXPECT_EQ((*result)[i], c.expected[i]) << c.name; + EXPECT_EQ((*result)[i], c.expected[i]); } } }
diff --git a/third_party/blink/public/common/http/structured_header.h b/third_party/blink/public/common/http/structured_header.h index 73055ec..9adef24c 100644 --- a/third_party/blink/public/common/http/structured_header.h +++ b/third_party/blink/public/common/http/structured_header.h
@@ -20,6 +20,13 @@ // This file implements parsing of HTTP structured headers, as defined in // https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html. // +// Both drafts 9 and 13 are currently supported. The major difference +// between the two drafts is in the various list formats: Draft 9 describes +// Parameterised lists and lists-of-lists, while draft 13 uses a single List +// syntax, whose members may be inner lists. There should be no ambiguity, +// however, as the code which calls this parser should be expecting only a +// single type for a given header. +// // Currently supported data types are: // Item: // integer: 123 @@ -28,6 +35,9 @@ // byte sequence: *YWJj* // Parameterised list: abc_123;a=1;b=2; cdef_456, ghi;q="9";r="w" // List-of-lists: "foo";"bar", "baz", "bat"; "one" +// List: "foo", "bar", "It was the best of times." +// ("foo" "bar"), ("baz"), ("bat" "one"), () +// abc;a=1;b=2; cde_456, (ghi jkl);q="9";r=w // // Functions are provided to parse each of these, which are intended to be // called with the complete value of an HTTP header (that is, any @@ -87,6 +97,9 @@ std::string string_value_; }; +// Holds a ParameterizedIdentifier (draft 9 only). The contained Item must be a +// Token, and there may be any number of parameters. Parameter ordering is not +// significant. struct BLINK_COMMON_EXPORT ParameterisedIdentifier { using Parameters = std::map<std::string, Item>; @@ -99,8 +112,45 @@ ~ParameterisedIdentifier(); }; +inline bool operator==(const ParameterisedIdentifier& lhs, + const ParameterisedIdentifier& rhs) { + return lhs.identifier == rhs.identifier && lhs.params == rhs.params; +} + +// Holds a ParameterizedMember, which may be either an Inner List, or a single +// Item, with any number of parameters. Parameter ordering is significant. +struct BLINK_COMMON_EXPORT ParameterizedMember { + using Parameters = std::vector<std::pair<std::string, Item>>; + + std::vector<Item> member; + // If false, then |member| should only hold one Item. + bool member_is_inner_list; + + Parameters params; + + ParameterizedMember(const ParameterizedMember&); + ParameterizedMember& operator=(const ParameterizedMember&); + ParameterizedMember(std::vector<Item>, bool, const Parameters&); + // Shorthand constructor for a member which is an inner list. + ParameterizedMember(std::vector<Item>, const Parameters&); + // Shorthand constructor for a member which is a single Item. + ParameterizedMember(Item, const Parameters&); + ~ParameterizedMember(); +}; + +inline bool operator==(const ParameterizedMember& lhs, + const ParameterizedMember& rhs) { + return lhs.member == rhs.member && + lhs.member_is_inner_list == rhs.member_is_inner_list && + lhs.params == rhs.params; +} + +// Structured Headers Draft 09 Parameterised List. using ParameterisedList = std::vector<ParameterisedIdentifier>; +// Structured Headers Draft 09 List of Lists. using ListOfLists = std::vector<std::vector<Item>>; +// Structured Headers Draft 13 List. +using List = std::vector<ParameterizedMember>; // Returns the result of parsing the header value as an Item, if it can be // parsed as one, or nullopt if it cannot. @@ -117,9 +167,16 @@ // Returns the result of parsing the header value as a List of Lists, if it can // be parsed as one, or nullopt if it cannot. Inner list items will be returned // as Items. +// Structured-Headers Draft 09 only. BLINK_COMMON_EXPORT base::Optional<ListOfLists> ParseListOfLists( const base::StringPiece& str); +// Returns the result of parsing the header value as a general List, if it can +// be parsed as one, or nullopt if it cannot. +// Structured-Headers Draft 13 only. +BLINK_COMMON_EXPORT base::Optional<List> ParseList( + const base::StringPiece& str); + } // namespace http_structured_header } // namespace blink
diff --git a/third_party/blink/public/platform/task_type.h b/third_party/blink/public/platform/task_type.h index 8d00677..a3a275d 100644 --- a/third_party/blink/public/platform/task_type.h +++ b/third_party/blink/public/platform/task_type.h
@@ -211,10 +211,15 @@ // Note that the ordering between tasks related to different frames is not // always guaranteed - tasks belonging to different frames can be reordered // when one of the frames is frozen. + // Note: all AssociatedRemotes/AssociatedReceivers should use this task type. kInternalNavigationAssociated = 63, - // Legacy IPCs that are freezable. - kInternalFreezableIPC = 64, + // Tasks which should run when the frame is frozen, but otherwise should run + // in order with other legacy IPC and channel-associated interfaces. + // Only tasks related to unfreezing itself should run here, the majority of + // the tasks + // should use kInternalNavigationAssociated instead. + kInternalNavigationAssociatedUnfreezable = 64, // Task used to split a script loading task for cooperative scheduling kInternalContinueScriptLoading = 65,
diff --git a/third_party/blink/public/platform/web_rtc_stats.h b/third_party/blink/public/platform/web_rtc_stats.h index ec90332e..b332e095 100644 --- a/third_party/blink/public/platform/web_rtc_stats.h +++ b/third_party/blink/public/platform/web_rtc_stats.h
@@ -18,7 +18,6 @@ } namespace webrtc { -class RTCStats; class RTCStatsCollectorCallback; class RTCStatsMemberInterface; class RTCStatsReport; @@ -27,47 +26,8 @@ namespace blink { -class WebRTCStats; class WebRTCStatsMember; - -class BLINK_PLATFORM_EXPORT WebRTCStatsReport { - public: - virtual ~WebRTCStatsReport(); - // Creates a new report object that is a handle to the same underlying stats - // report (the stats are not copied). The new report's iterator is reset, - // useful when needing multiple iterators. - virtual std::unique_ptr<WebRTCStatsReport> CopyHandle() const = 0; - - // Gets stats object by |id|, or null if no stats with that |id| exists. - virtual std::unique_ptr<WebRTCStats> GetStats(WebString id) const = 0; - // The next stats object, or null if the end has been reached. - virtual std::unique_ptr<WebRTCStats> Next() = 0; - // The number of stats objects. - virtual size_t Size() const = 0; -}; - -BLINK_PLATFORM_EXPORT -std::unique_ptr<WebRTCStatsReport> CreateRTCStatsReport( - const scoped_refptr<const webrtc::RTCStatsReport>& stats_report, - const WebVector<webrtc::NonStandardGroupId>& exposed_group_ids); - -class BLINK_PLATFORM_EXPORT WebRTCStats { - public: - virtual ~WebRTCStats(); - - virtual WebString Id() const = 0; - virtual WebString GetType() const = 0; - virtual double Timestamp() const = 0; - - virtual size_t MembersCount() const = 0; - virtual std::unique_ptr<WebRTCStatsMember> GetMember(size_t) const = 0; -}; - -BLINK_PLATFORM_EXPORT -std::unique_ptr<WebRTCStats> CreateRTCStats( - const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner, - const webrtc::RTCStats* stats, - const WebVector<webrtc::NonStandardGroupId>& exposed_group_ids); +class RTCStatsReportPlatform; class BLINK_PLATFORM_EXPORT WebRTCStatsMember { public: @@ -102,7 +62,7 @@ const webrtc::RTCStatsMemberInterface* member); using WebRTCStatsReportCallback = - base::OnceCallback<void(std::unique_ptr<WebRTCStatsReport>)>; + base::OnceCallback<void(std::unique_ptr<RTCStatsReportPlatform>)>; BLINK_PLATFORM_EXPORT rtc::scoped_refptr<webrtc::RTCStatsCollectorCallback>
diff --git a/third_party/blink/public/web/web_local_frame.h b/third_party/blink/public/web/web_local_frame.h index ebf2ca9..bac8761 100644 --- a/third_party/blink/public/web/web_local_frame.h +++ b/third_party/blink/public/web/web_local_frame.h
@@ -701,6 +701,12 @@ virtual bool GetPrintPresetOptionsForPlugin(const WebNode&, WebPrintPresetOptions*) = 0; + // Paint Preview ------------------------------------------------------------ + + // Captures a full frame paint preview of the WebFrame including subframes. + virtual bool CapturePaintPreview(const WebRect& bounds, + cc::PaintCanvas* canvas) = 0; + // Focus -------------------------------------------------------------- // Advance the focus of the WebView to next text input element from current
diff --git a/third_party/blink/renderer/bindings/BUILD.gn b/third_party/blink/renderer/bindings/BUILD.gn index 9e2797f6..0609966 100644 --- a/third_party/blink/renderer/bindings/BUILD.gn +++ b/third_party/blink/renderer/bindings/BUILD.gn
@@ -66,11 +66,16 @@ invoker.component, "--output", rebase_path(invoker.output, root_build_dir), + "--cached-parser-tables-dir", + rebase_path(bindings_scripts_output_dir, root_build_dir), ] if (defined(invoker.deps)) { deps = invoker.deps + } else { + deps = [] } + deps += [ "scripts:cached_lex_yacc_tables" ] } }
diff --git a/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py b/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py index c14b145..e31b171 100644 --- a/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py +++ b/third_party/blink/renderer/bindings/scripts/blink_idl_lexer.py
@@ -79,10 +79,22 @@ # Turn off optimization and caching to help debugging optimize = False outputdir = None + + # Ensure that if we are writing tables, we got a real outputdir. + # Because of the way PLY loads the lexer (via import), it can + # be loaded from anywhere in sys.path; requiring an outputdir + # can help minimize the likelihood of inconsistencies between + # scripts. + assert debug or outputdir + if outputdir: # Need outputdir in path because lex imports the cached lex table - # as a Python module - sys.path.append(outputdir) + # as a Python module. Putting this at the front of sys.path + # helps ensures that we get the one in outputdir, and not some + # module by the same name that might exist elsewhere in path, + # though it won't guarantee it. + if sys.path[0] != outputdir: + sys.path.insert(0, outputdir) if rewrite_tables: tablefile_root = os.path.join(outputdir, LEXTAB)
diff --git a/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py b/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py index a0c2054f..23ec694 100644 --- a/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py +++ b/third_party/blink/renderer/bindings/scripts/blink_idl_parser.py
@@ -93,6 +93,14 @@ outputdir = None picklefile = None write_tables = True + + # Ensure that if we are writing tables, we got a real outputdir. + # Because of the way PLY loads the lexer (via import), it can + # be loaded from anywhere in sys.path; requiring an outputdir + # can help minimize the likelihood of inconsistencies between + # scripts. + assert debug or not write_tables or outputdir + if outputdir: picklefile = picklefile or os.path.join(outputdir, 'parsetab.pickle') if rewrite_tables:
diff --git a/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py b/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py index 309b463..830637cb 100644 --- a/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py +++ b/third_party/blink/renderer/bindings/scripts/blink_idl_parser_test.py
@@ -16,6 +16,7 @@ def test_missing_semicolon_between_definitions(self): # No semicolon after enum definition. text = '''enum TestEnum { "value" } dictionary TestDictionary {};''' - parser = BlinkIDLParser() + # We use debug=True to not have to worry about generated parser tables. + parser = BlinkIDLParser(debug=True) parser.ParseText(filename='', data=text) self.assertGreater(parser.GetErrors(), 0)
diff --git a/third_party/blink/renderer/bindings/scripts/collect_idl_files.py b/third_party/blink/renderer/bindings/scripts/collect_idl_files.py index c6922e5..0a72e8a 100644 --- a/third_party/blink/renderer/bindings/scripts/collect_idl_files.py +++ b/third_party/blink/renderer/bindings/scripts/collect_idl_files.py
@@ -28,6 +28,8 @@ help="specify a component name") parser.add_option('--output', type='string', help="the output file path") + parser.add_option('--cached-parser-tables-dir', + help='location of the generated LEX and YACC files') options, args = parser.parse_args() if options.idl_list_file is None: @@ -36,6 +38,9 @@ parser.error("Specify the output file path with --output.") if options.component is None: parser.error("Specify a component with --component.") + if options.cached_parser_tables_dir is None: + parser.error("Specify the location of the generated " + "LEX and YACC files with --cached-parser-tables-dir.") if args: parser.error("Unknown arguments {}".format(args)) @@ -47,7 +52,7 @@ options, _ = parse_options() filepaths = utilities.read_idl_files_list_from_file(options.idl_list_file) - parser = blink_idl_parser.BlinkIDLParser() + parser = blink_idl_parser.BlinkIDLParser(outputdir=options.cached_parser_tables_dir) ast_group = web_idl.AstGroup(web_idl.Component(options.component)) for filepath in filepaths: ast_group.add_ast_node(blink_idl_parser.parse_file(parser, filepath))
diff --git a/third_party/blink/renderer/bindings/scripts/idl_reader.py b/third_party/blink/renderer/bindings/scripts/idl_reader.py index 3b0895ed..bbb4ad9 100644 --- a/third_party/blink/renderer/bindings/scripts/idl_reader.py +++ b/third_party/blink/renderer/bindings/scripts/idl_reader.py
@@ -81,7 +81,7 @@ class IdlReader(object): - def __init__(self, interfaces_info=None, outputdir=''): + def __init__(self, interfaces_info=None, outputdir='', debug=False): self.extended_attribute_validator = IDLExtendedAttributeValidator() self.interfaces_info = interfaces_info @@ -90,7 +90,7 @@ else: self.interface_dependency_resolver = None - self.parser = BlinkIDLParser(outputdir=outputdir) + self.parser = BlinkIDLParser(outputdir=outputdir, debug=debug) def read_idl_definitions(self, idl_filename): """Returns a dictionary whose key is component and value is an IdlDefinitions object for an IDL file, including all dependencies."""
diff --git a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc index a253d59..e47045b 100644 --- a/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc +++ b/third_party/blink/renderer/core/css/resolver/matched_properties_cache.cc
@@ -187,7 +187,7 @@ } void MatchedPropertiesCache::RemoveCachedMatchedPropertiesWithDeadEntries( - const WeakCallbackInfo& broker) { + const WeakCallbackInfo& info) { Vector<unsigned> to_remove; for (const auto& entry_pair : cache_) { // A nullptr value indicates that the entry is currently being created; see @@ -196,7 +196,7 @@ continue; for (const auto& matched_properties : entry_pair.value->matched_properties) { - if (!broker.IsHeapObjectAlive(matched_properties)) { + if (!info.IsHeapObjectAlive(matched_properties)) { to_remove.push_back(entry_pair.key); break; }
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc index 87752eb..207f2bd 100644 --- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc +++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -783,17 +783,19 @@ : ComputedStyle::kNotAtShadowBoundary); state.SetStyle(std::move(style)); } else { - // Strictly, we should only allow the root element to inherit from initial - // styles, but we allow getComputedStyle() for connected elements outside - // the flat tree rooted at an unassigned shadow host child, or Shadow DOM - // V0 insertion points. - DCHECK(element == GetDocument().documentElement() || - element->IsV0InsertionPoint() || - (IsShadowHost(element->parentNode()) && - !LayoutTreeBuilderTraversal::ParentElement(*element))); state.SetStyle(InitialStyleForElement(GetDocument())); state.SetParentStyle(ComputedStyle::Clone(*state.Style())); state.SetLayoutParentStyle(state.ParentStyle()); + if (element != GetDocument().documentElement()) { + // Strictly, we should only allow the root element to inherit from + // initial styles, but we allow getComputedStyle() for connected + // elements outside the flat tree rooted at an unassigned shadow host + // child, or Shadow DOM V0 insertion points. + DCHECK(element->IsV0InsertionPoint() || + (IsShadowHost(element->parentNode()) && + !LayoutTreeBuilderTraversal::ParentElement(*element))); + state.Style()->SetIsEnsuredOutsideFlatTree(); + } } }
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 613335f1..e7d64e18 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -54,6 +54,7 @@ #include "third_party/blink/renderer/core/css/style_environment_variables.h" #include "third_party/blink/renderer/core/css/style_sheet_contents.h" #include "third_party/blink/renderer/core/display_lock/display_lock_utilities.h" +#include "third_party/blink/renderer/core/dom/document_lifecycle.h" #include "third_party/blink/renderer/core/dom/element.h" #include "third_party/blink/renderer/core/dom/element_traversal.h" #include "third_party/blink/renderer/core/dom/flat_tree_traversal.h" @@ -1797,6 +1798,15 @@ PropagateWritingModeAndDirectionToHTMLRoot(); } +void StyleEngine::ClearEnsuredDescendantStyles(Element& element) { + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kInStyleRecalc); + SelectorFilterRootScope filter_scope(&element); + element.ClearNeedsStyleRecalc(); + element.RecalcDescendantStyles(StyleRecalcChange::kClearEnsured); + element.ClearChildNeedsStyleRecalc(); + GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kStyleClean); +} + void StyleEngine::RebuildLayoutTree() { DCHECK(GetDocument().documentElement()); DCHECK(!InRebuildLayoutTree());
diff --git a/third_party/blink/renderer/core/css/style_engine.h b/third_party/blink/renderer/core/css/style_engine.h index 2d5bb11..7148e9400 100644 --- a/third_party/blink/renderer/core/css/style_engine.h +++ b/third_party/blink/renderer/core/css/style_engine.h
@@ -360,6 +360,7 @@ void UpdateViewportStyle(); void UpdateStyleAndLayoutTree(); void RecalcStyle(); + void ClearEnsuredDescendantStyles(Element& element); void RebuildLayoutTree(); bool InRebuildLayoutTree() const { return in_layout_tree_rebuild_; }
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc index 14382b61..59a366b2 100644 --- a/third_party/blink/renderer/core/css/style_engine_test.cc +++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -2302,4 +2302,71 @@ EXPECT_FALSE(GetDocument().View()->NeedsLayout()); } +TEST_F(StyleEngineTest, GetComputedStyleOutsideFlatTree) { + ScopedFlatTreeStyleRecalcForTest feature_scope(true); + + GetDocument().body()->SetInnerHTMLFromString( + R"HTML(<div id="host"><div id="outer"><div id="inner"><div id="innermost"></div></div></div></div>)HTML"); + + auto* host = GetDocument().getElementById("host"); + auto* outer = GetDocument().getElementById("outer"); + auto* inner = GetDocument().getElementById("inner"); + auto* innermost = GetDocument().getElementById("innermost"); + + host->AttachShadowRootInternal(ShadowRootType::kOpen); + UpdateAllLifecyclePhases(); + + EXPECT_TRUE(host->GetComputedStyle()); + // ComputedStyle is not generated outside the flat tree. + EXPECT_FALSE(outer->GetComputedStyle()); + EXPECT_FALSE(inner->GetComputedStyle()); + EXPECT_FALSE(innermost->GetComputedStyle()); + + inner->EnsureComputedStyle(); + auto* outer_style = outer->GetComputedStyle(); + auto* inner_style = inner->GetComputedStyle(); + + ASSERT_TRUE(outer_style); + ASSERT_TRUE(inner_style); + EXPECT_FALSE(innermost->GetComputedStyle()); + EXPECT_TRUE(outer_style->IsEnsuredOutsideFlatTree()); + EXPECT_TRUE(inner_style->IsEnsuredOutsideFlatTree()); + EXPECT_EQ(Color::kTransparent, inner_style->VisitedDependentColor( + GetCSSPropertyBackgroundColor())); + + inner->SetInlineStyleProperty(CSSPropertyID::kBackgroundColor, "green"); + UpdateAllLifecyclePhases(); + + // Old ensured style is not cleared before we re-ensure it. + EXPECT_TRUE(inner->NeedsStyleRecalc()); + EXPECT_EQ(inner_style, inner->GetComputedStyle()); + + inner->EnsureComputedStyle(); + + // Outer style was not dirty - we still have the same ComputedStyle object. + EXPECT_EQ(outer_style, outer->GetComputedStyle()); + EXPECT_NE(inner_style, inner->GetComputedStyle()); + + inner_style = inner->GetComputedStyle(); + EXPECT_EQ(Color(0, 128, 0), inner_style->VisitedDependentColor( + GetCSSPropertyBackgroundColor())); + + // Making outer dirty will require that we clear ComputedStyles all the way up + // ensuring the style for innermost later because of inheritance. + outer->SetInlineStyleProperty(CSSPropertyID::kColor, "green"); + UpdateAllLifecyclePhases(); + + EXPECT_EQ(outer_style, outer->GetComputedStyle()); + EXPECT_EQ(inner_style, inner->GetComputedStyle()); + EXPECT_FALSE(innermost->GetComputedStyle()); + + auto* innermost_style = innermost->EnsureComputedStyle(); + + EXPECT_NE(outer_style, outer->GetComputedStyle()); + EXPECT_NE(inner_style, inner->GetComputedStyle()); + ASSERT_TRUE(innermost_style); + EXPECT_EQ(Color(0, 128, 0), + innermost_style->VisitedDependentColor(GetCSSPropertyColor())); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 99aa1671..ba7f272 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -1047,6 +1047,7 @@ http_refresh_scheduler_(MakeGarbageCollected<HttpRefreshScheduler>(this)), well_formed_(false), printing_(kNotPrinting), + is_painting_preview_(false), compatibility_mode_(kNoQuirksMode), compatibility_mode_locked_(false), last_focus_type_(kWebFocusTypeNone), @@ -3555,6 +3556,10 @@ } } +void Document::SetIsPaintingPreview(bool is_painting_preview) { + is_painting_preview_ = is_painting_preview; +} + // https://html.spec.whatwg.org/C/dynamic-markup-insertion.html#document-open-steps void Document::open(Document* entered_document, ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index 8261c70a..26b5c756 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h
@@ -774,6 +774,12 @@ } void SetPrinting(PrintingState); + bool IsPaintingPreview() const { return is_painting_preview_; } + bool IsCapturingLayout() const { + return printing_ == kPrinting || is_painting_preview_; + } + void SetIsPaintingPreview(bool); + enum CompatibilityMode { kQuirksMode, kLimitedQuirksMode, kNoQuirksMode }; void SetCompatibilityMode(CompatibilityMode); @@ -1840,6 +1846,7 @@ Member<CSSStyleSheet> elem_sheet_; PrintingState printing_; + bool is_painting_preview_; CompatibilityMode compatibility_mode_; // This is cheaper than making setCompatibilityMode virtual.
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index 0483a982..e4952ef 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3054,6 +3054,13 @@ } else if (ShadowRoot* root = GetShadowRoot()) { if (RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled()) { root->RecalcDescendantStyles(child_change); + // Sad panda. This is only to clear ensured ComputedStyles for elements + // outside the flat tree for getComputedStyle() in the cases where we + // kSubtreeStyleChange. Style invalidation and kLocalStyleChange will + // make sure we clear out-of-date ComputedStyles outside the flat tree + // in Element::EnsureComputedStyle(). + if (child_change.RecalcDescendants()) + RecalcDescendantStyles(StyleRecalcChange::kClearEnsured); } else { if (child_change.TraverseChild(*root)) root->RecalcStyle(child_change); @@ -4943,21 +4950,44 @@ // layoutObject because it did the layout, will be correct and so that the // values returned for the ":selection" pseudo-element will be correct. const ComputedStyle* element_style = GetComputedStyle(); - if (!element_style) { + if (!element_style || element_style->IsEnsuredOutsideFlatTree()) { if (CanParticipateInFlatTree()) { - if (ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*this)) + if (ContainerNode* parent = LayoutTreeBuilderTraversal::Parent(*this)) { parent->EnsureComputedStyle(); + if (element_style) + element_style = GetComputedStyle(); + } + if (RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled()) { + if (element_style && NeedsStyleRecalc()) { + // RecalcStyle() will not traverse into connected elements outside the + // flat tree and we may have a dirty element or ancestors if this + // element is not in the flat tree. If we don't need a style recalc, + // we can just re-use the ComputedStyle from the last + // getComputedStyle(). Otherwise, we need to clear the ensured styles + // for the uppermost dirty ancestor and all of its descendants. If + // this element was not the uppermost dirty element, we would not end + // up here because a dirty ancestor would have cleared the + // ComputedStyle in the recursive call above and element_style would + // have been null. + GetDocument().GetStyleEngine().ClearEnsuredDescendantStyles(*this); + element_style = nullptr; + } + } + } else { + element_style = nullptr; } - scoped_refptr<ComputedStyle> new_style = nullptr; - // TODO(crbug.com/953707): Avoid setting inline style during - // HTMLImageElement::CustomStyleForLayoutObject. - if (HasCustomStyleCallbacks() && !IsHTMLImageElement(*this)) - new_style = CustomStyleForLayoutObject(); - else - new_style = OriginalStyleForLayoutObject(); - element_style = new_style.get(); - new_style->SetIsEnsuredInDisplayNone(); - SetComputedStyle(std::move(new_style)); + if (!element_style) { + scoped_refptr<ComputedStyle> new_style = nullptr; + // TODO(crbug.com/953707): Avoid setting inline style during + // HTMLImageElement::CustomStyleForLayoutObject. + if (HasCustomStyleCallbacks() && !IsHTMLImageElement(*this)) + new_style = CustomStyleForLayoutObject(); + else + new_style = OriginalStyleForLayoutObject(); + element_style = new_style.get(); + new_style->SetIsEnsuredInDisplayNone(); + SetComputedStyle(std::move(new_style)); + } } if (!pseudo_element_specifier)
diff --git a/third_party/blink/renderer/core/dom/live_node_list_registry.cc b/third_party/blink/renderer/core/dom/live_node_list_registry.cc index a0599e9..6366cf65 100644 --- a/third_party/blink/renderer/core/dom/live_node_list_registry.cc +++ b/third_party/blink/renderer/core/dom/live_node_list_registry.cc
@@ -42,10 +42,9 @@ mask_ = mask; } -void LiveNodeListRegistry::ProcessCustomWeakness( - const WeakCallbackInfo& broker) { - auto* it = std::remove_if(data_.begin(), data_.end(), [broker](Entry entry) { - return !broker.IsHeapObjectAlive(entry.first); +void LiveNodeListRegistry::ProcessCustomWeakness(const WeakCallbackInfo& info) { + auto* it = std::remove_if(data_.begin(), data_.end(), [info](Entry entry) { + return !info.IsHeapObjectAlive(entry.first); }); if (it == data_.end()) return;
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index 6e1d0cb..c4eec73 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -1303,7 +1303,25 @@ // early return here is a performance optimization. if (parent_dirty) return; - + // If we are outside the flat tree and FlatTreeStyleRecalc is enabled, we + // should not update the recalc root because we should not traverse those + // nodes from StyleEngine::RecalcStyle(). + if (RuntimeEnabledFeatures::FlatTreeStyleRecalcEnabled()) { + if (const ComputedStyle* current_style = GetComputedStyle()) { + if (current_style->IsEnsuredOutsideFlatTree()) + return; + } else { + ContainerNode* style_parent = ancestor; + while (style_parent && !style_parent->CanParticipateInFlatTree()) + style_parent = style_parent->GetStyleRecalcParent(); + if (style_parent) { + if (const auto* parent_style = style_parent->GetComputedStyle()) { + if (parent_style->IsEnsuredOutsideFlatTree()) + return; + } + } + } + } // If we're in a locked subtree, then we should not update the style recalc // roots. These would be updated when we commit the lock. If we have locked // display locks somewhere in the document, we iterate up the ancestor chain
diff --git a/third_party/blink/renderer/core/dom/node_test.cc b/third_party/blink/renderer/core/dom/node_test.cc index a249ae1d..2e5694c 100644 --- a/third_party/blink/renderer/core/dom/node_test.cc +++ b/third_party/blink/renderer/core/dom/node_test.cc
@@ -503,4 +503,28 @@ EXPECT_TRUE(GetDocument().GetStyleEngine().NeedsStyleRecalc()); } +TEST_F(NodeTest, UpdateChildDirtyAfterSlottingDirtyNode) { + ScopedFlatTreeStyleRecalcForTest scope(true); + + SetBodyContent("<div id=host><span></span></div>"); + + auto* host = GetDocument().getElementById("host"); + auto* span = To<Element>(host->firstChild()); + + // Make sure the span is style dirty. + span->setAttribute("style", "color:green"); + + ShadowRoot& shadow_root = + host->AttachShadowRootInternal(ShadowRootType::kOpen); + shadow_root.SetInnerHTMLFromString("<div><slot></slot></div>"); + + GetDocument().GetSlotAssignmentEngine().RecalcSlotAssignments(); + + // Make sure shadow tree div and slot are marked with ChildNeedsStyleRecalc + // when the dirty span is slotted in. + EXPECT_TRUE(shadow_root.firstChild()->ChildNeedsStyleRecalc()); + EXPECT_TRUE(shadow_root.firstChild()->firstChild()->ChildNeedsStyleRecalc()); + EXPECT_TRUE(span->NeedsStyleRecalc()); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/frame/event_handler_registry.cc b/third_party/blink/renderer/core/frame/event_handler_registry.cc index c15fda7..435d28a 100644 --- a/third_party/blink/renderer/core/frame/event_handler_registry.cc +++ b/third_party/blink/renderer/core/frame/event_handler_registry.cc
@@ -340,8 +340,7 @@ EventHandlerRegistry, &EventHandlerRegistry::ProcessCustomWeakness>(this); } -void EventHandlerRegistry::ProcessCustomWeakness( - const WeakCallbackInfo& broker) { +void EventHandlerRegistry::ProcessCustomWeakness(const WeakCallbackInfo& info) { Vector<UntracedMember<EventTarget>> dead_targets; for (int i = 0; i < kEventHandlerClassCount; ++i) { EventHandlerClass handler_class = static_cast<EventHandlerClass>(i); @@ -349,9 +348,9 @@ for (const auto& event_target : *targets) { Node* node = event_target.key->ToNode(); LocalDOMWindow* window = event_target.key->ToLocalDOMWindow(); - if (node && !broker.IsHeapObjectAlive(node)) { + if (node && !info.IsHeapObjectAlive(node)) { dead_targets.push_back(node); - } else if (window && !broker.IsHeapObjectAlive(window)) { + } else if (window && !info.IsHeapObjectAlive(window)) { dead_targets.push_back(window); } }
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc index 24ea8a0..3640a0c 100644 --- a/third_party/blink/renderer/core/frame/local_frame.cc +++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -1287,6 +1287,18 @@ frame_view->ScheduleAnimation(); } +bool LocalFrame::ClipsContent() const { + // A paint preview shouldn't clip to the viewport if it is the main frame or a + // root remote frame. + if (GetDocument()->IsPaintingPreview() && IsLocalRoot()) + return false; + + if (IsMainFrame()) + return GetSettings()->GetMainFrameClipsContent(); + // By default clip to viewport. + return true; +} + void LocalFrame::SetViewportIntersectionFromParent( const ViewportIntersectionState& intersection_state) { // We only schedule an update if the viewport intersection or occlusion state
diff --git a/third_party/blink/renderer/core/frame/local_frame.h b/third_party/blink/renderer/core/frame/local_frame.h index a5e3023a..75cb56b5 100644 --- a/third_party/blink/renderer/core/frame/local_frame.h +++ b/third_party/blink/renderer/core/frame/local_frame.h
@@ -411,6 +411,9 @@ void WasHidden(); void WasShown(); + // Whether the frame clips its content to the frame's size. + bool ClipsContent() const; + // For a navigation initiated from this LocalFrame with user gesture, record // the UseCounter AdClickNavigation if this frame is an adframe. //
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 a716d44..d7005d1 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -2342,7 +2342,7 @@ DCHECK_EQ(target_state, DocumentLifecycle::kPaintClean); RunPaintLifecyclePhase(); DCHECK(ShouldThrottleRendering() || - (frame_->GetDocument()->Printing() && + (frame_->GetDocument()->IsCapturingLayout() && !RuntimeEnabledFeatures::PrintBrowserEnabled()) || Lifecycle().GetState() == DocumentLifecycle::kPaintClean); } @@ -2495,16 +2495,16 @@ void LocalFrameView::RunPaintLifecyclePhase() { TRACE_EVENT0("blink,benchmark", "LocalFrameView::RunPaintLifecyclePhase"); - // While printing a document, the paint walk is done by the printing component - // into a special canvas. There is no point doing a normal paint step (or - // animations update) when in this mode. + // While printing or capturing a paint preview of a document, the paint walk + // is done into a special canvas. There is no point doing a normal paint step + // (or animations update) when in this mode. // // RuntimeEnabledFeatures::PrintBrowserEnabled is a mode which runs the // browser normally, but renders every page as if it were being printed. // See crbug.com/667547 - bool print_mode_enabled = frame_->GetDocument()->Printing() && - !RuntimeEnabledFeatures::PrintBrowserEnabled(); - if (!print_mode_enabled) + bool is_capturing_layout = frame_->GetDocument()->IsCapturingLayout() && + !RuntimeEnabledFeatures::PrintBrowserEnabled(); + if (!is_capturing_layout) PaintTree(); if (!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()) { @@ -2513,7 +2513,7 @@ } } - if (!print_mode_enabled) { + if (!is_capturing_layout) { bool needed_update = !paint_artifact_compositor_ || paint_artifact_compositor_->NeedsUpdate(); PushPaintArtifactToCompositor(); @@ -3541,9 +3541,11 @@ // with CompositeAfterPaint. DCHECK(!RuntimeEnabledFeatures::CompositeAfterPaintEnabled()); - // Paint the whole rect if "MainFrameClipsContent" is false, meaning that - // WebPreferences::record_whole_document is true. - if (!frame_->GetSettings()->GetMainFrameClipsContent()) + // Paint the whole rect if ClipsContent is false, meaning that the whole + // document should be recorded. This occurs if: + // - A paint preview is being captured. + // - WebPreferences::record_whole_document is true. + if (!frame_->ClipsContent()) return; // By default we consider the bounds of the FrameView to be what is considered
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc index 4c685ca..cd078c7 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.cc +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.cc
@@ -514,6 +514,60 @@ WebPrintParams print_params_; }; +class PaintPreviewContext : public PrintContext { + public: + PaintPreviewContext(LocalFrame* frame) : PrintContext(frame, false) {} + ~PaintPreviewContext() override = default; + + bool Capture(cc::PaintCanvas* canvas, FloatSize size) { + // This code is based on ChromePrintContext::SpoolSinglePage()/SpoolPage(). + // It differs in that it: + // 1. Uses a different set of flags for painting and the graphics context. + // 2. Paints a single page of |size| rather than a specific page in a + // reformatted document. + // 3. Does no scaling. + if (!GetFrame()->GetDocument() || + !GetFrame()->GetDocument()->GetLayoutView()) + return false; + GetFrame()->View()->UpdateLifecyclePhasesForPrinting(); + if (!GetFrame()->GetDocument() || + !GetFrame()->GetDocument()->GetLayoutView()) + return false; + FloatRect bounds(0, 0, size.Width(), size.Height()); + PaintRecordBuilder builder(nullptr, nullptr, nullptr, + canvas->GetPaintPreviewTracker()); + builder.Context().SetIsPaintingPreview(true); + + LocalFrameView* frame_view = GetFrame()->View(); + DCHECK(frame_view); + PropertyTreeState property_tree_state = + frame_view->GetLayoutView()->FirstFragment().LocalBorderBoxProperties(); + + // This calls BeginRecording on |builder| with dimensions specified by the + // CullRect. + frame_view->PaintContentsOutsideOfLifecycle( + builder.Context(), + kGlobalPaintNormalPhase | kGlobalPaintFlattenCompositingLayers | + kGlobalPaintAddUrlMetadata, + CullRect(RoundedIntRect(bounds))); + { + // Add anchors. + ScopedPaintChunkProperties scoped_paint_chunk_properties( + builder.Context().GetPaintController(), property_tree_state, builder, + DisplayItem::kPrintedContentDestinationLocations); + DrawingRecorder line_boundary_recorder( + builder.Context(), builder, + DisplayItem::kPrintedContentDestinationLocations); + OutputLinkedDestinations(builder.Context(), RoundedIntRect(bounds)); + } + canvas->drawPicture(builder.EndRecording(property_tree_state)); + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(PaintPreviewContext); +}; + static WebDocumentLoader* DocumentLoaderForDocLoader(DocumentLoader* loader) { return loader ? WebDocumentLoaderImpl::FromDocumentLoader(loader) : nullptr; } @@ -1548,6 +1602,21 @@ return plugin_container->GetPrintPresetOptionsFromDocument(preset_options); } +bool WebLocalFrameImpl::CapturePaintPreview(const WebRect& bounds, + cc::PaintCanvas* canvas) { + FloatSize float_bounds(bounds.width, bounds.height); + GetFrame()->GetDocument()->SetIsPaintingPreview(true); + ResourceCacheValidationSuppressor validation_suppressor( + GetFrame()->GetDocument()->Fetcher()); + GetFrame()->View()->ForceLayoutForPagination(float_bounds, float_bounds, 1); + PaintPreviewContext* paint_preview_context = + MakeGarbageCollected<PaintPreviewContext>(GetFrame()); + bool success = paint_preview_context->Capture(canvas, float_bounds); + GetFrame()->GetDocument()->SetIsPaintingPreview(false); + GetFrame()->EndPrinting(); + return success; +} + bool WebLocalFrameImpl::HasCustomPageSizeStyle(int page_index) { return GetFrame()->GetDocument()->StyleForPage(page_index)->PageSizeType() != EPageSizeType::kAuto;
diff --git a/third_party/blink/renderer/core/frame/web_local_frame_impl.h b/third_party/blink/renderer/core/frame/web_local_frame_impl.h index ef0067c..e862362 100644 --- a/third_party/blink/renderer/core/frame/web_local_frame_impl.h +++ b/third_party/blink/renderer/core/frame/web_local_frame_impl.h
@@ -297,6 +297,8 @@ void DispatchAfterPrintEvent() override; bool GetPrintPresetOptionsForPlugin(const WebNode&, WebPrintPresetOptions*) override; + bool CapturePaintPreview(const WebRect& bounds, + cc::PaintCanvas* canvas) override; void AdvanceFocusInForm(WebFocusType) override; bool ShouldSuppressKeyboardForFocusedElement() override; WebPerformance Performance() const override;
diff --git a/third_party/blink/renderer/core/inspector/network_resources_data.cc b/third_party/blink/renderer/core/inspector/network_resources_data.cc index 0530b05..1253713 100644 --- a/third_party/blink/renderer/core/inspector/network_resources_data.cc +++ b/third_party/blink/renderer/core/inspector/network_resources_data.cc
@@ -143,8 +143,8 @@ } void NetworkResourcesData::ResourceData::ProcessCustomWeakness( - const WeakCallbackInfo& broker) { - if (!cached_resource_ || broker.IsHeapObjectAlive(cached_resource_)) + const WeakCallbackInfo& info) { + if (!cached_resource_ || info.IsHeapObjectAlive(cached_resource_)) return; // Mark loaded resources or resources without the buffer as loaded.
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc b/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc index b3342cd5..99d7eda9 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_observer.cc
@@ -282,9 +282,8 @@ } } -void IntersectionObserver::ProcessCustomWeakness( - const WeakCallbackInfo& broker) { - if (RootIsImplicit() || (root() && broker.IsHeapObjectAlive(root()))) +void IntersectionObserver::ProcessCustomWeakness(const WeakCallbackInfo& info) { + if (RootIsImplicit() || (root() && info.IsHeapObjectAlive(root()))) return; DummyExceptionStateForTesting exception_state; disconnect(exception_state);
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc index 82387ff4..9a16efd 100644 --- a/third_party/blink/renderer/core/layout/layout_view.cc +++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -647,8 +647,9 @@ RETURN_SCROLLBAR_MODE(ScrollbarMode::kAlwaysOff); } - if (document.Printing()) { - // When printing, frame-level scrollbars are never displayed. + if (document.IsCapturingLayout()) { + // When capturing layout (e.g. printing), frame-level scrollbars are never + // displayed. // TODO(szager): Figure out the right behavior when printing an overflowing // iframe. https://bugs.chromium.org/p/chromium/issues/detail?id=777528 RETURN_SCROLLBAR_MODE(ScrollbarMode::kAlwaysOff);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc index 1be5b7d8..c543aab 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -376,8 +376,8 @@ // fragmentation context. if (is_constrained_by_outer_fragmentation_context_ && column_size.block_size != kIndefiniteSize) { - if (const auto* token = BreakToken()) - column_size.block_size -= token->ConsumedBlockSize(); + column_size.block_size -= ConsumedBlockSizeInContentBox( + border_scrollbar_padding_.block_start, BreakToken()); // Subtract the space already taken in the current fragment (spanners and // earlier column rows).
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc index 0070061..e9c066b 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm_test.cc
@@ -3888,6 +3888,42 @@ EXPECT_EQ(expectation, dump); } +TEST_F(NGColumnLayoutAlgorithmTest, NestedLimitedHeightWithPadding) { + SetBodyInnerHTML(R"HTML( + <style> + .outer { columns:3; width:320px; height:100px; } + .inner { columns:2; height:100px; padding-top:50px; } + .outer, .inner { column-gap:10px; column-fill:auto; } + </style> + <div id="container"> + <div class="outer"> + <div class="inner"> + <div style="width:22px; height:200px;"></div> + </div> + </div> + </div> + )HTML"); + + String dump = DumpFragmentTree(GetElementById("container")); + String expectation = R"DUMP(.:: LayoutNG Physical Fragment Tree ::. + offset:unplaced size:1000x100 + offset:0,0 size:320x100 + offset:0,0 size:100x100 + offset:0,0 size:100x100 + offset:0,50 size:45x50 + offset:0,0 size:22x50 + offset:55,50 size:45x50 + offset:0,0 size:22x50 + offset:110,0 size:100x50 + offset:0,0 size:100x50 + offset:0,0 size:45x50 + offset:0,0 size:22x50 + offset:55,0 size:45x50 + offset:0,0 size:22x50 +)DUMP"; + EXPECT_EQ(expectation, dump); +} + TEST_F(NGColumnLayoutAlgorithmTest, NestedUnbalancedInnerAutoHeight) { // The fragments generated by an inner multicol are block-size constrained by // the outer multicol, so if column-fill is auto, we shouldn't forcefully @@ -4696,7 +4732,7 @@ offset:0,0 size:100x50 offset:1,0 size:98x20 offset:0,0 size:4x20 - offset:1,20 size:44x28 + offset:1,20 size:44x29 offset:0,0 size:7x20 offset:55,20 size:44x20 offset:0,0 size:8x20
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc index 330e366..61c2719 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc +++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.cc
@@ -8,6 +8,7 @@ #include "base/optional.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_table_cell.h" +#include "third_party/blink/renderer/core/layout/ng/ng_block_break_token.h" #include "third_party/blink/renderer/core/layout/ng/ng_block_node.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h" #include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h" @@ -1271,4 +1272,18 @@ return base::nullopt; } +LayoutUnit ConsumedBlockSizeInContentBox( + LayoutUnit border_scrollbar_padding_block_start, + const NGBlockBreakToken* break_token) { + if (!break_token) + return LayoutUnit(); + LayoutUnit consumed_block_size = + break_token->ConsumedBlockSize() - border_scrollbar_padding_block_start; + // There are no valid break points inside borders and padding, but if the + // fragmentainer is actually shorter than the space taken up bby borders + // and/or padding, we may end up slicing them into multiple fragmentainers + // anyway - in which case the size we just calculated becomes negative. + return consumed_block_size.ClampNegativeToZero(); +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/ng_length_utils.h b/third_party/blink/renderer/core/layout/ng/ng_length_utils.h index 4d69861..dc99463 100644 --- a/third_party/blink/renderer/core/layout/ng/ng_length_utils.h +++ b/third_party/blink/renderer/core/layout/ng/ng_length_utils.h
@@ -24,6 +24,7 @@ class Length; struct MinMaxSizeInput; class NGConstraintSpace; +class NGBlockBreakToken; class NGBlockNode; class NGLayoutInputNode; @@ -482,6 +483,12 @@ const NGBoxStrut& border_scrollbar_padding, NGMinMaxSizeType); +// Return the sum of the block-size of the content-boxes in all preceding +// fragments. +LayoutUnit ConsumedBlockSizeInContentBox( + LayoutUnit border_scrollbar_padding_block_start, + const NGBlockBreakToken*); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_NG_LENGTH_UTILS_H_
diff --git a/third_party/blink/renderer/core/paint/frame_painter.cc b/third_party/blink/renderer/core/paint/frame_painter.cc index f8ce906d..3ca2029 100644 --- a/third_party/blink/renderer/core/paint/frame_painter.cc +++ b/third_party/blink/renderer/core/paint/frame_painter.cc
@@ -76,7 +76,7 @@ PaintLayerFlags root_layer_paint_flags = 0; // This will prevent clipping the root PaintLayer to its visible content // rect when root layer scrolling is enabled. - if (document->Printing()) + if (document->IsCapturingLayout()) root_layer_paint_flags = kPaintLayerPaintingOverflowContents; PaintLayer* root_layer = layout_view->Layer();
diff --git a/third_party/blink/renderer/core/paint/paint_layer_painter.cc b/third_party/blink/renderer/core/paint/paint_layer_painter.cc index 16c67f1..9c3a8b9 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_painter.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_painter.cc
@@ -112,8 +112,8 @@ const GraphicsContext& context, const PaintLayerPaintingInfo& painting_info, PaintLayerFlags paint_flags) { - // Caching is not needed during printing. - if (context.Printing()) + // Caching is not needed during printing or painting previews. + if (context.Printing() || context.IsPaintingPreview()) return false; if (context.GetPaintController().IsSkippingCache()) @@ -198,8 +198,7 @@ // of the main frame. if (layer.GetLayoutObject().IsLayoutView()) { const auto* frame = layer.GetLayoutObject().GetFrame(); - if (frame && frame->IsMainFrame() && - !frame->GetSettings()->GetMainFrameClipsContent()) + if (frame && frame->IsMainFrame() && !frame->ClipsContent()) return true; } return false;
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 3e59e20..cc6a0ea 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -1541,8 +1541,7 @@ static bool CanOmitOverflowClip(const LayoutObject& object) { DCHECK(NeedsOverflowClip(object)); - if (object.IsLayoutView() && object.GetFrame()->IsMainFrame() && - !object.GetFrame()->GetSettings()->GetMainFrameClipsContent()) { + if (object.IsLayoutView() && !object.GetFrame()->ClipsContent()) { return true; }
diff --git a/third_party/blink/renderer/core/paint/view_painter.cc b/third_party/blink/renderer/core/paint/view_painter.cc index 5d6bed5f..b643cc2 100644 --- a/third_party/blink/renderer/core/paint/view_painter.cc +++ b/third_party/blink/renderer/core/paint/view_painter.cc
@@ -48,9 +48,12 @@ // The background rect always includes at least the visible content size. PhysicalRect background_rect(layout_view_.BackgroundRect()); - // When printing, paint the entire unclipped scrolling content area. - if (paint_info.IsPrinting()) + // When printing or painting a preview, paint the entire unclipped scrolling + // content area. + if (paint_info.IsPrinting() || + !layout_view_.GetFrameView()->GetFrame().ClipsContent()) { background_rect.Unite(layout_view_.DocumentRect()); + } const DisplayItemClient* background_client = &layout_view_;
diff --git a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 index 35cb079a..cbd7d151 100644 --- a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 +++ b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
@@ -1029,5 +1029,12 @@ include_paths: ["third_party/blink/renderer/platform/wtf/text/atomic_string.h"], default_value: "g_null_atom", }, + { + name: "IsEnsuredOutsideFlatTree", + field_template: "monotonic_flag", + default_value: "false", + custom_compare: true, + inherited: true, + }, ], }
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc index a22d9e8d..d0aa251 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.cc
@@ -1196,18 +1196,11 @@ } void SVGSMILElement::ScheduleEvent(const AtomicString& event_type) { - GetDocument() - .GetTaskRunner(TaskType::kDOMManipulation) - ->PostTask(FROM_HERE, WTF::Bind(&SVGSMILElement::DispatchPendingEvent, - WrapPersistent(this), event_type)); -} - -void SVGSMILElement::DispatchPendingEvent(const AtomicString& event_type) { DCHECK(event_type == event_type_names::kEndEvent || event_type == event_type_names::kBeginEvent || event_type == event_type_names::kRepeatEvent || event_type == "repeatn"); - DispatchEvent(*Event::Create(event_type)); + EnqueueEvent(*Event::Create(event_type), TaskType::kDOMManipulation); } bool SVGSMILElement::HasValidTarget() const {
diff --git a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h index 08b8e6d..e9c61565 100644 --- a/third_party/blink/renderer/core/svg/animation/svg_smil_element.h +++ b/third_party/blink/renderer/core/svg/animation/svg_smil_element.h
@@ -124,7 +124,6 @@ void ScheduleEvent(const AtomicString& event_type); void ScheduleRepeatEvents(); - void DispatchPendingEvent(const AtomicString& event_type); virtual bool IsSVGDiscardElement() const { return false; }
diff --git a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc index c96d616..aa90abb 100644 --- a/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc +++ b/third_party/blink/renderer/core/svg/svg_tree_scope_resources.cc
@@ -33,11 +33,11 @@ } void SVGTreeScopeResources::ProcessCustomWeakness( - const WeakCallbackInfo& broker) { + const WeakCallbackInfo& info) { // Unregister and remove any resources that are no longer alive. Vector<AtomicString> to_remove; for (auto& resource_entry : resources_) { - if (broker.IsHeapObjectAlive(resource_entry.value)) + if (info.IsHeapObjectAlive(resource_entry.value)) continue; resource_entry.value->Unregister(); to_remove.push_back(resource_entry.key);
diff --git a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h index 6c69b3d..af65667 100644 --- a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h +++ b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer.h
@@ -72,7 +72,10 @@ inline const void* DataShared() const; inline void* DataMaybeShared(); inline const void* DataMaybeShared() const; - inline unsigned ByteLength() const; + inline size_t ByteLengthAsSizeT() const; + // This function is deprecated and should not be used. Use {ByteLengthAsSizeT} + // instead. + inline unsigned ByteLengthAsUnsigned() const; // Creates a new ArrayBuffer object with copy of bytes in this object // ranging from |begin| up to but not including |end|. @@ -124,7 +127,7 @@ // TODO(binji): support creating a SharedArrayBuffer by copying another // ArrayBuffer? DCHECK(!other->IsShared()); - return ArrayBuffer::Create(other->Data(), other->ByteLength()); + return ArrayBuffer::Create(other->Data(), other->ByteLengthAsSizeT()); } scoped_refptr<ArrayBuffer> ArrayBuffer::Create(const void* source, @@ -238,7 +241,15 @@ return contents_.DataMaybeShared(); } -unsigned ArrayBuffer::ByteLength() const { +size_t ArrayBuffer::ByteLengthAsSizeT() const { + return contents_.DataLength(); +} + +// This function is deprecated and should not be used. Use {ByteLengthAsSizeT} +// instead. +unsigned ArrayBuffer::ByteLengthAsUnsigned() const { + CHECK_LE(contents_.DataLength(), + static_cast<size_t>(std::numeric_limits<unsigned>::max())); // TODO(dtapuska): Revisit this cast. ArrayBufferContents // uses size_t for storing data. Whereas ArrayBuffer IDL is // only uint32_t based. @@ -254,7 +265,7 @@ } unsigned ArrayBuffer::ClampIndex(unsigned index) const { - return index < ByteLength() ? index : ByteLength(); + return index < ByteLengthAsUnsigned() ? index : ByteLengthAsUnsigned(); } } // namespace blink
diff --git a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h index 49af984..5b7b548 100644 --- a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h +++ b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_view.h
@@ -90,10 +90,10 @@ return false; if (sizeof(T) > 1 && byte_offset % sizeof(T)) return false; - if (byte_offset > buffer->ByteLength()) + if (byte_offset > buffer->ByteLengthAsUnsigned()) return false; - unsigned remaining_elements = - static_cast<unsigned>((buffer->ByteLength() - byte_offset) / sizeof(T)); + unsigned remaining_elements = static_cast<unsigned>( + (buffer->ByteLengthAsUnsigned() - byte_offset) / sizeof(T)); if (num_elements > remaining_elements) return false; return true;
diff --git a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc index 0874012..7935d89 100644 --- a/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc +++ b/third_party/blink/renderer/core/typed_arrays/array_buffer/array_piece.cc
@@ -47,7 +47,8 @@ void ArrayPiece::InitWithArrayBuffer(ArrayBuffer* buffer) { if (buffer) { - InitWithData(buffer->Data(), SafeCast<unsigned>(buffer->ByteLength())); + InitWithData(buffer->Data(), + SafeCast<unsigned>(buffer->ByteLengthAsUnsigned())); is_detached_ = buffer->IsDetached(); } else { InitNull();
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc index f4da2348..bf7452e 100644 --- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc +++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer.cc
@@ -41,8 +41,8 @@ ArrayBufferContents& result) { DOMArrayBuffer* to_transfer = this; if (!IsDetachable(isolate)) { - to_transfer = - DOMArrayBuffer::Create(Buffer()->Data(), Buffer()->ByteLength()); + to_transfer = DOMArrayBuffer::Create(Buffer()->Data(), + Buffer()->ByteLengthAsUnsigned()); } if (!to_transfer->Buffer()->Transfer(result))
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h index fc2f200..fa42233d 100644 --- a/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h +++ b/third_party/blink/renderer/core/typed_arrays/dom_array_buffer_base.h
@@ -21,7 +21,7 @@ const void* Data() const { return Buffer()->Data(); } void* Data() { return Buffer()->Data(); } - unsigned ByteLength() const { return Buffer()->ByteLength(); } + unsigned ByteLength() const { return Buffer()->ByteLengthAsUnsigned(); } bool IsDetached() const { return Buffer()->IsDetached(); } bool IsShared() const { return Buffer()->IsShared(); }
diff --git a/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc b/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc index 026c80d..844ca28 100644 --- a/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc +++ b/third_party/blink/renderer/core/typed_arrays/dom_data_view.cc
@@ -20,7 +20,7 @@ unsigned byte_length) { base::CheckedNumeric<uint32_t> checked_max = byte_offset; checked_max += byte_length; - CHECK_LE(checked_max.ValueOrDie(), buffer->ByteLength()); + CHECK_LE(checked_max.ValueOrDie(), buffer->ByteLengthAsUnsigned()); return base::AdoptRef(new DataView(buffer, byte_offset, byte_length)); }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc index d3e3af9..9b17ea3c 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -1120,7 +1120,19 @@ } bool AXNodeObject::IsImage() const { - return RoleValue() == ax::mojom::Role::kImage; + // Canvas is not currently included so that it is not exposed unless there is + // a label, fallback content or something to make it accessible. This decision + // may be revisited at a later date. + switch (RoleValue()) { + case ax::mojom::Role::kDocCover: + case ax::mojom::Role::kGraphicsSymbol: + case ax::mojom::Role::kImage: + case ax::mojom::Role::kImageMap: + case ax::mojom::Role::kSvgRoot: + return true; + default: + return false; + } } bool AXNodeObject::IsImageButton() const {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc index 579e707..b70044bc 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.cc
@@ -116,6 +116,7 @@ #include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h" +#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/functional.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc index b06e03ce..12e78284 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler_test.cc
@@ -50,6 +50,7 @@ #include "third_party/blink/renderer/modules/peerconnection/peer_connection_tracker.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h" +#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h" #include "third_party/webrtc/api/peer_connection_interface.h" #include "third_party/webrtc/api/rtp_receiver_interface.h" @@ -214,9 +215,9 @@ const blink::WebMediaStreamTrack& track)); }; -void OnStatsDelivered(std::unique_ptr<blink::WebRTCStatsReport>* result, +void OnStatsDelivered(std::unique_ptr<RTCStatsReportPlatform>* result, scoped_refptr<base::SingleThreadTaskRunner> main_thread, - std::unique_ptr<blink::WebRTCStatsReport> report) { + std::unique_ptr<RTCStatsReportPlatform> report) { EXPECT_TRUE(main_thread->BelongsToCurrentThread()); EXPECT_TRUE(report); result->reset(report.release()); @@ -917,7 +918,7 @@ std::unique_ptr<const webrtc::RTCStats>(stats_defined_members.release())); pc_handler_->native_peer_connection()->SetGetStatsReport(report); - std::unique_ptr<blink::WebRTCStatsReport> result; + std::unique_ptr<RTCStatsReportPlatform> result; pc_handler_->GetStats( base::BindOnce(OnStatsDelivered, &result, blink::scheduler::GetSingleThreadTaskRunnerForTesting()), @@ -927,7 +928,7 @@ int undefined_stats_count = 0; int defined_stats_count = 0; - for (std::unique_ptr<blink::WebRTCStats> stats = result->Next(); stats; + for (std::unique_ptr<RTCStats> stats = result->Next(); stats; stats.reset(result->Next().release())) { EXPECT_EQ(stats->GetType().Utf8(), webrtc::RTCTestStats::kType); if (stats->Id().Utf8() == "RTCUndefinedStats") {
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc index cd4b886c..ab04c13 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.cc
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h" #include "third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h" #include "third_party/blink/renderer/platform/bindings/microtask.h" +#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/webrtc/api/rtp_parameters.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc index 3620b11..7327a4d5 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver_impl_test.cc
@@ -21,6 +21,7 @@ #include "third_party/blink/renderer/modules/peerconnection/mock_peer_connection_impl.h" #include "third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h" #include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" +#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" #include "third_party/webrtc/api/stats/rtc_stats_report.h" #include "third_party/webrtc/api/stats/rtcstats_objects.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc index a69b1b5..5789874 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.cc
@@ -25,6 +25,7 @@ #include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/persistent.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_dtmf_sender_handler.h" +#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc index 3955125f..f737a21 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl.cc
@@ -453,8 +453,9 @@ void RTCRtpSenderImpl::ReplaceTrack(blink::WebMediaStreamTrack with_track, blink::RTCVoidRequest* request) { - internal_->ReplaceTrack(std::move(with_track), - base::BindOnce(&OnReplaceTrackCompleted, request)); + internal_->ReplaceTrack( + std::move(with_track), + WTF::Bind(&OnReplaceTrackCompleted, WrapPersistent(request))); } std::unique_ptr<blink::RtcDtmfSenderHandler> RTCRtpSenderImpl::GetDtmfSender()
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc index affc05fd..292a515 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender_impl_test.cc
@@ -23,6 +23,7 @@ #include "third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h" #include "third_party/blink/renderer/modules/peerconnection/webrtc_media_stream_track_adapter_map.h" #include "third_party/blink/renderer/platform/mediastream/media_stream_audio_source.h" +#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h" #include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h" #include "third_party/blink/renderer/platform/testing/io_task_runner_testing_platform_support.h" #include "third_party/webrtc/api/stats/rtc_stats_report.h"
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc index 995b652..e985bcd 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc +++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.cc
@@ -7,16 +7,16 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/bindings/core/v8/v8_object_builder.h" +#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h" #include "third_party/blink/renderer/platform/wtf/std_lib_extras.h" - #include "third_party/webrtc/api/stats/rtc_stats.h" namespace blink { namespace { -v8::Local<v8::Value> WebRTCStatsToValue(ScriptState* script_state, - const WebRTCStats* stats) { +v8::Local<v8::Value> RTCStatsToValue(ScriptState* script_state, + const RTCStats* stats) { V8ObjectBuilder builder(script_state); builder.AddString("id", stats->Id()); @@ -98,23 +98,23 @@ class RTCStatsReportIterationSource final : public PairIterable<String, v8::Local<v8::Value>>::IterationSource { public: - RTCStatsReportIterationSource(std::unique_ptr<WebRTCStatsReport> report) + RTCStatsReportIterationSource(std::unique_ptr<RTCStatsReportPlatform> report) : report_(std::move(report)) {} bool Next(ScriptState* script_state, String& key, v8::Local<v8::Value>& value, ExceptionState& exception_state) override { - std::unique_ptr<WebRTCStats> stats = report_->Next(); + std::unique_ptr<RTCStats> stats = report_->Next(); if (!stats) return false; key = stats->Id(); - value = WebRTCStatsToValue(script_state, stats.get()); + value = RTCStatsToValue(script_state, stats.get()); return true; } private: - std::unique_ptr<WebRTCStatsReport> report_; + std::unique_ptr<RTCStatsReportPlatform> report_; }; } // namespace @@ -136,7 +136,7 @@ return enabled_origin_trials; } -RTCStatsReport::RTCStatsReport(std::unique_ptr<WebRTCStatsReport> report) +RTCStatsReport::RTCStatsReport(std::unique_ptr<RTCStatsReportPlatform> report) : report_(std::move(report)) {} uint32_t RTCStatsReport::size() const { @@ -153,10 +153,10 @@ const String& key, v8::Local<v8::Value>& value, ExceptionState&) { - std::unique_ptr<WebRTCStats> stats = report_->GetStats(key); + std::unique_ptr<RTCStats> stats = report_->GetStats(key); if (!stats) return false; - value = WebRTCStatsToValue(script_state, stats.get()); + value = RTCStatsToValue(script_state, stats.get()); return true; }
diff --git a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h index f6f0e15..cd5eeb3 100644 --- a/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h +++ b/third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h
@@ -26,7 +26,7 @@ DEFINE_WRAPPERTYPEINFO(); public: - RTCStatsReport(std::unique_ptr<WebRTCStatsReport>); + RTCStatsReport(std::unique_ptr<RTCStatsReportPlatform>); uint32_t size() const; @@ -40,7 +40,7 @@ ExceptionState&) override; private: - std::unique_ptr<WebRTCStatsReport> report_; + std::unique_ptr<RTCStatsReportPlatform> report_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc b/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc index ba2848d..9d78cde 100644 --- a/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc +++ b/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.cc
@@ -6,6 +6,7 @@ #include "base/bind.h" #include "base/callback.h" +#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h" namespace blink { @@ -18,17 +19,17 @@ return base::BindOnce(&TestWebRTCStatsReportObtainer::OnStatsDelivered, this); } -blink::WebRTCStatsReport* TestWebRTCStatsReportObtainer::report() const { +RTCStatsReportPlatform* TestWebRTCStatsReportObtainer::report() const { return report_.get(); } -blink::WebRTCStatsReport* TestWebRTCStatsReportObtainer::WaitForReport() { +RTCStatsReportPlatform* TestWebRTCStatsReportObtainer::WaitForReport() { run_loop_.Run(); return report_.get(); } void TestWebRTCStatsReportObtainer::OnStatsDelivered( - std::unique_ptr<blink::WebRTCStatsReport> report) { + std::unique_ptr<RTCStatsReportPlatform> report) { report_ = std::move(report); run_loop_.Quit(); }
diff --git a/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h b/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h index affd519..9d376e05 100644 --- a/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h +++ b/third_party/blink/renderer/modules/peerconnection/test_webrtc_stats_report_obtainer.h
@@ -15,7 +15,7 @@ // The obtainer is a test-only helper class capable of waiting for a GetStats() // callback to be called. It takes ownership of and exposes the resulting -// blink::WebRTCStatsReport. +// RTCStatsReportPlatform. // While WaitForReport() is waiting for the report, tasks posted on the current // thread are executed (see base::RunLoop::Run()) making it safe to wait on the // same thread that the stats report callback occurs on without blocking the @@ -27,18 +27,18 @@ blink::WebRTCStatsReportCallback GetStatsCallbackWrapper(); - blink::WebRTCStatsReport* report() const; - blink::WebRTCStatsReport* WaitForReport(); + RTCStatsReportPlatform* report() const; + RTCStatsReportPlatform* WaitForReport(); private: friend class WTF::ThreadSafeRefCounted<TestWebRTCStatsReportObtainer>; friend class CallbackWrapper; virtual ~TestWebRTCStatsReportObtainer(); - void OnStatsDelivered(std::unique_ptr<blink::WebRTCStatsReport> report); + void OnStatsDelivered(std::unique_ptr<RTCStatsReportPlatform> report); base::RunLoop run_loop_; - std::unique_ptr<blink::WebRTCStatsReport> report_; + std::unique_ptr<RTCStatsReportPlatform> report_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc b/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc index 531cfd02..d271f3a 100644 --- a/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc +++ b/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.cc
@@ -1,12 +1,13 @@ #include "third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" +#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h" namespace blink { void WebRTCStatsReportCallbackResolver( ScriptPromiseResolver* resolver, - std::unique_ptr<WebRTCStatsReport> report) { + std::unique_ptr<RTCStatsReportPlatform> report) { DCHECK(ExecutionContext::From(resolver->GetScriptState())->IsContextThread()); resolver->Resolve(MakeGarbageCollected<RTCStatsReport>(std::move(report))); }
diff --git a/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h b/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h index ce7de6a8..8aa110b 100644 --- a/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h +++ b/third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h
@@ -14,7 +14,7 @@ namespace blink { void WebRTCStatsReportCallbackResolver(ScriptPromiseResolver*, - std::unique_ptr<WebRTCStatsReport>); + std::unique_ptr<RTCStatsReportPlatform>); } // namespace blink
diff --git a/third_party/blink/renderer/modules/webusb/usb_device.cc b/third_party/blink/renderer/modules/webusb/usb_device.cc index 5985cec3..78b20d9 100644 --- a/third_party/blink/renderer/modules/webusb/usb_device.cc +++ b/third_party/blink/renderer/modules/webusb/usb_device.cc
@@ -107,7 +107,7 @@ } vector->Append(static_cast<uint8_t*>(array_buffer->Data()), - array_buffer->ByteLength()); + array_buffer->ByteLengthAsUnsigned()); } else { ArrayBufferView* view = buffer_source.GetAsArrayBufferView().View()->View(); if (!view->Buffer() || view->Buffer()->IsDetached()) {
diff --git a/third_party/blink/renderer/platform/exported/web_rtc_stats.cc b/third_party/blink/renderer/platform/exported/web_rtc_stats.cc index ed27c0a..f871cdb 100644 --- a/third_party/blink/renderer/platform/exported/web_rtc_stats.cc +++ b/third_party/blink/renderer/platform/exported/web_rtc_stats.cc
@@ -6,10 +6,6 @@ namespace blink { -WebRTCStatsReport::~WebRTCStatsReport() = default; - -WebRTCStats::~WebRTCStats() = default; - WebRTCStatsMember::~WebRTCStatsMember() = default; } // namespace blink
diff --git a/third_party/blink/renderer/platform/graphics/graphics_context.cc b/third_party/blink/renderer/platform/graphics/graphics_context.cc index f2d047a..22074d10 100644 --- a/third_party/blink/renderer/platform/graphics/graphics_context.cc +++ b/third_party/blink/renderer/platform/graphics/graphics_context.cc
@@ -306,6 +306,8 @@ canvas_ = paint_recorder_.beginRecording(bounds); if (metafile_) canvas_->SetPrintingMetafile(metafile_); + if (tracker_) + canvas_->SetPaintPreviewTracker(tracker_); } namespace {
diff --git a/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h b/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h index 42631cf..ca07051 100644 --- a/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h +++ b/third_party/blink/renderer/platform/graphics/paint/paint_record_builder.h
@@ -19,10 +19,6 @@ class PaintCanvas; } -namespace paint_preview { -class PaintPreviewTracker; -} - namespace blink { class GraphicsContext; class PaintController;
diff --git a/third_party/blink/renderer/platform/heap/heap_test.cc b/third_party/blink/renderer/platform/heap/heap_test.cc index 39c90da..6b3bd5fd 100644 --- a/third_party/blink/renderer/platform/heap/heap_test.cc +++ b/third_party/blink/renderer/platform/heap/heap_test.cc
@@ -863,8 +863,8 @@ this); } - void ZapWeakMembers(const WeakCallbackInfo& broker) { - if (!broker.IsHeapObjectAlive(weak_bar_)) + void ZapWeakMembers(const WeakCallbackInfo& info) { + if (!info.IsHeapObjectAlive(weak_bar_)) weak_bar_ = nullptr; } @@ -1013,8 +1013,8 @@ this); } - void ZapWeakMembers(const WeakCallbackInfo& broker) { - if (data_ && !broker.IsHeapObjectAlive(data_)) { + void ZapWeakMembers(const WeakCallbackInfo& info) { + if (data_ && !info.IsHeapObjectAlive(data_)) { data_->WillFinalize(); data_ = nullptr; did_call_will_finalize_ = true;
diff --git a/third_party/blink/renderer/platform/heap/visitor.h b/third_party/blink/renderer/platform/heap/visitor.h index 81ea157..67e195fe 100644 --- a/third_party/blink/renderer/platform/heap/visitor.h +++ b/third_party/blink/renderer/platform/heap/visitor.h
@@ -80,8 +80,8 @@ template <typename T, void (T::*method)(const WeakCallbackInfo&)> struct WeakCallbackMethodDelegate { STATIC_ONLY(WeakCallbackMethodDelegate); - static void Trampoline(const WeakCallbackInfo& broker, void* self) { - (reinterpret_cast<T*>(self)->*method)(broker); + static void Trampoline(const WeakCallbackInfo& info, void* self) { + (reinterpret_cast<T*>(self)->*method)(info); } };
diff --git a/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc b/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc index d9c2c3c..216c0f02 100644 --- a/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc +++ b/third_party/blink/renderer/platform/loader/fetch/memory_cache.cc
@@ -71,8 +71,8 @@ MemoryCacheEntry, &MemoryCacheEntry::ClearResourceWeak>(this); } -void MemoryCacheEntry::ClearResourceWeak(const WeakCallbackInfo& broker) { - if (!resource_ || broker.IsHeapObjectAlive(resource_)) +void MemoryCacheEntry::ClearResourceWeak(const WeakCallbackInfo& info) { + if (!resource_ || info.IsHeapObjectAlive(resource_)) return; GetMemoryCache()->Remove(resource_.Get()); resource_.Clear();
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc b/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc index bc9f898..9619bce 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats.cc
@@ -118,13 +118,6 @@ } // namespace -std::unique_ptr<blink::WebRTCStatsReport> CreateRTCStatsReport( - const scoped_refptr<const webrtc::RTCStatsReport>& stats_report, - const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) { - return std::make_unique<RTCStatsReportPlatform>(std::move(stats_report), - exposed_group_ids); -} - RTCStatsReportPlatform::RTCStatsReportPlatform( const scoped_refptr<const webrtc::RTCStatsReport>& stats_report, const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) @@ -138,41 +131,36 @@ RTCStatsReportPlatform::~RTCStatsReportPlatform() {} -std::unique_ptr<blink::WebRTCStatsReport> RTCStatsReportPlatform::CopyHandle() +std::unique_ptr<RTCStatsReportPlatform> RTCStatsReportPlatform::CopyHandle() const { - return CreateRTCStatsReport(stats_report_, exposed_group_ids_); + return std::make_unique<RTCStatsReportPlatform>(stats_report_, + exposed_group_ids_); } -std::unique_ptr<blink::WebRTCStats> RTCStatsReportPlatform::GetStats( +std::unique_ptr<RTCStats> RTCStatsReportPlatform::GetStats( blink::WebString id) const { const webrtc::RTCStats* stats = stats_report_->Get(id.Utf8()); if (!stats || !IsWhitelistedStats(*stats)) - return std::unique_ptr<blink::WebRTCStats>(); - return CreateRTCStats(stats_report_, stats, exposed_group_ids_); + return std::unique_ptr<RTCStats>(); + return std::make_unique<RTCStats>(stats_report_, stats, exposed_group_ids_); } -std::unique_ptr<blink::WebRTCStats> RTCStatsReportPlatform::Next() { +std::unique_ptr<RTCStats> RTCStatsReportPlatform::Next() { while (it_ != end_) { const webrtc::RTCStats& next = *it_; ++it_; - if (IsWhitelistedStats(next)) - return CreateRTCStats(stats_report_, &next, exposed_group_ids_); + if (IsWhitelistedStats(next)) { + return std::make_unique<RTCStats>(stats_report_, &next, + exposed_group_ids_); + } } - return std::unique_ptr<blink::WebRTCStats>(); + return std::unique_ptr<RTCStats>(); } size_t RTCStatsReportPlatform::Size() const { return size_; } -std::unique_ptr<blink::WebRTCStats> CreateRTCStats( - const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner, - const webrtc::RTCStats* stats, - const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids) { - return std::make_unique<RTCStats>(std::move(stats_owner), stats, - exposed_group_ids); -} - RTCStats::RTCStats( const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner, const webrtc::RTCStats* stats, @@ -362,7 +350,7 @@ DCHECK(report); DCHECK(callback_); // Make sure the callback is destroyed in the main thread as well. - std::move(callback_).Run(CreateRTCStatsReport( + std::move(callback_).Run(std::make_unique<RTCStatsReportPlatform>( base::WrapRefCounted(report.get()), exposed_group_ids_)); }
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats.h b/third_party/blink/renderer/platform/peerconnection/rtc_stats.h index 5f20aa1..9e3087c4 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_stats.h +++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats.h
@@ -15,6 +15,8 @@ namespace blink { +class RTCStats; + // Wrapper around a webrtc::RTCStatsReport. Filters out any stats objects that // aren't whitelisted. |filter| controls whether to include only standard // members (RTCStatsMemberInterface::is_standardized return true) or not @@ -26,18 +28,25 @@ // TODO(crbug.com/787254): Switch over the classes below from using WebVector // and WebString to WTF::Vector and WTF::String, when their respective parent // classes are gone. -class PLATFORM_EXPORT RTCStatsReportPlatform : public WebRTCStatsReport { +class PLATFORM_EXPORT RTCStatsReportPlatform { public: RTCStatsReportPlatform( const scoped_refptr<const webrtc::RTCStatsReport>& stats_report, const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids); - ~RTCStatsReportPlatform() override; - std::unique_ptr<blink::WebRTCStatsReport> CopyHandle() const override; + virtual ~RTCStatsReportPlatform(); + // Creates a new report object that is a handle to the same underlying stats + // report (the stats are not copied). The new report's iterator is reset, + // useful when needing multiple iterators. + std::unique_ptr<RTCStatsReportPlatform> CopyHandle() const; - std::unique_ptr<blink::WebRTCStats> GetStats( - blink::WebString id) const override; - std::unique_ptr<blink::WebRTCStats> Next() override; - size_t Size() const override; + // Gets stats object by |id|, or null if no stats with that |id| exists. + std::unique_ptr<RTCStats> GetStats(blink::WebString id) const; + + // The next stats object, or null if the end has been reached. + std::unique_ptr<RTCStats> Next(); + + // The number of stats objects. + size_t Size() const; private: const scoped_refptr<const webrtc::RTCStatsReport> stats_report_; @@ -48,20 +57,20 @@ const size_t size_; }; -class PLATFORM_EXPORT RTCStats : public blink::WebRTCStats { +class PLATFORM_EXPORT RTCStats { public: RTCStats( const scoped_refptr<const webrtc::RTCStatsReport>& stats_owner, const webrtc::RTCStats* stats, const blink::WebVector<webrtc::NonStandardGroupId>& exposed_group_ids); - ~RTCStats() override; + virtual ~RTCStats(); - blink::WebString Id() const override; - blink::WebString GetType() const override; - double Timestamp() const override; + blink::WebString Id() const; + blink::WebString GetType() const; + double Timestamp() const; - size_t MembersCount() const override; - std::unique_ptr<blink::WebRTCStatsMember> GetMember(size_t i) const override; + size_t MembersCount() const; + std::unique_ptr<blink::WebRTCStatsMember> GetMember(size_t i) const; private: // Reference to keep the report that owns |stats_| alive. @@ -107,7 +116,7 @@ // A stats collector callback. // It is invoked on the WebRTC signaling thread and will post a task to invoke // |callback| on the thread given in the |main_thread| argument. -// The argument to the callback will be a |blink::WebRTCStatsReport|. +// The argument to the callback will be a |RTCStatsReportPlatform|. class PLATFORM_EXPORT RTCStatsCollectorCallbackImpl : public webrtc::RTCStatsCollectorCallback { public:
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc b/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc index 082c9d6..8e05e2c 100644 --- a/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc +++ b/third_party/blink/renderer/platform/peerconnection/rtc_stats_test.cc
@@ -45,7 +45,7 @@ // Only whitelisted stats are counted. EXPECT_EQ(report.Size(), 1u); - std::unique_ptr<blink::WebRTCStats> stats = report.Next(); + std::unique_ptr<RTCStats> stats = report.Next(); EXPECT_TRUE(stats); EXPECT_EQ(stats->Id(), whitelisted_id); EXPECT_FALSE(report.Next()); @@ -89,7 +89,7 @@ // TestStats has two members, but the non-standard member should be filtered // out. RTCStatsReportPlatform report(webrtc_report.get(), {}); - std::unique_ptr<blink::WebRTCStats> stats = report.Next(); + std::unique_ptr<RTCStats> stats = report.Next(); ASSERT_NE(nullptr, stats); ASSERT_EQ(1u, stats->MembersCount()); EXPECT_EQ("standardized", stats->GetMember(0)->GetName()); @@ -105,7 +105,7 @@ RTCStatsReportPlatform report( webrtc_report.get(), std::vector<webrtc::NonStandardGroupId>{ webrtc::NonStandardGroupId::kGroupIdForTesting}); - std::unique_ptr<blink::WebRTCStats> stats = report.GetStats("id"); + std::unique_ptr<RTCStats> stats = report.GetStats("id"); ASSERT_NE(nullptr, stats); ASSERT_EQ(2u, stats->MembersCount()); EXPECT_EQ("standardized", stats->GetMember(0)->GetName()); @@ -120,7 +120,7 @@ // Check that filtering options are preserved during copy. RTCStatsReportPlatform standard_members_report(webrtc_report.get(), {}); - std::unique_ptr<blink::WebRTCStatsReport> standard_members_copy = + std::unique_ptr<RTCStatsReportPlatform> standard_members_copy = standard_members_report.CopyHandle(); ASSERT_EQ(1u, standard_members_report.GetStats("id")->MembersCount()); @@ -129,7 +129,7 @@ RTCStatsReportPlatform all_members_report( webrtc_report.get(), std::vector<webrtc::NonStandardGroupId>{ webrtc::NonStandardGroupId::kGroupIdForTesting}); - std::unique_ptr<blink::WebRTCStatsReport> all_members_copy = + std::unique_ptr<RTCStatsReportPlatform> all_members_copy = all_members_report.CopyHandle(); ASSERT_EQ(2u, all_members_report.GetStats("id")->MembersCount()); ASSERT_EQ(2u, all_members_copy->GetStats("id")->MembersCount());
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 893757d..e6eeceac 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -378,7 +378,7 @@ }, { name: "CSS3TextBreakAnywhere", - status: "experimental", + status: "stable", }, { name: "CSSAdditiveAnimations",
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc index 41d9683..6f1747b5 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.cc
@@ -474,7 +474,7 @@ } else { return PausableTaskQueueTraits(); } - case TaskType::kInternalFreezableIPC: + case TaskType::kInternalNavigationAssociated: return FreezableTaskQueueTraits(); case TaskType::kInternalIPC: // Some tasks in the tests need to run when objects are paused e.g. to hook @@ -491,7 +491,7 @@ // time is paused. case TaskType::kInternalInspector: // Navigation IPCs do not run using virtual time to avoid hanging. - case TaskType::kInternalNavigationAssociated: + case TaskType::kInternalNavigationAssociatedUnfreezable: return DoesNotUseVirtualTimeTaskQueueTraits(); case TaskType::kDeprecatedNone: case TaskType::kMainThreadTaskQueueV8:
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc b/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc index a21f77a..5902a7a 100644 --- a/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc +++ b/third_party/blink/renderer/platform/scheduler/main_thread/task_type_names.cc
@@ -129,8 +129,8 @@ return "InternalContentCapture"; case TaskType::kInternalNavigationAssociated: return "InternalNavigationAssociated"; - case TaskType::kInternalFreezableIPC: - return "InternalFreezableIPC"; + case TaskType::kInternalNavigationAssociatedUnfreezable: + return "InternalNavigationAssociatedUnfreezable"; case TaskType::kInternalContinueScriptLoading: return "InternalContinueScriptLoading"; case TaskType::kExperimentalWebScheduling:
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc index 6a24bff..710b1872 100644 --- a/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc +++ b/third_party/blink/renderer/platform/scheduler/worker/worker_scheduler.cc
@@ -169,7 +169,7 @@ case TaskType::kInternalMediaRealTime: case TaskType::kInternalUserInteraction: case TaskType::kInternalIntersectionObserver: - case TaskType::kInternalFreezableIPC: + case TaskType::kInternalNavigationAssociated: case TaskType::kInternalContinueScriptLoading: // UnthrottledTaskRunner is generally discouraged in future. // TODO(nhiroki): Identify which tasks can be throttled / suspendable and @@ -180,7 +180,7 @@ case TaskType::kInternalIPC: case TaskType::kInternalInspector: case TaskType::kInternalTest: - case TaskType::kInternalNavigationAssociated: + case TaskType::kInternalNavigationAssociatedUnfreezable: // kWebLocks can be frozen if for entire page, but not for individual // frames. See https://crrev.com/c/1687716 case TaskType::kWebLocks:
diff --git a/third_party/blink/renderer/platform/wtf/hash_table.h b/third_party/blink/renderer/platform/wtf/hash_table.h index c38ae79f..7019c2c 100644 --- a/third_party/blink/renderer/platform/wtf/hash_table.h +++ b/third_party/blink/renderer/platform/wtf/hash_table.h
@@ -2053,7 +2053,7 @@ using ValueType = typename HashTableType::ValueType; // Used for purely weak and for weak-and-strong tables (ephemerons). - static void Process(const typename Allocator::WeakCallbackInfo& broker, + static void Process(const typename Allocator::WeakCallbackInfo&, void* parameter) { HashTableType* table = reinterpret_cast<HashTableType*>(parameter); // During incremental marking, the table may be freed after the callback has
diff --git a/third_party/blink/tools/blinkpy/bindings/bindings_tests.py b/third_party/blink/tools/blinkpy/bindings/bindings_tests.py index 6db448d8..56983d1 100644 --- a/third_party/blink/tools/blinkpy/bindings/bindings_tests.py +++ b/third_party/blink/tools/blinkpy/bindings/bindings_tests.py
@@ -105,7 +105,7 @@ shutil.rmtree(name) -def generate_interface_dependencies(runtime_enabled_features): +def generate_interface_dependencies(runtime_enabled_features, cache_directory): def idl_paths_recursive(directory): # This is slow, especially on Windows, due to os.walk making # excess stat() calls. Faster versions may appear in Python 3.5 or @@ -127,7 +127,7 @@ return idl_paths def collect_interfaces_info(idl_path_list): - info_collector = InterfaceInfoCollector() + info_collector = InterfaceInfoCollector(cache_directory) for idl_path in idl_path_list: info_collector.collect_info(idl_path) info = info_collector.get_info_as_dict() @@ -208,6 +208,9 @@ continue directory_with_component = os.path.join(directory, component) for filename in os.listdir(directory_with_component): + if filename in ('lextab.py', 'parsetab.pickle'): + # Ignore tempfiles from PLY. + continue files.append(os.path.join(directory_with_component, filename)) return files @@ -288,7 +291,10 @@ return features_map try: - generate_interface_dependencies(make_runtime_features_dict()) + output_dir = os.path.join(output_directory, 'third_party/blink/renderer/bindings/tests/results') + if not os.path.exists(output_dir): + os.makedirs(output_dir) + generate_interface_dependencies(make_runtime_features_dict(), output_directory) for component in COMPONENT_DIRECTORY: output_dir = os.path.join(output_directory, component) if not os.path.exists(output_dir): @@ -297,7 +303,7 @@ options = IdlCompilerOptions( output_directory=output_dir, impl_output_directory=output_dir, - cache_directory=None, + cache_directory=output_dir, target_component=component) if component == 'core': @@ -308,7 +314,7 @@ partial_interface_options = IdlCompilerOptions( output_directory=partial_interface_output_dir, impl_output_directory=None, - cache_directory=None, + cache_directory=output_dir, target_component='modules') idl_filenames = []
diff --git a/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json.py b/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json.py index 484b2e0..bd3ef84 100755 --- a/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json.py +++ b/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json.py
@@ -65,7 +65,8 @@ Returns: a generator which yields IDL node objects """ - parser = BlinkIDLParser() + # We use debug=True to not have to worry about generated parser tables. + parser = BlinkIDLParser(debug=True) for path in paths: definitions = parse_file(parser, path) for definition in definitions.GetChildren():
diff --git a/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json_test.py b/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json_test.py index f98971b..f61724b 100755 --- a/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json_test.py +++ b/third_party/blink/tools/blinkpy/bindings/collect_idls_into_json_test.py
@@ -35,7 +35,8 @@ class TestFunctions(unittest.TestCase): def setUp(self): - parser = BlinkIDLParser() + # We use debug=True to not have to worry about generated parser tables. + parser = BlinkIDLParser(debug=True) path = os.path.join( testdata_path, utilities.read_file_to_list(_FILE)[0]) definitions = parse_file(parser, path)
diff --git a/third_party/blink/web_tests/FlagExpectations/use-vulkan=native b/third_party/blink/web_tests/FlagExpectations/use-vulkan=native index aa49509d..775c91e 100644 --- a/third_party/blink/web_tests/FlagExpectations/use-vulkan=native +++ b/third_party/blink/web_tests/FlagExpectations/use-vulkan=native
@@ -38,8 +38,5 @@ crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap-no-alpha.html [ Skip ] crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap.html [ Skip ] -# createImageBitmap fails for HTMLVideoElement -crbug.com/1003799 fast/canvas/color-space/canvas-createImageBitmap-p3.html [ Skip ] - # Crashing third_party/blink/tools/blinkpy/common/message_pool.py crbug.com/1018884 compositing/overflow/scrollbar-layer-placement.html [ Skip ] \ No newline at end of file
diff --git a/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader b/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader index d3d8b61b..fdee1c2f 100644 --- a/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader +++ b/third_party/blink/web_tests/FlagExpectations/use-vulkan=swiftshader
@@ -1,6 +1,3 @@ -# Test consistently hitting default timeout. -Bug(none) css3/filters/effect-reference-subregion.html [ Skip ] - # OffscreenCanvas not rendering. crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-drawImage-in-worker.html [ Skip ] crbug.com/1002538 fast/canvas/OffscreenCanvas-2d-drawImage.html [ Skip ] @@ -22,7 +19,4 @@ # Expected Image Region Rendering Nothing. crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap-alpha.html [ Skip ] crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap-no-alpha.html [ Skip ] -crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap.html [ Skip ] - -# createImageBitmap fails for HTMLVideoElement -crbug.com/1003799 fast/canvas/color-space/canvas-createImageBitmap-p3.html [ Skip ] +crbug.com/1002547 fast/canvas/imagebitmap/transferFromImageBitmap.html [ Skip ] \ No newline at end of file
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests index ec3b3fd..fd1607e 100644 --- a/third_party/blink/web_tests/NeverFixTests +++ b/third_party/blink/web_tests/NeverFixTests
@@ -148,6 +148,10 @@ [ Linux ] inspector-protocol/layout-fonts/mac-case-insensitive-matching.js [ Skip ] [ Win ] inspector-protocol/layout-fonts/mac-case-insensitive-matching.js [ Skip ] +# Mac only test for Gill Sans kerning +crbug.com/1004945 [ Linux ] fast/text/mac-aat-morx-kern.html [ Skip ] +crbug.com/1004945 [ Win ] fast/text/mac-aat-morx-kern.html [ Skip ] + # Segoe UI matching is only relevant on Windows [ Mac ] inspector-protocol/layout-fonts/font-weight-granularity-matching.js [ Skip ] [ Linux ] inspector-protocol/layout-fonts/font-weight-granularity-matching.js [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 78529ae44..e7f620bb 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -210,6 +210,8 @@ crbug.com/730267 virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-layer.html [ Pass Timeout Failure ] crbug.com/730267 virtual/gpu-rasterization-disable-yuv/images/yuv-decode-eligible/color-profile-layer-filter.html [ Pass Timeout Failure ] +crbug.com/1022460 [ Win ] storage/indexeddb/key-type-array.html [ Pass Crash ] + # Flaky virtual/threaded/fast/scrolling tests crbug.com/841567 virtual/threaded-prefer-compositing/fast/scrolling/absolute-position-behind-scrollbar.html [ Failure Pass ] crbug.com/841567 virtual/threaded-prefer-compositing/fast/scrolling/fixed-position-behind-scrollbar.html [ Failure Pass ] @@ -2797,6 +2799,7 @@ crbug.com/1022141 virtual/speech-with-unified-autoplay/external/wpt/speech-api/SpeechSynthesis-speak-events.html [ Crash Timeout ] # ====== New tests from wpt-importer added here ====== +crbug.com/626703 external/wpt/streams/readable-byte-streams/construct-byob-request.any.sharedworker.html [ Timeout ] crbug.com/626703 [ Linux ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html [ Timeout ] crbug.com/626703 [ Mac ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html [ Timeout ] crbug.com/626703 [ Win ] external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/window-iframe-messagechannel.https.html [ Timeout ] @@ -3855,7 +3858,7 @@ crbug.com/626703 external/wpt/html/cross-origin-embedder-policy/none.https.html [ Failure ] crbug.com/626703 external/wpt/html/cross-origin-opener-policy/coop-sandbox.https.html [ Failure ] crbug.com/626703 [ Debug ] external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Failure ] -crbug.com/626703 [ Debug ] virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Pass Failure ] +crbug.com/626703 [ Debug ] virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Pass Failure ] # Failure due to on-going off-thread paint worklet project. crbug.com/957457 virtual/off-main-thread-css-paint/external/wpt/css/css-paint-api/invalid-image-pending-script.https.html [ Crash ] @@ -5800,7 +5803,7 @@ # Sheriff 2019-10-11 crbug.com/1012599 external/wpt/fetch/cross-origin-resource-policy/fetch.https.any.sharedworker.html [ Pass Timeout ] crbug.com/1013391 http/tests/devtools/a11y-axe-core/settings/shortcuts-a11y-test.js [ Pass Timeout ] -crbug.com/1013523 [ Release ] virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Failure Pass ] +crbug.com/1013523 [ Release ] virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Failure Pass ] crbug.com/1013523 [ Release Linux Mac ] external/wpt/html/cross-origin-embedder-policy/require-corp.https.html [ Failure Pass ] crbug.com/1010472 [ Linux Mac Debug ] virtual/disable-deferred-rendering/fast/canvas/color-space/canvas-drawImage-offscreenCanvas.html [ Timeout Pass ] crbug.com/1010472 virtual/disable-deferred-rendering/fast/canvas/OffscreenCanvas-placeholder-createImageBitmap.html [ Failure Pass ] @@ -5820,7 +5823,7 @@ crbug.com/1014812 virtual/threaded/external/wpt/animation-worklet/playback-rate.https.html [ Pass Timeout Failure ] crbug.com/1014950 [ Mac ] http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-no-url-end-to-end.js [ Pass Timeout ] crbug.com/1014950 [ Mac ] virtual/threaded/http/tests/devtools/tracing/timeline-js/timeline-js-line-level-profile-no-url-end-to-end.js [ Pass Timeout ] -crbug.com/1015187 [ Linux Mac ] virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/none.https.html [ Pass Failure ] +crbug.com/1015187 [ Linux Mac ] virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/none.https.html [ Pass Failure ] # Sheriff 2019-10-18 crbug.com/1015859 [ Linux ] http/tests/devtools/a11y-axe-core/performance/landing-page-a11y-test.js [ Pass Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 3ed9aef..96e081eb 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -584,9 +584,9 @@ "args": ["--enable-features=BlinkSchedulerDisableAntiStarvationForPriorities"] }, { - "prefix": "cross-origin-embedder-policy", + "prefix": "cross-origin-isolation", "bases": ["external/wpt/html/cross-origin-embedder-policy"], - "args": ["--enable-features=CrossOriginEmbedderPolicy"] + "args": ["--enable-features=CrossOriginIsolation"] }, { "prefix": "json-modules",
diff --git a/third_party/blink/web_tests/accessibility/image-map1-expected.txt b/third_party/blink/web_tests/accessibility/image-map1-expected.txt index d7afe984..c777793 100644 --- a/third_party/blink/web_tests/accessibility/image-map1-expected.txt +++ b/third_party/blink/web_tests/accessibility/image-map1-expected.txt
@@ -2,6 +2,7 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". +PASS container.role is 'AXRole: AXImageMap' PASS container.childAtIndex(0).role is 'AXRole: AXLink' PASS container.childAtIndex(0).name is 'Link1' PASS container.childAtIndex(1).role is 'AXRole: AXLink'
diff --git a/third_party/blink/web_tests/accessibility/image-map1.html b/third_party/blink/web_tests/accessibility/image-map1.html index 3e4e4ab1..ec8a37cb 100644 --- a/third_party/blink/web_tests/accessibility/image-map1.html +++ b/third_party/blink/web_tests/accessibility/image-map1.html
@@ -27,7 +27,12 @@ if (window.accessibilityController) { document.getElementById("body").focus(); - var container = accessibilityController.focusedElement.childAtIndex(0); + var body = accessibilityController.accessibleElementById('body'); + var container = body.childAtIndex(0); + + shouldBe("container.role", "'AXRole: AXImageMap'"); + + shouldBe("container.childAtIndex(0).role", "'AXRole: AXLink'"); shouldBe("container.childAtIndex(0).name", "'Link1'");
diff --git a/third_party/blink/web_tests/accessibility/image-map2-expected.txt b/third_party/blink/web_tests/accessibility/image-map2-expected.txt index d36e7ab..ddad784 100644 --- a/third_party/blink/web_tests/accessibility/image-map2-expected.txt +++ b/third_party/blink/web_tests/accessibility/image-map2-expected.txt
@@ -2,9 +2,6 @@ ---------------------- ------------ - -AXRole: AXGenericContainer ------------- Link1 AXRole: AXLink ------------
diff --git a/third_party/blink/web_tests/accessibility/image-map2.html b/third_party/blink/web_tests/accessibility/image-map2.html index 1a29b48..7f5c12b 100644 --- a/third_party/blink/web_tests/accessibility/image-map2.html +++ b/third_party/blink/web_tests/accessibility/image-map2.html
@@ -3,7 +3,7 @@ if (window.testRunner) testRunner.dumpAsText(); </script> -<body id="body"> +<body> <div id="result"></div> @@ -13,18 +13,18 @@ <area shape="rect" coords="12,74,134,88" href="http://www.apple.com" alt="Link2" /> </map> - <img src="resources/cake.png" border="0" align="left" usemap="#imagemap1" vspace="1"> + <img id="map" src="resources/cake.png" border="0" align="left" usemap="#imagemap1" vspace="1"> <script> if (window.accessibilityController) { var result = document.getElementById("result"); - var body = document.getElementById("body"); - body.focus(); + var container = accessibilityController.accessibleElementById('map'); + result.innerText += "Image map - test 2 - 2 Links (alt tags)\n"; result.innerText += "----------------------\n"; - result.innerText += accessibilityController.focusedElement.childAtIndex(0).attributesOfChildren() + "\n\n"; + result.innerText += container.attributesOfChildren() + "\n\n"; } </script> </body>
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json index b55b9035..7b43560 100644 --- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json +++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_6.json
@@ -46615,6 +46615,30 @@ {} ] ], + "css/css-flexbox/percentage-heights-008.html": [ + [ + "css/css-flexbox/percentage-heights-008.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], + "css/css-flexbox/percentage-heights-009.html": [ + [ + "css/css-flexbox/percentage-heights-009.html", + [ + [ + "/css/reference/ref-filled-green-100px-square.xht", + "==" + ] + ], + {} + ] + ], "css/css-flexbox/percentage-size-subitems-001.html": [ [ "css/css-flexbox/percentage-size-subitems-001.html", @@ -46855,18 +46879,6 @@ {} ] ], - "css/css-flexbox/ttwf-reftest-flex-order.html": [ - [ - "css/css-flexbox/ttwf-reftest-flex-order.html", - [ - [ - "/css/css-flexbox/reference/ttwf-reftest-flex-order-ref.html", - "==" - ] - ], - {} - ] - ], "css/css-flexbox/ttwf-reftest-flex-wrap-reverse.html": [ [ "css/css-flexbox/ttwf-reftest-flex-wrap-reverse.html", @@ -52997,6 +53009,450 @@ {} ] ], + "css/css-intrinsic-size/intrinsic-size-001.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-001.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-002.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-002.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-002-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-003.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-003.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-003-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-004.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-004.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-004-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-005.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-005.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-004-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-006.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-006.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-006-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-007.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-007.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-007-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-008.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-008.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-008-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-009.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-009.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-009-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-010.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-010.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-010-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-011.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-011.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-011-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-012.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-012.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-012-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-013.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-013.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-013-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-014.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-014.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-014-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-015.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-015.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-015-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-016.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-016.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-016-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-017.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-017.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-017-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-018.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-018.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-018-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-019.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-019.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-019-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-020.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-020.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-020-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-021.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-021.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-021-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-022.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-022.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-022-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-023.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-023.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-023-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-024.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-024.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-024-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-025.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-025.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-025-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-026.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-026.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-026-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-001.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-auto-001.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-auto-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-002.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-auto-002.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-auto-002-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-003.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-auto-003.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-auto-003-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-001.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-legacy-001.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-legacy-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-002.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-legacy-002.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-legacy-002-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-003.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-legacy-003.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-legacy-003-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-004.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-legacy-004.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-legacy-004-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-005.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-legacy-005.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-legacy-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-006.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-legacy-006.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-legacy-006-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-007.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-legacy-007.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-legacy-007-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-008.html": [ + [ + "css/css-intrinsic-size/intrinsic-size-with-legacy-008.html", + [ + [ + "/css/css-intrinsic-size/intrinsic-size-with-legacy-008-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-layout-api/auto-block-size/absolute.https.html": [ [ "css/css-layout-api/auto-block-size/absolute.https.html", @@ -70749,6 +71205,42 @@ {} ] ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-006.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-anywhere-006.html", + [ + [ + "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-007.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-anywhere-007.html", + [ + [ + "/css/css-text/overflow-wrap/overflow-wrap-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-008.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-anywhere-008.html", + [ + [ + "/css/css-text/overflow-wrap/overflow-wrap-002-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/overflow-wrap/overflow-wrap-anywhere-fit-content-001.html": [ [ "css/css-text/overflow-wrap/overflow-wrap-anywhere-fit-content-001.html", @@ -70761,6 +71253,54 @@ {} ] ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-001.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-001.html", + [ + [ + "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-002.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-002.html", + [ + [ + "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-003.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-003.html", + [ + [ + "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-004.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-004.html", + [ + [ + "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-001.html": [ [ "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-001.html", @@ -70965,6 +71505,54 @@ {} ] ], + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-005.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-005.html", + [ + [ + "/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-006.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-006.html", + [ + [ + "/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-007.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-007.html", + [ + [ + "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-008.html": [ + [ + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-008.html", + [ + [ + "/css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/overflow-wrap/overflow-wrap-normal-keep-all-001.html": [ [ "css/css-text/overflow-wrap/overflow-wrap-normal-keep-all-001.html", @@ -73689,6 +74277,66 @@ {} ] ], + "css/css-text/white-space/break-spaces-before-first-char-014.html": [ + [ + "css/css-text/white-space/break-spaces-before-first-char-014.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-before-first-char-015.html": [ + [ + "css/css-text/white-space/break-spaces-before-first-char-015.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-before-first-char-016.html": [ + [ + "css/css-text/white-space/break-spaces-before-first-char-016.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-before-first-char-017.html": [ + [ + "css/css-text/white-space/break-spaces-before-first-char-017.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-before-first-char-018.html": [ + [ + "css/css-text/white-space/break-spaces-before-first-char-018.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/white-space/break-spaces-tab-001.html": [ [ "css/css-text/white-space/break-spaces-tab-001.html", @@ -73761,6 +74409,126 @@ {} ] ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-001.html": [ + [ + "css/css-text/white-space/break-spaces-with-overflow-wrap-001.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-002.html": [ + [ + "css/css-text/white-space/break-spaces-with-overflow-wrap-002.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-003.html": [ + [ + "css/css-text/white-space/break-spaces-with-overflow-wrap-003.html", + [ + [ + "/css/css-text/white-space/reference/pre-wrap-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-004.html": [ + [ + "css/css-text/white-space/break-spaces-with-overflow-wrap-004.html", + [ + [ + "/css/css-text/white-space/reference/pre-wrap-001-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-005.html": [ + [ + "css/css-text/white-space/break-spaces-with-overflow-wrap-005.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-006.html": [ + [ + "css/css-text/white-space/break-spaces-with-overflow-wrap-006.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-007.html": [ + [ + "css/css-text/white-space/break-spaces-with-overflow-wrap-007.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-008.html": [ + [ + "css/css-text/white-space/break-spaces-with-overflow-wrap-008.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-009.html": [ + [ + "css/css-text/white-space/break-spaces-with-overflow-wrap-009.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-010.html": [ + [ + "css/css-text/white-space/break-spaces-with-overflow-wrap-010.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/white-space/control-chars-000.html": [ [ "css/css-text/white-space/control-chars-000.html", @@ -74661,6 +75429,30 @@ {} ] ], + "css/css-text/white-space/pre-wrap-009.html": [ + [ + "css/css-text/white-space/pre-wrap-009.html", + [ + [ + "/css/css-text/white-space/reference/white-space-break-spaces-005-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/white-space/pre-wrap-010.html": [ + [ + "css/css-text/white-space/pre-wrap-010.html", + [ + [ + "/css/css-text/white-space/reference/pre-wrap-001-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/white-space/pre-wrap-011.html": [ [ "css/css-text/white-space/pre-wrap-011.html", @@ -76181,6 +76973,30 @@ {} ] ], + "css/css-text/word-break/word-break-break-all-inline-009.html": [ + [ + "css/css-text/word-break/word-break-break-all-inline-009.html", + [ + [ + "/css/css-text/word-break/reference/word-break-break-all-010-ref.html", + "==" + ] + ], + {} + ] + ], + "css/css-text/word-break/word-break-break-all-inline-010.html": [ + [ + "css/css-text/word-break/word-break-break-all-inline-010.html", + [ + [ + "/css/css-text/word-break/reference/word-break-break-all-010-ref.html", + "==" + ] + ], + {} + ] + ], "css/css-text/word-break/word-break-break-word-overflow-wrap-interactions.html": [ [ "css/css-text/word-break/word-break-break-word-overflow-wrap-interactions.html", @@ -133597,9 +134413,6 @@ "css/css-flexbox/reference/ttwf-reftest-flex-inline-ref.html": [ [] ], - "css/css-flexbox/reference/ttwf-reftest-flex-order-ref.html": [ - [] - ], "css/css-flexbox/reference/ttwf-reftest-flex-wrap-ref.html": [ [] ], @@ -139666,6 +140479,120 @@ "css/css-inline/parsing/dominant-baseline-valid-expected.txt": [ [] ], + "css/css-intrinsic-size/intrinsic-size-001-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-002-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-003-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-004-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-005-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-006-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-007-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-008-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-009-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-010-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-011-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-012-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-013-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-014-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-015-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-016-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-017-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-018-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-019-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-020-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-021-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-022-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-023-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-024-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-025-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-026-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-001-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-002-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-003-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-001-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-002-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-003-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-004-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-005-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-006-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-007-ref.html": [ + [] + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-008-ref.html": [ + [] + ], + "css/css-intrinsic-size/resources/dice.png": [ + [] + ], "css/css-layout-api/META.yml": [ [] ], @@ -143371,9 +144298,6 @@ "css/css-text/overflow-wrap/overflow-wrap-004-ref.html": [ [] ], - "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-002-expected.txt": [ - [] - ], "css/css-text/overflow-wrap/reference/overflow-wrap-break-word-001-ref.html": [ [] ], @@ -143416,12 +144340,6 @@ "css/css-text/parsing/hyphens-computed-expected.txt": [ [] ], - "css/css-text/parsing/overflow-wrap-computed-expected.txt": [ - [] - ], - "css/css-text/parsing/overflow-wrap-valid-expected.txt": [ - [] - ], "css/css-text/parsing/text-align-all-valid-expected.txt": [ [] ], @@ -143449,12 +144367,6 @@ "css/css-text/parsing/text-transform-valid-expected.txt": [ [] ], - "css/css-text/parsing/word-wrap-computed-expected.txt": [ - [] - ], - "css/css-text/parsing/word-wrap-valid-expected.txt": [ - [] - ], "css/css-text/shaping/reference/shaping-000-sanity-ref.html": [ [] ], @@ -162589,6 +163501,9 @@ "html/webappapis/system-state-and-capabilities/the-navigator-object/navigatorcookies-cookieenabled-false-manual-expected.txt": [ [] ], + "html/webappapis/the-windoworworkerglobalscope-mixin/README.md": [ + [] + ], "html/webappapis/the-windoworworkerglobalscope-mixin/support/WorkerSelfOriginSharedWorker.js": [ [] ], @@ -171169,30 +172084,6 @@ "streams/count-queuing-strategy.any.worker-expected.txt": [ [] ], - "streams/piping/abort.any-expected.txt": [ - [] - ], - "streams/piping/abort.any.serviceworker-expected.txt": [ - [] - ], - "streams/piping/abort.any.sharedworker-expected.txt": [ - [] - ], - "streams/piping/abort.any.worker-expected.txt": [ - [] - ], - "streams/piping/pipe-through.any-expected.txt": [ - [] - ], - "streams/piping/pipe-through.any.serviceworker-expected.txt": [ - [] - ], - "streams/piping/pipe-through.any.sharedworker-expected.txt": [ - [] - ], - "streams/piping/pipe-through.any.worker-expected.txt": [ - [] - ], "streams/readable-byte-streams/brand-checks.any-expected.txt": [ [] ], @@ -177025,9 +177916,6 @@ "webaudio/js/worklet-recorder.js": [ [] ], - "webaudio/refresh_idl.rb": [ - [] - ], "webaudio/resources/4ch-440.wav": [ [] ], @@ -207526,6 +208414,12 @@ {} ] ], + "css/css-flexbox/percentage-padding-001.html": [ + [ + "css/css-flexbox/percentage-padding-001.html", + {} + ] + ], "css/css-flexbox/position-absolute-001.html": [ [ "css/css-flexbox/position-absolute-001.html", @@ -207682,6 +208576,12 @@ {} ] ], + "css/css-fonts/generic-family-keywords-001.html": [ + [ + "css/css-fonts/generic-family-keywords-001.html", + {} + ] + ], "css/css-fonts/idlharness.html": [ [ "css/css-fonts/idlharness.html", @@ -210536,6 +211436,102 @@ {} ] ], + "css/css-intrinsic-size/parsing/intrinsic-block-size-computed.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-block-size-computed.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-block-size-invalid.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-block-size-invalid.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-block-size-valid.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-block-size-valid.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-height-computed.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-height-computed.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-height-invalid.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-height-invalid.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-height-valid.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-height-valid.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-inline-size-computed.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-inline-size-computed.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-inline-size-invalid.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-inline-size-invalid.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-inline-size-valid.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-inline-size-valid.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-size-computed.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-size-computed.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-size-invalid.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-size-invalid.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-size-sets-computed-dimensions.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-size-sets-computed-dimensions.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-size-valid.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-size-valid.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-width-computed.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-width-computed.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-width-invalid.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-width-invalid.html", + {} + ] + ], + "css/css-intrinsic-size/parsing/intrinsic-width-valid.html": [ + [ + "css/css-intrinsic-size/parsing/intrinsic-width-valid.html", + {} + ] + ], "css/css-layout-api/at-supports-rule.https.html": [ [ "css/css-layout-api/at-supports-rule.https.html", @@ -210620,6 +211616,12 @@ {} ] ], + "css/css-lists/list-inside-contain.html": [ + [ + "css/css-lists/list-inside-contain.html", + {} + ] + ], "css/css-lists/nested-list-with-list-style-type-none.html": [ [ "css/css-lists/nested-list-with-list-style-type-none.html", @@ -244847,9 +245849,9 @@ {} ] ], - "html/dom/usvstring-reflection.html": [ + "html/dom/usvstring-reflection.https.html": [ [ - "html/dom/usvstring-reflection.html", + "html/dom/usvstring-reflection.https.html", {} ] ], @@ -291216,9 +292218,9 @@ } ] ], - "screen_enumeration/requestDisplays.tentative.https.any.js": [ + "screen_enumeration/getScreens.tentative.https.any.js": [ [ - "screen_enumeration/requestDisplays.tentative.https.any.html", + "screen_enumeration/getScreens.tentative.https.any.html", { "script_metadata": [ [ @@ -291229,7 +292231,7 @@ } ], [ - "screen_enumeration/requestDisplays.tentative.https.any.serviceworker.html", + "screen_enumeration/getScreens.tentative.https.any.serviceworker.html", { "script_metadata": [ [ @@ -291240,7 +292242,7 @@ } ], [ - "screen_enumeration/requestDisplays.tentative.https.any.sharedworker.html", + "screen_enumeration/getScreens.tentative.https.any.sharedworker.html", { "script_metadata": [ [ @@ -291251,7 +292253,7 @@ } ], [ - "screen_enumeration/requestDisplays.tentative.https.any.worker.html", + "screen_enumeration/getScreens.tentative.https.any.worker.html", { "script_metadata": [ [ @@ -291321,6 +292323,14 @@ {} ] ], + "scroll-to-text-fragment/scroll-to-text-fragment-api.html": [ + [ + "scroll-to-text-fragment/scroll-to-text-fragment-api.html", + { + "testdriver": true + } + ] + ], "scroll-to-text-fragment/scroll-to-text-fragment-same-doc.html": [ [ "scroll-to-text-fragment/scroll-to-text-fragment-same-doc.html", @@ -296397,6 +297407,64 @@ } ] ], + "streams/piping/throwing-options.any.js": [ + [ + "streams/piping/throwing-options.any.html", + { + "script_metadata": [ + [ + "global", + "worker,jsshell" + ] + ] + } + ], + [ + "streams/piping/throwing-options.any.js", + { + "jsshell": true, + "script_metadata": [ + [ + "global", + "worker,jsshell" + ] + ] + } + ], + [ + "streams/piping/throwing-options.any.serviceworker.html", + { + "script_metadata": [ + [ + "global", + "worker,jsshell" + ] + ] + } + ], + [ + "streams/piping/throwing-options.any.sharedworker.html", + { + "script_metadata": [ + [ + "global", + "worker,jsshell" + ] + ] + } + ], + [ + "streams/piping/throwing-options.any.worker.html", + { + "script_metadata": [ + [ + "global", + "worker,jsshell" + ] + ] + } + ] + ], "streams/piping/transform-streams.any.js": [ [ "streams/piping/transform-streams.any.html", @@ -300823,6 +301891,12 @@ {} ] ], + "svg/animations/short-simple-duration-and-fractional-repeatcount.html": [ + [ + "svg/animations/short-simple-duration-and-fractional-repeatcount.html", + {} + ] + ], "svg/animations/single-values-animation.html": [ [ "svg/animations/single-values-animation.html", @@ -301281,6 +302355,12 @@ {} ] ], + "svg/animations/switching-animated-target-to-unknown-element.html": [ + [ + "svg/animations/switching-animated-target-to-unknown-element.html", + {} + ] + ], "svg/animations/syncbase-remove-add-while-running.html": [ [ "svg/animations/syncbase-remove-add-while-running.html", @@ -310041,6 +311121,23 @@ {} ] ], + "web-animations/idlharness.window.js": [ + [ + "web-animations/idlharness.window.html", + { + "script_metadata": [ + [ + "script", + "/resources/WebIDLParser.js" + ], + [ + "script", + "/resources/idlharness.js" + ] + ] + } + ] + ], "web-animations/interfaces/Animatable/animate-no-browsing-context.html": [ [ "web-animations/interfaces/Animatable/animate-no-browsing-context.html", @@ -310095,23 +311192,6 @@ {} ] ], - "web-animations/interfaces/Animation/idlharness.window.js": [ - [ - "web-animations/interfaces/Animation/idlharness.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/WebIDLParser.js" - ], - [ - "script", - "/resources/idlharness.js" - ] - ] - } - ] - ], "web-animations/interfaces/Animation/oncancel.html": [ [ "web-animations/interfaces/Animation/oncancel.html", @@ -310184,23 +311264,6 @@ {} ] ], - "web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.js": [ - [ - "web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/WebIDLParser.js" - ], - [ - "script", - "/resources/idlharness.js" - ] - ] - } - ] - ], "web-animations/interfaces/Document/timeline.html": [ [ "web-animations/interfaces/Document/timeline.html", @@ -310219,23 +311282,6 @@ {} ] ], - "web-animations/interfaces/DocumentTimeline/idlharness.window.js": [ - [ - "web-animations/interfaces/DocumentTimeline/idlharness.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/WebIDLParser.js" - ], - [ - "script", - "/resources/idlharness.js" - ] - ] - } - ] - ], "web-animations/interfaces/DocumentTimeline/style-change-events.html": [ [ "web-animations/interfaces/DocumentTimeline/style-change-events.html", @@ -310266,23 +311312,6 @@ {} ] ], - "web-animations/interfaces/KeyframeEffect/idlharness.window.js": [ - [ - "web-animations/interfaces/KeyframeEffect/idlharness.window.html", - { - "script_metadata": [ - [ - "script", - "/resources/WebIDLParser.js" - ], - [ - "script", - "/resources/idlharness.js" - ] - ] - } - ] - ], "web-animations/interfaces/KeyframeEffect/iterationComposite.html": [ [ "web-animations/interfaces/KeyframeEffect/iterationComposite.html", @@ -373329,6 +374358,18 @@ "1318933952c99e9bb142f74110cbc388e6dda6c4", "reftest" ], + "css/css-flexbox/percentage-heights-008.html": [ + "732f94199b5129e8d7a46dba0a6195d996678683", + "reftest" + ], + "css/css-flexbox/percentage-heights-009.html": [ + "b3de59562bc1ff6b78d9c7b29a5836d47bf8a81b", + "reftest" + ], + "css/css-flexbox/percentage-padding-001.html": [ + "8bba5d60f5cae1b93df70c1973a473f163020a51", + "testharness" + ], "css/css-flexbox/percentage-size-subitems-001.html": [ "70f3953052a3a770c6cd15ee169607a00fc452b0", "reftest" @@ -373517,10 +374558,6 @@ "369de990ff2190ea0e4592d4dfc354a8a8fcae16", "support" ], - "css/css-flexbox/reference/ttwf-reftest-flex-order-ref.html": [ - "6cddecece8649a168f915e502eae4d00204a74fb", - "support" - ], "css/css-flexbox/reference/ttwf-reftest-flex-wrap-ref.html": [ "bb3e2b947af42106dec6974664075afb9e8cb7d3", "support" @@ -373805,10 +374842,6 @@ "275ecd0b6091a1c2d267b5104552c9038b76b681", "reftest" ], - "css/css-flexbox/ttwf-reftest-flex-order.html": [ - "2edac404b6d1688c1cbe7cc497e82d5e87a918fd", - "reftest" - ], "css/css-flexbox/ttwf-reftest-flex-wrap-reverse.html": [ "f2aefa29e8b5e4461e6a8ae9eb76bc8c1c771698", "reftest" @@ -375085,6 +376118,10 @@ "8caf2f3d6000a28c548c84a6fbe2d4c8de2ee5b7", "testharness" ], + "css/css-fonts/generic-family-keywords-001.html": [ + "aa9fb5a6a03bb330d35669f903a1ee7c0f138e18", + "testharness" + ], "css/css-fonts/idlharness-expected.txt": [ "e1973eefdf8f986be26bdc0ae2751afd4e84775f", "support" @@ -385873,6 +386910,370 @@ "d51c759dcc5d7f7e2820751e7a5a7f39dcf91bf1", "testharness" ], + "css/css-intrinsic-size/intrinsic-size-001-ref.html": [ + "d4f0281ae48cd9ab43403fcbfc0c50d8c96e1381", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-001.html": [ + "43c18a0e670b33162b38f845dd860caee9f4efae", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-002-ref.html": [ + "ab847fc36e56155a0b3638a24f9ca90077c76b23", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-002.html": [ + "d7c34558d3b7b3291826ad9c3df4e8f7c4a25fe6", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-003-ref.html": [ + "6a2d05149894c0e7ecfc5471bab6055bc51f072d", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-003.html": [ + "da51eb3fc309dc7463a5e5ff06a468efbd0507b6", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-004-ref.html": [ + "6e710943de9957bcda6ac83985615e35f2154d1e", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-004.html": [ + "f24ffbecee80ddeaca75ec972b513a68eb0ceba0", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-005-ref.html": [ + "950f7190cac250124ba5cda419a71126e157d2e0", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-005.html": [ + "ffbfe8b1ec79b4c13121a0c22b3f2265dd52b9c2", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-006-ref.html": [ + "d545093e2db58163637e466b233cd15da40d0f7b", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-006.html": [ + "3540df2734e46bbdecdf4c48b70e9c1d69bb3a16", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-007-ref.html": [ + "6b3f63685ac07bb0e5f95570744a7b87c56158f6", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-007.html": [ + "b0ff2c89e8ea7ab6ff961b7076d798ac7aedc268", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-008-ref.html": [ + "5c6186fd48cf0dfd2ee83fd6ed2819fa6dbb0989", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-008.html": [ + "27178f67d4929e15cc823d25f81072707fa09aa2", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-009-ref.html": [ + "223e0c8a33a6832e37dc4b78de4c27b5a3abcc11", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-009.html": [ + "3d837b9b9bb8b475747a66bb6f5652fb8bade000", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-010-ref.html": [ + "eaaa0977f139938e2657814fd78d543f2bc5e0db", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-010.html": [ + "73d23c732c6775ab6948d38ee3dcf59f05da16fa", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-011-ref.html": [ + "29d1f4e2d1a108dd53c5905e45d9c7923ca9a2ba", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-011.html": [ + "d050160f7f78fb9596caeb7e48740f8d8cb64944", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-012-ref.html": [ + "ed9857aa2565762f514fe5fb73173b6a5da6494f", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-012.html": [ + "a5ba04751cd92e889c3d27892abd7d0413ff35a6", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-013-ref.html": [ + "9f8334c03d508bc1d91d0163674a28c89c77e034", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-013.html": [ + "dca4c17f7bd9822ad1db78dee371b928923b8acc", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-014-ref.html": [ + "66c10824893089e0c78dd5f6f68e167eac7438b6", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-014.html": [ + "d69f58fd2ec2ee696a4cf65e1cda9832ddad45b9", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-015-ref.html": [ + "ae65a3b5ca547b19e8bdc7b38099c8206edfa6c4", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-015.html": [ + "c7a977540dde36d40d7499ea2c3c89f3ba32a653", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-016-ref.html": [ + "f80510f630624b7bce27483fe9847cd182114fe0", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-016.html": [ + "2c1c917b4f8221096d905ced69f4e92e5172843a", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-017-ref.html": [ + "553451a7075559dad575be17e2ce08b62cb67832", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-017.html": [ + "d9d33477834bcdc00d57cbe2f465dd3538e487bc", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-018-ref.html": [ + "17261caa8af2b65f80ed331fb38bb5c2e37d5b10", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-018.html": [ + "e31b0a412eda0ad07c741c032be6f9bb0b848434", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-019-ref.html": [ + "8e55d7b02f9d1d7352ebdeeca1ee48a1009b49f4", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-019.html": [ + "571863939c57c1d37f617aca3bbb75da05d858de", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-020-ref.html": [ + "1ee5ba8376ddc7e6bb74d765755fbe89b9e33b6b", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-020.html": [ + "c4055bb09d4aff664e7d1fe89b19014f9448a2b3", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-021-ref.html": [ + "35db43fcf44a3668ae19f0d97ea7a872223fcc9c", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-021.html": [ + "93e610be7acf8353db9d63ee8cc3192b9ca24e68", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-022-ref.html": [ + "b0df199283470db4a7ecba4011a3429e8065bb7e", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-022.html": [ + "5331df38fed841d17d8a7899abe93d5193866249", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-023-ref.html": [ + "800e4ae706447004c3c8ff5bf8a530216cba1dea", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-023.html": [ + "aa946e82ac760b784f261b958e834b6540bf00c4", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-024-ref.html": [ + "02ec85a0084910bb09de2e7871b7ddd7d8a68265", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-024.html": [ + "f9fdd8848fe8942acb7b3eb3750840a0318426ec", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-025-ref.html": [ + "60d5cc9cd9aadb99620773ea11eaf9e2081b771b", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-025.html": [ + "d80b9772e5aef7be64188943ae7a3ab5cd8a74f0", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-026-ref.html": [ + "2e456b43422c014a10c62fe93c776c43ad59581a", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-026.html": [ + "fb5412bed8f18cea23b8966f7227a03d743a4f06", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-001-ref.html": [ + "99e86d0c38fd2b76745b6cbd05224dc5aa0537d6", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-001.html": [ + "41b89e3d5aae831fed4d76008867f07e12596664", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-002-ref.html": [ + "70a245469b702bb5b2348ca7698c71ac1ca99671", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-002.html": [ + "446f2154de81c5e33462e325739edb1f2c0854b5", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-003-ref.html": [ + "246a5bad51ed6155177a7f1fb11705c4ca7dd944", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-auto-003.html": [ + "c5da41152863551a6977aeed6b9cb937a77da0a1", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-001-ref.html": [ + "39c6abdcf8eba74a04c1255388ca551cf8988ed5", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-001.html": [ + "e565b56fe98d61022f5cfc184706325ad98a9101", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-002-ref.html": [ + "535915a7a7bed54142f731a21eb20a97379650a1", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-002.html": [ + "bc1141822a66c4560a6cc75f69f890f95d9d233c", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-003-ref.html": [ + "eb6394fe28464f74106c99830d67af1efa58aba4", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-003.html": [ + "78502f4bd645e47658358d760f67dae2b5a02a1e", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-004-ref.html": [ + "d5e7c9ff9bb9c4f155955065161e14f1fcbc954e", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-004.html": [ + "7187222c4ce55dfd827ea81fd3ac0e841b652b7c", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-005-ref.html": [ + "c23984f5f1a4d07c2121088987718781d00fc85c", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-005.html": [ + "0ec60fdaa3353e0a799838ce61eccd3f3ae6b264", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-006-ref.html": [ + "9b9e25d3c8da8693f82bfa7d49e87a320bb3f141", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-006.html": [ + "e4882539b82b691256e6d1af5cdb700411810502", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-007-ref.html": [ + "6894b4643ad616d4acf3a631c991718c76cdae27", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-007.html": [ + "0e749f7038c83382aa43ae152e6537714b893c73", + "reftest" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-008-ref.html": [ + "5cce190275940e70c3e3451a47ed9432025dab46", + "support" + ], + "css/css-intrinsic-size/intrinsic-size-with-legacy-008.html": [ + "973683aac4208fc6c379ec5541a56b7029c965f3", + "reftest" + ], + "css/css-intrinsic-size/parsing/intrinsic-block-size-computed.html": [ + "e9a073ca2aacd9dd9fce6a1b0d33493498b33bac", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-block-size-invalid.html": [ + "1b6cba20f88d78f8e29d385676a261d6d78c8e67", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-block-size-valid.html": [ + "b34c73b230f50d00371811ec063180bfc249fad7", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-height-computed.html": [ + "6f95274c637a54bd88b1bf5e732b8a6aaa291e32", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-height-invalid.html": [ + "1f801124a2b5f2fe3cf96c76b9b64fe33d9f50da", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-height-valid.html": [ + "e461476211879b903e451e662ad393162a94afdd", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-inline-size-computed.html": [ + "c53a77e5631068101f4d58a9a67d6db8b9c8c2a3", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-inline-size-invalid.html": [ + "6ad224d11d3831ba227fc41ab90bf0c3b748be46", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-inline-size-valid.html": [ + "ad5aef95dca952785a8263a7b6447ef4e4b83e03", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-size-computed.html": [ + "29be33d4a3d9a33ec30cfe150f9c9f80d5fd796d", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-size-invalid.html": [ + "b4cb2dbffd2004762d028f092e82e5f9297655ec", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-size-sets-computed-dimensions.html": [ + "e70c3179223eaf220edd3993069848b8e0294dea", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-size-valid.html": [ + "7ab13c7d7986151f22e01711f34a9184effca082", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-width-computed.html": [ + "08602e5347f3de0827446875b15a29c8b6789b27", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-width-invalid.html": [ + "b89f6567ae27595ac752ece8bfe66784d16146de", + "testharness" + ], + "css/css-intrinsic-size/parsing/intrinsic-width-valid.html": [ + "e2d23eabe5da207ce82519e9f57adcbd4cf5d70c", + "testharness" + ], + "css/css-intrinsic-size/resources/dice.png": [ + "c82d01517cd056fe1b63266b00fb9a96ce6251a2", + "support" + ], "css/css-layout-api/META.yml": [ "c85c2d4ccc0b02f3e22ca444952fb7583d96e7c7", "support" @@ -386757,6 +388158,10 @@ "df54e8fb0df8146f896c2abd136d63d930d92d1c", "testharness" ], + "css/css-lists/list-inside-contain.html": [ + "dc06eab97ea648bb598cdbfae5ac43d61847e8ae", + "testharness" + ], "css/css-lists/list-item-definition-ref.html": [ "2d49bc4cb972803c45f701667d68d13028c4abc2", "support" @@ -390534,7 +391939,7 @@ "reftest" ], "css/css-overflow/dynamic-visible-to-clip-001.html": [ - "08114d73b8bf6364d2ad647236fe5388f9eef1b2", + "b97701bfb299b5b9fc06b774f489b2e2285b2c13", "reftest" ], "css/css-overflow/float-with-relpos-and-transform.html": [ @@ -400961,18 +402366,42 @@ "d125a0b5c85c15c94f4765c11c5b6ef276cca7e2", "reftest" ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-006.html": [ + "ac90149ff30d1d8252171460ab1f3b8800c2d58a", + "reftest" + ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-007.html": [ + "a5e10a84ebd3dad65e5cecfbf55eea0e70cdc108", + "reftest" + ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-008.html": [ + "ddb95629999d3599d972de5cf19afaa9378d6d06", + "reftest" + ], "css/css-text/overflow-wrap/overflow-wrap-anywhere-fit-content-001.html": [ "8655b1f087df4534f59ea7c6348fe3272f84ccbf", "reftest" ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-001.html": [ + "5a93c873445e91d59a857220056ba18234926850", + "reftest" + ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-002.html": [ + "38dc19631d3794e011f046acb225471aec2363dd", + "reftest" + ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-003.html": [ + "511294901d914cf8f836ea8b50662544fb72dbf4", + "reftest" + ], + "css/css-text/overflow-wrap/overflow-wrap-anywhere-inline-004.html": [ + "e498e1eff16a40ce96279173b42c3827b566ba5c", + "reftest" + ], "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-001.html": [ "c4a0e10fa42d6389f1bb02a945137a4f40fa03db", "reftest" ], - "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-002-expected.txt": [ - "db1a5fe8be54f9d11b92c5a0fd40cd590752c57b", - "support" - ], "css/css-text/overflow-wrap/overflow-wrap-anywhere-span-002.html": [ "b149ca4d7c25c25999e4fed9373df926c1f30cb6", "testharness" @@ -401046,7 +402475,7 @@ "reftest" ], "css/css-text/overflow-wrap/overflow-wrap-min-content-size-001.html": [ - "608d4853a2425d9b4157bbe331fd78763985cecd", + "6975e816b469a898d3f3617f49ad91badfdc0859", "reftest" ], "css/css-text/overflow-wrap/overflow-wrap-min-content-size-002.html": [ @@ -401058,7 +402487,23 @@ "reftest" ], "css/css-text/overflow-wrap/overflow-wrap-min-content-size-004.html": [ - "7ee2b344f7fdee15b05e590ff93a23c04cf63ffc", + "16161ece69dc85e0caffe370889e46a3071ebe08", + "reftest" + ], + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-005.html": [ + "c8c2a1a43353f9f572ce0a586a2d9c81f51515d1", + "reftest" + ], + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-006.html": [ + "dbbd39301bd741cb77f49deebc6de0ea324e8ddb", + "reftest" + ], + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-007.html": [ + "7296b8d3769a6ea83726d41efdd0725c230e9d17", + "reftest" + ], + "css/css-text/overflow-wrap/overflow-wrap-min-content-size-008.html": [ + "5c2b3958bd79a235d2c0236804de8df195c87776", "reftest" ], "css/css-text/overflow-wrap/overflow-wrap-normal-keep-all-001.html": [ @@ -401098,7 +402543,7 @@ "support" ], "css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html": [ - "99d964777c663fb8ca37be00c162ddfbb82951c9", + "ef5c2e88cefbb99163b8144098d38eb5fb0d06bf", "support" ], "css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-002-ref.html": [ @@ -401110,7 +402555,7 @@ "support" ], "css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html": [ - "c37f3f107841a33afd891a7f39433146ab4704cc", + "93e22ba71ed08199fb01858e8db9950c41d4b35b", "support" ], "css/css-text/overflow-wrap/reference/overflow-wrap-normal-keep-all-001-ref.html": [ @@ -401189,10 +402634,6 @@ "caaae9a5a0150a35563662a8c917046fb08e79fb", "testharness" ], - "css/css-text/parsing/overflow-wrap-computed-expected.txt": [ - "6866ac85893203f11267894682e1eef594072202", - "support" - ], "css/css-text/parsing/overflow-wrap-computed.html": [ "5cc8b831a8f66c154638aecf0f2b249d1391566e", "testharness" @@ -401201,10 +402642,6 @@ "1a467d5f1882fe1d5ede656bd91008499b49367a", "testharness" ], - "css/css-text/parsing/overflow-wrap-valid-expected.txt": [ - "13b5febca96187dbb6310f3b55ff58bfcb833c81", - "support" - ], "css/css-text/parsing/overflow-wrap-valid.html": [ "8ab907c570288a397249fb7b14cc795049283227", "testharness" @@ -401361,10 +402798,6 @@ "217b2488f53128b8475ce4a3f4ca2aa84570b743", "testharness" ], - "css/css-text/parsing/word-wrap-computed-expected.txt": [ - "6f296dd1c7f8e39482b99c89358ce56962cc9f6e", - "support" - ], "css/css-text/parsing/word-wrap-computed.html": [ "0f3639e2e1cbdaee8f349f208f63659d13eefef7", "testharness" @@ -401373,10 +402806,6 @@ "40890775ca563101f4ebcb4d46ecd439bececb61", "testharness" ], - "css/css-text/parsing/word-wrap-valid-expected.txt": [ - "364576f2ccab5a97dc80e4f647f1455a0ba3a488", - "support" - ], "css/css-text/parsing/word-wrap-valid.html": [ "ce5731551aec95f08df44f15ea6491045d14b235", "testharness" @@ -403370,7 +404799,7 @@ "reftest" ], "css/css-text/white-space/break-spaces-before-first-char-011.html": [ - "bc6b2965cb0fdc554082ae0cd2453c602fd805de", + "cf1babeb5e93f601a416994cce060d46a3894f07", "reftest" ], "css/css-text/white-space/break-spaces-before-first-char-012.html": [ @@ -403381,6 +404810,26 @@ "828058f53dd811d4dbea0b7e0d56ab5a940725c6", "reftest" ], + "css/css-text/white-space/break-spaces-before-first-char-014.html": [ + "6eb32b57f3f3298d9b66056c7c6842c88851b152", + "reftest" + ], + "css/css-text/white-space/break-spaces-before-first-char-015.html": [ + "785c2f2a4e9ac98bbb53124eb5a0a45e5bf1648e", + "reftest" + ], + "css/css-text/white-space/break-spaces-before-first-char-016.html": [ + "bec4520b113b26a10f1ff29b3f515487f8d565e0", + "reftest" + ], + "css/css-text/white-space/break-spaces-before-first-char-017.html": [ + "9cb8fdbebcbec4687a1f523b1ffcd4a137338bff", + "reftest" + ], + "css/css-text/white-space/break-spaces-before-first-char-018.html": [ + "828058f53dd811d4dbea0b7e0d56ab5a940725c6", + "reftest" + ], "css/css-text/white-space/break-spaces-tab-001.html": [ "4b01a60395a6c1133c7af8af957dd70859db4823", "reftest" @@ -403405,6 +404854,46 @@ "34df3bfc1bd2f20abbe29b79124a95ce28a4cfaf", "reftest" ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-001.html": [ + "6912bafee9ebd55cfeddd878f9145048b235566b", + "reftest" + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-002.html": [ + "caef57ec60f8fa7c1874825272290d8236af10dd", + "reftest" + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-003.html": [ + "9f91d085d8ad295b7308fe65822ad4114273fbf7", + "reftest" + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-004.html": [ + "911cff021ad2df5ada257d3aa0d2a53aa131caac", + "reftest" + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-005.html": [ + "d5c836539d2636e3b4e916d2b66eca135a659321", + "reftest" + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-006.html": [ + "0e4b6a80f14eb9c6ed73d7d97d040ba0163dbe93", + "reftest" + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-007.html": [ + "bf51e4bc2fb4b3d17635df65716a3fe2e504bda2", + "reftest" + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-008.html": [ + "9826449ecc639cd0c6f388159e0a118ff1f2e0ca", + "reftest" + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-009.html": [ + "3b6e76433091aae25af57b389b207d75d51dae73", + "reftest" + ], + "css/css-text/white-space/break-spaces-with-overflow-wrap-010.html": [ + "d479c5e56757fd32fcfff2066e326a8bfc24860a", + "reftest" + ], "css/css-text/white-space/control-chars-000.html": [ "b038fe9a90d3b8b9cb3bde7fd46396c7121688c9", "reftest" @@ -403717,6 +405206,14 @@ "e2faf3671c2061c30028be4c9608ba1495b79072", "reftest" ], + "css/css-text/white-space/pre-wrap-009.html": [ + "0912a2d3a150cea47ace39cb815af14ca811bb60", + "reftest" + ], + "css/css-text/white-space/pre-wrap-010.html": [ + "71d169c65c011fe28e1b2fcdb3c3bd9dd35dad32", + "reftest" + ], "css/css-text/white-space/pre-wrap-011.html": [ "9945e3ae2dda846c8691a3676d3a83aacd08bb0c", "reftest" @@ -404709,6 +406206,14 @@ "930ae436fe4f1c91b60e9a84c0925e679b6ddfc0", "reftest" ], + "css/css-text/word-break/word-break-break-all-inline-009.html": [ + "e1914f5f4db6d5bfbc5c928562eb1ab790a934b8", + "reftest" + ], + "css/css-text/word-break/word-break-break-all-inline-010.html": [ + "875a36233c555e9b99822773d39f960b579d16f6", + "reftest" + ], "css/css-text/word-break/word-break-break-word-crash-001.html": [ "894a6f3aa0ce257a92926158b75a29986a98e079", "testharness" @@ -404754,7 +406259,7 @@ "reftest" ], "css/css-text/word-break/word-break-min-content-001.html": [ - "20b610180b359bfdf7da5720d2e962af2ba6343f", + "a310e304529dd83f1d356cab6b6664e7f07be97d", "reftest" ], "css/css-text/word-break/word-break-min-content-002.html": [ @@ -404766,7 +406271,7 @@ "reftest" ], "css/css-text/word-break/word-break-min-content-004.html": [ - "efa61b9cd8af65bdb354ef7b07e7008f8a3b6511", + "89b30027c2e9b127ee65e5466ae0d7872f0fa451", "reftest" ], "css/css-text/word-break/word-break-min-content-005.html": [ @@ -432690,7 +434195,7 @@ "support" ], "custom-elements/CustomElementRegistry.html": [ - "368044df3c9373b4ea966bd1b7e9080581b91293", + "c288e8232703afbe00d355ef5b40bdc8d1fa0ac2", "testharness" ], "custom-elements/Document-createElement-svg.svg": [ @@ -434550,7 +436055,7 @@ "testharness" ], "dom/nodes/aria-element-reflection.tentative.html": [ - "848828810f160d5ac01f11bf41b27230b9738800", + "7c8e690a28bbcaa1391878300f143aa1e584fe5e", "testharness" ], "dom/nodes/attributes.html": [ @@ -446318,7 +447823,7 @@ "support" ], "html/cross-origin-opener-policy/coep.https.html": [ - "1c04ed30dd7b3e7cdf7df43e29eca3b433000703", + "64994cdfb76f18cb11c42cc8258209fcfd1091e3", "testharness" ], "html/cross-origin-opener-policy/coep.https.html.headers": [ @@ -446350,7 +447855,7 @@ "support" ], "html/cross-origin-opener-policy/no-https.html": [ - "da9efdce777c43e5b3f37bda628884c1a3579fde", + "014ba1f333b5e254609819bd99618ebcc6b7391b", "testharness" ], "html/cross-origin-opener-policy/no-https.html.headers": [ @@ -447669,7 +449174,7 @@ "aba2b3016a5d56e29cdf5526b7b7259e402c188d", "testharness" ], - "html/dom/usvstring-reflection.html": [ + "html/dom/usvstring-reflection.https.html": [ "b9cafd1fb352cf619141420cbb68aca1483ca8e4", "testharness" ], @@ -451382,7 +452887,7 @@ "support" ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js": [ - "96276d747047fc72d02a22055edf2986ab2163b9", + "a755865911d7bd5eea2c7eeca85705602234e571", "testharness" ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt": [ @@ -451530,7 +453035,7 @@ "support" ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js": [ - "9befc9006e706853d9fab259e631a39f3193c095", + "ffc3708acb7ae00339efbde8c9d912b1f58e7e50", "support" ], "html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js.headers": [ @@ -463581,6 +465086,10 @@ "006827f186eb4e47d387a3b0c9fae404e41e1d37", "testharness" ], + "html/webappapis/the-windoworworkerglobalscope-mixin/README.md": [ + "10ae3e5f03601a67e247f771cf73fdfddfdda12f", + "support" + ], "html/webappapis/the-windoworworkerglobalscope-mixin/Worker_Self_Origin.html": [ "22b28b3e35ef5f05d18b4013798d6513c59c1700", "testharness" @@ -464514,7 +466023,7 @@ "support" ], "infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini": [ - "0bcdd374f2521b6534208ab750a1c0d36e7dd7ca", + "40a58e4153ec8c39c3ce6ce64e8bcaae391f3b68", "support" ], "infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection-following-subtest.html.ini": [ @@ -464526,7 +466035,7 @@ "support" ], "infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini": [ - "39773dfe714a6b5754bfe73c64294bcb38f2afa3", + "da4fe27e58959f7e3d6ba5ebbc7edd58a93dcf5c", "support" ], "infrastructure/metadata/infrastructure/reftest/reftest_and_fail.html.ini": [ @@ -464570,19 +466079,19 @@ "support" ], "infrastructure/metadata/infrastructure/server/context.any.js.ini": [ - "c3431d687b60aa1a07d9a4307ccfd4a2253ee162", + "ca095a18785a6d31070c02492a868c3b8d6e6606", "support" ], "infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini": [ - "8db9536e38cc880865c374f3743d7df9f727a530", + "23387657b41e99385f8fb9cbc0e46a7dd2626164", "support" ], "infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini": [ - "5f5ed991cf1b04da84e89d7eae2e0d80b9fd2841", + "5b24c9429dc6e75a1288379290f04b18ab050f2c", "support" ], "infrastructure/metadata/infrastructure/server/title.any.js.ini": [ - "e2a7b5578c3b0dec13206ec60da2a5c018c23eb1", + "8cbb5f76493c2c8e21f6c45223d4b551f5335b68", "support" ], "infrastructure/metadata/infrastructure/server/wpt-server-http.sub.html.ini": [ @@ -465454,7 +466963,7 @@ "support" ], "interfaces/web-animations.idl": [ - "6fd172ce425d570d097fcb573115091c83cc5484", + "0d5d40ba74f40ed68c19a8218710204b2767ae12", "support" ], "interfaces/web-bluetooth.idl": [ @@ -465466,7 +466975,7 @@ "support" ], "interfaces/web-share.idl": [ - "f433f2314becd82e7446cc00c96108d1f0efe681", + "a29107f05987369128593b9fb2bd3bb13017eae0", "support" ], "interfaces/webaudio.idl": [ @@ -465502,7 +467011,7 @@ "support" ], "interfaces/webrtc-stats.idl": [ - "2b823047ff1e37a13e9d2e71711360944019fcb5", + "3e58254baa45dbd9f94307326bf3f6fedce53b60", "support" ], "interfaces/webrtc.idl": [ @@ -468794,7 +470303,7 @@ "manual" ], "mediacapture-streams/MediaStream-MediaElement-srcObject.https.html": [ - "79100ab59fb65cc1eaccf7db0207c6f158f3e0e8", + "790f73ae7bd21bb118a104fc3c3e37d7895f5fe6", "testharness" ], "mediacapture-streams/MediaStream-add-audio-track.https.html": [ @@ -494506,7 +496015,7 @@ "support" ], "resources/chromium/nfc-mock.js": [ - "8924a26adb4fe28704d3ec017e8634e6527cb778", + "ce22a9c2cfe9c0ae460d6e1eff4aaa99fe6b24e3", "support" ], "resources/chromium/sensor.mojom.js": [ @@ -494566,7 +496075,7 @@ "support" ], "resources/chromium/webxr-test.js": [ - "ffb7f87ab0f2b772b696f37480b48447ac27c5ae", + "653dcac79f8f22e7143568fcf33543d210eb0127", "support" ], "resources/chromium/webxr-test.js.headers": [ @@ -494610,7 +496119,7 @@ "support" ], "resources/testharness.js": [ - "bed2856685478f1ac43bd1c655cdc57d3a1081ba", + "7fb1c0c8a52c1be6f2a54d9912e714f74922ee89", "support" ], "resources/testharness.js.headers": [ @@ -494761,8 +496270,8 @@ "e1b50f670105f3a05dacd3518d62770685121c67", "support" ], - "screen_enumeration/requestDisplays.tentative.https.any.js": [ - "e2a5bc427deb96275a1441141d53e2ffc7f8cd99", + "screen_enumeration/getScreens.tentative.https.any.js": [ + "0b8c226ddbd7035d29760b8afa84d8429a3d3482", "testharness" ], "scroll-animations/META.yml": [ @@ -494813,16 +496322,20 @@ "0320210f8394c7439353a6e1efd0eba339b27e20", "testharness" ], + "scroll-to-text-fragment/scroll-to-text-fragment-api.html": [ + "8b1dea6f331bf41b4759cadf6859f016848566fa", + "testharness" + ], "scroll-to-text-fragment/scroll-to-text-fragment-same-doc.html": [ "3bfd45382e55657b8f42d16f3a47c0188cd5c73f", "testharness" ], "scroll-to-text-fragment/scroll-to-text-fragment-target.html": [ - "cf8e29589701bc8fc91d201bd43b12e5d1302073", + "1ef9dbba519697c61529fba0e81dc64979257e70", "support" ], "scroll-to-text-fragment/scroll-to-text-fragment.html": [ - "eda63fa5b6477655a5a3ad44047f0dd6466f0b37", + "b3a35f489aca424b24c57b40796a179c5ee5b4c7", "testharness" ], "secure-contexts/META.yml": [ @@ -499910,7 +501423,7 @@ "testharness" ], "speech-api/SpeechSynthesis-speak-events.html": [ - "babfe3c388e92aee8c4e6ea62cd3c038eb5bcb2d", + "c559da1f92965d00c7532bfdad6e0cccad80c83a", "testharness" ], "speech-api/SpeechSynthesis-speak-ownership-expected.txt": [ @@ -500197,26 +501710,10 @@ "48bb81fca5cd7b7fb689c0ce7ed22e9894461e63", "support" ], - "streams/piping/abort.any-expected.txt": [ - "d85fa6d704d972c59296336120755ac134aef6a3", - "support" - ], "streams/piping/abort.any.js": [ "65c458aa2941ff64677ec976e05de5be264dda60", "testharness" ], - "streams/piping/abort.any.serviceworker-expected.txt": [ - "d85fa6d704d972c59296336120755ac134aef6a3", - "support" - ], - "streams/piping/abort.any.sharedworker-expected.txt": [ - "d85fa6d704d972c59296336120755ac134aef6a3", - "support" - ], - "streams/piping/abort.any.worker-expected.txt": [ - "d85fa6d704d972c59296336120755ac134aef6a3", - "support" - ], "streams/piping/close-propagation-backward.any.js": [ "99141e3120ffe2cb81120451434f08bc0d16318d", "testharness" @@ -500245,30 +501742,18 @@ "541cfad6243c12114dc683c68ce558e7c4d9a042", "testharness" ], - "streams/piping/pipe-through.any-expected.txt": [ - "372db5d0ee3948fd7350b216ae901bd21f0c9ef0", - "support" - ], "streams/piping/pipe-through.any.js": [ "868899c72665802f8083d367955a021321c2a3be", "testharness" ], - "streams/piping/pipe-through.any.serviceworker-expected.txt": [ - "372db5d0ee3948fd7350b216ae901bd21f0c9ef0", - "support" - ], - "streams/piping/pipe-through.any.sharedworker-expected.txt": [ - "372db5d0ee3948fd7350b216ae901bd21f0c9ef0", - "support" - ], - "streams/piping/pipe-through.any.worker-expected.txt": [ - "372db5d0ee3948fd7350b216ae901bd21f0c9ef0", - "support" - ], "streams/piping/then-interception.any.js": [ "3c85f6edb25b955645ccc5fedae3f0facdb36a2b", "testharness" ], + "streams/piping/throwing-options.any.js": [ + "6fab32cc6dcf4c2f4fb5a7a22999788f22459f4e", + "testharness" + ], "streams/piping/transform-streams.any.js": [ "368ed79da4786e0206d421d33076fe9fe61a14ba", "testharness" @@ -501261,6 +502746,10 @@ "56f67dc5ed1ceeeea347b703f5048b289f95131b", "testharness" ], + "svg/animations/short-simple-duration-and-fractional-repeatcount.html": [ + "025dd5092d3bb77707423b316f10bef8f2fb927d", + "testharness" + ], "svg/animations/single-values-animation.html": [ "40aa3461866cf4c32316d86216dcfe4298be7718", "testharness" @@ -501565,6 +503054,10 @@ "17b78a2787d0becf64b90136fcf0f6f966404baa", "testharness" ], + "svg/animations/switching-animated-target-to-unknown-element.html": [ + "fef86a723eebede0641f0fd46f7a2672b184457e", + "testharness" + ], "svg/animations/syncbase-remove-add-while-running.html": [ "61b9604a7b6751a156c48431b89fa2f3cd1af551", "testharness" @@ -503638,7 +505131,7 @@ "support" ], "tools/OWNERS": [ - "e1a1c69d26f27b9b8d36c08dc36eb06eb2b2f9cf", + "1cfc2ba5907a71ed1007031053a855bde4ebeea3", "support" ], "tools/__init__.py": [ @@ -508150,7 +509643,7 @@ "support" ], "tools/wptrunner/requirements.txt": [ - "d8a6c898d24f40c2bcffae42c32e63a9e5b10005", + "60775f8259eb317203825ea8fd5c26c901db5fad", "support" ], "tools/wptrunner/requirements_android_webview.txt": [ @@ -513749,6 +515242,10 @@ "a33d6d4f24676356b59b6b431968d8486df50615", "testharness" ], + "web-animations/idlharness.window.js": [ + "c32016280e659fe8268c87b58e4956a1eb81b399", + "testharness" + ], "web-animations/interfaces/Animatable/animate-expected.txt": [ "a69448468b1eb5de8f6fbb6df1fad60c14d27aab", "support" @@ -513809,10 +515306,6 @@ "793616d3006a7360f2e2e17639acd3529042083a", "support" ], - "web-animations/interfaces/Animation/idlharness.window.js": [ - "14b8395a2171db536ac5bbde964972a99defc41d", - "testharness" - ], "web-animations/interfaces/Animation/oncancel.html": [ "d5391196092c9671c2c22c1c035bc173bbef7b4f", "testharness" @@ -513865,10 +515358,6 @@ "1c40a3fb211c1bd3e33e6c6c6325b1d25e3b981d", "testharness" ], - "web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.js": [ - "5124e5095724521c721b8781dcfc92ff573f48e8", - "testharness" - ], "web-animations/interfaces/Document/getAnimations-expected.txt": [ "859827578a16c73324301d8d506f23ded98c4c64", "support" @@ -513889,10 +515378,6 @@ "ca0997ac8f9012b7d019760be97e09fa0f837179", "testharness" ], - "web-animations/interfaces/DocumentTimeline/idlharness.window.js": [ - "395d133f482a38a33ea5be061450f0f322be9fc9", - "testharness" - ], "web-animations/interfaces/DocumentTimeline/style-change-events.html": [ "c1607e6fb92943c580802025e4a4cc617a747144", "testharness" @@ -513921,10 +515406,6 @@ "461f7f2cf65778622d41016e16fddd79285bae8e", "support" ], - "web-animations/interfaces/KeyframeEffect/idlharness.window.js": [ - "22548861ae335c80858808cbe19f996f24a7edc9", - "testharness" - ], "web-animations/interfaces/KeyframeEffect/iterationComposite-expected.txt": [ "5319aefca8ebc4b276a13c936b91f71f2a3a9322", "support" @@ -514469,10 +515950,6 @@ "3bf3bc23b20764ba54d5ff125699df91fffe741a", "support" ], - "webaudio/refresh_idl.rb": [ - "a07847535ad7cae63b06c3d30333819cfef08b77", - "support" - ], "webaudio/resources/4ch-440.wav": [ "85dc1ea9044e28eeeac6176bae61285c25ebf711", "support" @@ -516462,7 +517939,7 @@ "support" ], "webgpu/cts.html": [ - "b60faec9623bb0adf7c1b9ad0e5d488ce14b5882", + "b66553df983d543453ed1f35cf20add65801481f", "testharness" ], "webgpu/framework/allowed_characters.js": [ @@ -516474,7 +517951,7 @@ "support" ], "webgpu/framework/fixture.js": [ - "2c1ea8314689e610528ba81254ee00e99242f4d5", + "127931223cb8b071606af2f08d97681c1a32f295", "support" ], "webgpu/framework/gpu/implementation.js": [ @@ -516498,7 +517975,7 @@ "support" ], "webgpu/framework/logger.js": [ - "e854292473640a21d6bb660a2a0999e740a90c8e", + "ee86919612d8725136f12879a58520004575138c", "support" ], "webgpu/framework/params/combine.js": [ @@ -516542,7 +518019,7 @@ "support" ], "webgpu/framework/test_group.js": [ - "69d8cc0401714f4f6ffe2ddfe0f8763b833914e5", + "68527a5b2cf55426ae779739fba788cfde94b244", "support" ], "webgpu/framework/tree.js": [ @@ -516562,7 +518039,7 @@ "support" ], "webgpu/framework/util/stack.js": [ - "ae99ac904a132d947f304ca0f03f50b25fd197ae", + "bd51d54509483954bb84ea9757b873ca42233cab", "support" ], "webgpu/framework/util/timeout.js": [ @@ -516570,7 +518047,7 @@ "support" ], "webgpu/framework/version.js": [ - "55a72f5efb03ad9043ea2600a311cfff249a21ce", + "154f0629b0dd367d3ef89ae4f200ce851b845f66", "support" ], "webgpu/runtime/helper/options.js": [ @@ -516586,7 +518063,7 @@ "testharness" ], "webgpu/runtime/wpt.js": [ - "c87f9167bbeba1edca847a76a6cb59401f0c7409", + "e078f6717471ad2364cf31587c55b4f24f2a3a00", "support" ], "webgpu/suites/cts/buffers/create_mapped.spec.js": [ @@ -516610,7 +518087,7 @@ "support" ], "webgpu/suites/cts/canvas/context_creation.spec.js": [ - "ba0d47228536da7192111f8bd7a6947de7c6181a", + "a693b002769ae9a1e951bc1888ca49ba393df7d0", "support" ], "webgpu/suites/cts/command_buffer/basic.spec.js": [ @@ -516618,7 +518095,7 @@ "support" ], "webgpu/suites/cts/command_buffer/compute/basic.spec.js": [ - "8fcc7ef9309b5a8760247f0c86ea374c0d3f3e14", + "8a5fc168a4d8fbed69ba5ee2009fc7049fdcf3a3", "support" ], "webgpu/suites/cts/command_buffer/copies.spec.js": [ @@ -516630,11 +518107,11 @@ "support" ], "webgpu/suites/cts/command_buffer/render/rendering.spec.js": [ - "46829a8d07cc51a04ad1ec323fdaf6f5b14e6cdc", + "43c4566799531fca8869500823c12feacd7d1522", "support" ], "webgpu/suites/cts/command_buffer/render/storeop.spec.js": [ - "0b38debc13425c87def0548f88085aa362a7a7cb", + "0326cf65ad69a1558a69b83df94622041d7eb1db", "support" ], "webgpu/suites/cts/examples.spec.js": [ @@ -516650,7 +518127,7 @@ "support" ], "webgpu/suites/cts/gpu_test.js": [ - "96f109d3043edf8f77d7cbfce88e13b348e44f58", + "272b1b831e8f42626f285b7e4bbdff3c0b6b6306", "support" ], "webgpu/suites/cts/index.js": [ @@ -516670,7 +518147,7 @@ "support" ], "webgpu/suites/cts/validation/createRenderPipeline.spec.js": [ - "cc838fc6515a5b9a7cc55bacc0361556a3bdd93c", + "b66dabf285a2c007e01356ed9c42a9cfe7eddc43", "support" ], "webgpu/suites/cts/validation/createTexture.spec.js": [ @@ -516694,7 +518171,7 @@ "support" ], "webgpu/suites/cts/validation/render_pass.spec.js": [ - "52da36fa7ac9cb196aaf578707acf09a7f62724d", + "3e08dcc17368ecb7a74d386c64e2166fb6baff66", "support" ], "webgpu/suites/cts/validation/render_pass_descriptor.spec.js": [ @@ -516718,7 +518195,7 @@ "support" ], "webgpu/suites/cts/validation/setVertexBuffer.spec.js": [ - "1df40173abe0eab97fe384b12df94f0e4ec03c3b", + "0f47e7324eb06aeb8d52c6e744932884ba2064ee", "support" ], "webgpu/suites/cts/validation/setViewport.spec.js": [ @@ -516730,7 +518207,7 @@ "support" ], "webgpu/suites/cts/validation/vertex_input.spec.js": [ - "951c9ead3cfc53569bbcfa322252edef3b672609", + "c5978025c9a777fd6e275fe7d2520092d3f39c8c", "support" ], "webmessaging/Channel_postMessage_Blob.htm": [ @@ -525442,7 +526919,7 @@ "support" ], "wpt.py": [ - "0736186c5d813f04a83fdd117974a9e1513dbff1", + "c65e1ed2c6cde4d3abd9e9a771f02542398fec49", "support" ], "x-frame-options/META.yml": [
diff --git a/third_party/blink/web_tests/external/wpt/css/css-lists/list-inside-contain-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-lists/list-inside-contain-expected.txt new file mode 100644 index 0000000..42e1de3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-lists/list-inside-contain-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/dynamic-visible-to-clip-001.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/dynamic-visible-to-clip-001.html index 08114d7..b97701b 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-overflow/dynamic-visible-to-clip-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/dynamic-visible-to-clip-001.html
@@ -1,4 +1,5 @@ <!doctype html> +<html class="reftest-wait"> <meta charset="utf-8"> <title>Overflow areas are updated when dynamically changed to overflow: clip</title> <link rel="help" href="https://drafts.csswg.org/css-overflow/#valdef-overflow-clip"> @@ -30,7 +31,10 @@ onload = function() { let target = document.getElementById("target"); window.unused = target.getBoundingClientRect(); // Update layout - target.style.overflow = "-moz-hidden-unscrollable"; - target.style.overflow = "clip"; + requestAnimationFrame(() => requestAnimationFrame(() => { + target.style.overflow = "-moz-hidden-unscrollable"; + target.style.overflow = "clip"; + document.documentElement.removeAttribute("class"); + })); } </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-001.html index f15adc9b..6975e81 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-001.html
@@ -6,6 +6,7 @@ <meta name="flags" content=""> <link rel="match" href="reference/overflow-wrap-min-content-size-001-ref.html"> <meta name="assert" content="Soft wrap opportunities introduced by overflow-wrap:anywhere **are** considered when calculating min-content intrinsic sizes."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> table { font: 20px/1 Ahem;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-004.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-004.html index 1fe8f94..16161ec 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-004.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/overflow-wrap-min-content-size-004.html
@@ -6,6 +6,7 @@ <meta name="flags" content="ahem"> <link rel="match" href="reference/overflow-wrap-min-content-size-004-ref.html"> <meta name="assert" content="Soft wrap opportunities introduced by overflow-wrap:break-word **are not** considered when calculating min-content intrinsic sizes."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> table { font: 20px/1 Ahem;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html index 1c87ab9a..ef5c2e8 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html
@@ -2,6 +2,7 @@ <meta charset="utf-8"> <title>CSS Text Test reference</title> <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> div { font: 20px/1 Ahem;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html index 6639eda..93e22ba 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/overflow-wrap/reference/overflow-wrap-min-content-size-004-ref.html
@@ -2,6 +2,7 @@ <meta charset="utf-8"> <title>CSS Text Test reference</title> <link rel="author" title="Florian Rivoal" href="http://florian.rivoal.net/"> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> div { font: 20px/1 Ahem;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/word-break/word-break-min-content-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/word-break/word-break-min-content-001.html index ba7009e7..a310e30 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-text/word-break/word-break-min-content-001.html +++ b/third_party/blink/web_tests/external/wpt/css/css-text/word-break/word-break-min-content-001.html
@@ -7,6 +7,7 @@ <meta name="flags" content=""> <link rel="match" href="../overflow-wrap/reference/overflow-wrap-min-content-size-001-ref.html"> <meta name="assert" content="word-break: break-word should behave as overflow-wrap: anywhere, so breaking opportunities **are** considered when calculating min-content intrinsic sizes."> +<link rel="stylesheet" type="text/css" href="/fonts/ahem.css"> <style> div { font: 20px/1 Ahem; } table {
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry-expected.txt b/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry-expected.txt deleted file mode 100644 index 2f827d6..0000000 --- a/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry-expected.txt +++ /dev/null
@@ -1,47 +0,0 @@ -This is a testharness.js-based test. -PASS CustomElementRegistry interface must have define as a method -PASS customElements.define must throw when the element interface is not a constructor -PASS customElements.define must not throw the constructor is HTMLElement -PASS customElements.define must throw with an invalid name -PASS customElements.define must throw when there is already a custom element of the same name -PASS customElements.define must throw a NotSupportedError when there is already a custom element with the same class -PASS customElements.define must throw a NotSupportedError when element definition is running flag is set -PASS customElements.define must check IsConstructor on the constructor before checking the element definition is running flag -PASS customElements.define must validate the custom element name before checking the element definition is running flag -PASS customElements.define unset the element definition is running flag before upgrading custom elements -FAIL customElements.define must not throw when defining another custom element in a different global object during Get(constructor, "prototype") Failed to execute 'define' on 'CustomElementRegistry': the name "another-custom-element" has already been used with this registry -PASS Custom Elements: CustomElementRegistry interface -FAIL customElements.define must get "prototype" property of the constructor assert_array_equals: lengths differ, expected 1 got 3 -PASS customElements.define must rethrow an exception thrown while getting "prototype" property of the constructor -PASS customElements.define must throw when "prototype" property of the constructor is not an object -PASS customElements.define must get callbacks of the constructor prototype -PASS customElements.define must rethrow an exception thrown while getting callbacks on the constructor prototype -PASS customElements.define must rethrow an exception thrown while converting a callback value to Function callback type -PASS customElements.define must get "observedAttributes" property on the constructor prototype when "attributeChangedCallback" is present -PASS customElements.define must rethrow an exception thrown while getting observedAttributes on the constructor prototype -PASS customElements.define must rethrow an exception thrown while converting the value of observedAttributes to sequence<DOMString> -PASS customElements.define must rethrow an exception thrown while iterating over observedAttributes to sequence<DOMString> -PASS customElements.define must rethrow an exception thrown while retrieving Symbol.iterator on observedAttributes -PASS customElements.define must not throw even if "observedAttributes" fails to convert if "attributeChangedCallback" is not defined -PASS customElements.define must rethrow an exception thrown while getting disabledFeatures on the constructor prototype -PASS customElements.define must rethrow an exception thrown while converting the value of disabledFeatures to sequence<DOMString> -PASS customElements.define must rethrow an exception thrown while iterating over disabledFeatures to sequence<DOMString> -PASS customElements.define must rethrow an exception thrown while retrieving Symbol.iterator on disabledFeatures -PASS customElements.define must rethrow an exception thrown while getting formAssociated on the constructor prototype -PASS customElements.define must get four additional callbacks on the prototype if formAssociated is converted to true -PASS customElements.define must rethrow an exception thrown while getting additional formAssociated callbacks on the constructor prototype -PASS customElements.define must define an instantiatable custom element -PASS customElements.define must upgrade elements in the shadow-including tree order -PASS CustomElementRegistry interface must have get as a method -PASS customElements.get must return undefined when the registry does not contain an entry with the given name -PASS customElements.get must return undefined when the registry does not contain an entry with the given name even if the name was not a valid custom element name -PASS customElements.get return the constructor of the entry with the given name when there is a matching entry. -PASS customElements.whenDefined must return a promise for a valid custom element name -PASS customElements.whenDefined must return the same promise each time invoked for a valid custom element name which has not been defined -PASS customElements.whenDefined must return an unresolved promise when the registry does not contain the entry with the given name -PASS customElements.whenDefined must return a rejected promise when the given name is not a valid custom element name -PASS customElements.whenDefined must return a resolved promise when the registry contains the entry with the given name -PASS customElements.whenDefined must return a new resolved promise each time invoked when the registry contains the entry with the given name -PASS A promise returned by customElements.whenDefined must be resolved by "define" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry.html b/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry.html index 368044df..c288e82 100644 --- a/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry.html +++ b/third_party/blink/web_tests/external/wpt/custom-elements/CustomElementRegistry.html
@@ -185,12 +185,15 @@ var proxy = new Proxy(class extends HTMLElement { }, { get: function (target, name) { calls.push(name); - iframe.contentWindow.customElements.define('another-custom-element', InnerCustomElement); + if (name === "prototype") { + iframe.contentWindow.customElements.define('another-custom-element', InnerCustomElement); + } return target[name]; } }) customElements.define('element-with-inner-element-define', proxy); - assert_array_equals(calls, ['prototype'], 'customElements.define must get "prototype"'); + assert_array_equals(calls, ['prototype', 'disabledFeatures', 'formAssociated'], + 'customElements.define must get "prototype", "disabledFeatures", and "formAssociated" on the constructor'); assert_true(iframe.contentDocument.createElement('another-custom-element') instanceof InnerCustomElement); }); document.body.removeChild(iframe); @@ -226,8 +229,8 @@ } }); customElements.define('proxy-element', proxy); - assert_array_equals(calls, ['prototype']); -}, 'customElements.define must get "prototype" property of the constructor'); + assert_array_equals(calls, ['prototype', 'disabledFeatures', 'formAssociated']); +}, 'customElements.define must get "prototype", "disabledFeatures", and "formAssociated" property of the constructor'); test(function () { var proxy = new Proxy(class extends HTMLElement { }, {
diff --git a/third_party/blink/web_tests/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt index f6bcb6a..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt +++ b/third_party/blink/web_tests/external/wpt/fetch/metadata/sec-fetch-dest/redirect/redirect-https-downgrade.tentative.sub-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL redirect-https-downgrade Uncaught SyntaxError: Unexpected token 'return' +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt index 2be08465..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt +++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_html_element-manual-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL graphics-document on HTML element Uncaught ReferenceError: ATTAcomm is not defined +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_svg_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_svg_element-manual-expected.txt index 6a1b58d..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_svg_element-manual-expected.txt +++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-document_on_svg_element-manual-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL graphics-document on SVG element Uncaught ReferenceError: ATTAcomm is not defined +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_html_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_html_element-manual-expected.txt index f735916..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_html_element-manual-expected.txt +++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_html_element-manual-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL graphics-object on HTML element Uncaught ReferenceError: ATTAcomm is not defined +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt index e5649930..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt +++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-object_on_svg_element-manual-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL graphics-object on SVG element Uncaught ReferenceError: ATTAcomm is not defined +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt index f57f1a03b..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt +++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_html_element-manual-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL graphics-symbol on HTML element Uncaught ReferenceError: ATTAcomm is not defined +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt index 98a13d5..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt +++ b/third_party/blink/web_tests/external/wpt/graphics-aam/graphics-symbol_on_svg_element-manual-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL graphics-symbol on SVG element Uncaught ReferenceError: ATTAcomm is not defined +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt index 9d1840b5..1bafd5c6 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https-expected.txt
@@ -7,5 +7,6 @@ FAIL Same-site popup with coop unsafe-inherit without coep assert_equals: expected "" but got "same-site-popup-with-coop-unsafe-inherit-without-coep" FAIL Same-origin popup without coep assert_equals: expected "" but got "popup-without-coep" FAIL Same-site popup without coep assert_equals: expected "" but got "same-site-popup-without-coep" +FAIL Bonus: window.crossOriginIsolated assert_true: expected true got undefined Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html index 1c04ed30..64994cdf 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/coep.https.html
@@ -40,4 +40,8 @@ coop_coep_test(t, SAME_SITE, variant.coop, variant.coep, `same-site-${variant.title.replace(/ /g,"-")}`, false); }, `Same-site ${variant.title}`); }); + +test(() => { + assert_true(window.crossOriginIsolated); +}, "Bonus: window.crossOriginIsolated"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https-expected.txt b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https-expected.txt new file mode 100644 index 0000000..9cd8ef4 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS Cross-Origin-Opener-Policy only works over secure contexts +FAIL Bonus: window.crossOriginIsolated assert_false: expected false got undefined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https.html index da9efdc..014ba1f 100644 --- a/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https.html +++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-opener-policy/no-https.html
@@ -15,4 +15,8 @@ t.done(); }, 500); }, "Cross-Origin-Opener-Policy only works over secure contexts"); + +test(() => { + assert_false(window.crossOriginIsolated); +}, "Bonus: window.crossOriginIsolated"); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/dom/usvstring-reflection.html b/third_party/blink/web_tests/external/wpt/html/dom/usvstring-reflection.https.html similarity index 100% rename from third_party/blink/web_tests/external/wpt/html/dom/usvstring-reflection.html rename to third_party/blink/web_tests/external/wpt/html/dom/usvstring-reflection.https.html
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt index 7b70ea2..d6e67e0 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-sharedworker-success.https-expected.txt
@@ -1,4 +1,5 @@ This is a testharness.js-based test. FAIL postMessaging to a dedicated sub-worker allows them to see each others' modifications Worker is not defined +FAIL Bonus: self.crossOriginIsolated assert_true: expected true got undefined Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https-expected.txt new file mode 100644 index 0000000..0c7bb4b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/nested-worker-success.https-expected.txt
@@ -0,0 +1,5 @@ +This is a testharness.js-based test. +PASS postMessaging to a dedicated sub-worker allows them to see each others' modifications +FAIL Bonus: self.crossOriginIsolated assert_true: expected true got undefined +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt index 03e29e36..3d3e7c3 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any-expected.txt
@@ -2,5 +2,6 @@ FAIL SharedArrayBuffer over MessageChannel without COOP+COEP assert_throws: function "() => channel.port1.postMessage(sab)" did not throw FAIL SharedArrayBuffer over BroadcastChannel without COOP+COEP assert_throws: function "() => channel.postMessage(sab)" did not throw FAIL SharedArrayBuffer over postMessage() without COOP+COEP assert_throws: function "() => self.postMessage(sab)" did not throw +FAIL Bonus: self.crossOriginIsolated assert_false: expected false got undefined Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js index 96276d7..a755865 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js
@@ -16,3 +16,7 @@ assert_throws("DataCloneError", () => self.postMessage(sab)); }, "SharedArrayBuffer over postMessage() without COOP+COEP"); } + +test(() => { + assert_false(self.crossOriginIsolated); +}, "Bonus: self.crossOriginIsolated");
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt index 6600416..35419f6 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.worker-expected.txt
@@ -1,5 +1,6 @@ This is a testharness.js-based test. FAIL SharedArrayBuffer over MessageChannel without COOP+COEP assert_throws: function "() => channel.port1.postMessage(sab)" did not throw FAIL SharedArrayBuffer over BroadcastChannel without COOP+COEP assert_throws: function "() => channel.postMessage(sab)" did not throw +FAIL Bonus: self.crossOriginIsolated assert_false: expected false got undefined Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js index 9befc90..ffc3708 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js
@@ -7,4 +7,8 @@ return testSharingViaIncrementerScript(t, worker, "parent worker", worker, "sub-worker"); }, "postMessaging to a dedicated sub-worker allows them to see each others' modifications"); +test(() => { + assert_true(self.crossOriginIsolated); +}, "Bonus: self.crossOriginIsolated"); + done();
diff --git a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt index 49cfaff..c960d0d 100644 --- a/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt +++ b/third_party/blink/web_tests/external/wpt/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window-expected.txt
@@ -7,7 +7,7 @@ PASS JS-engine-created TypeError (cross-site iframe) PASS web API-created TypeError (worker) PASS web API-created TypeError (cross-site iframe) -FAIL web API-created DOMException (worker) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:41:19)\n at Test.step (http://web-platform.test:8001/resources/testharness.js:1914:25)\n at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:40:3)\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined -FAIL web API-created DOMException (cross-site iframe) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:60:19)\n at Test.step (http://web-platform.test:8001/resources/testharness.js:1914:25)\n at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:57:3)\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined +FAIL web API-created DOMException (worker) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:41:19)\n at Test.step (http://web-platform.test:8001/resources/testharness.js:1917:25)\n at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:40:3)\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined +FAIL web API-created DOMException (cross-site iframe) assert_equals: expected (string) "Error: Failed to execute 'createElement' on 'Document': The tag name provided ('') is not a valid name.\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:33:14\n at Test.<anonymous> (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:60:19)\n at Test.step (http://web-platform.test:8001/resources/testharness.js:1917:25)\n at async_test (http://web-platform.test:8001/resources/testharness.js:576:22)\n at stackTests (http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:57:3)\n at http://web-platform.test:8001/html/infrastructure/safe-passing-of-structured-data/structured-cloning-error-stack-optional.sub.window.js:31:1" but got (undefined) undefined Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/README.md b/third_party/blink/web_tests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/README.md new file mode 100644 index 0000000..10ae3e5f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/README.md
@@ -0,0 +1 @@ +`self.crossOriginIsolated` is tested in `html/cross-origin-opener-policy/coep.https.html`, `html/cross-origin-opener-policy/no-https.html`, `html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/no-coop-coep.https.any.js`, and `html/infrastructure/safe-passing-of-structured-data/shared-array-buffers/resources/nested-worker-success.js`.
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt index 1765dd9..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt +++ b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/uncaught-exception-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Uncaught exception Uncaught Error: error outside any setup or test +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt index 3a828c8..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt +++ b/third_party/blink/web_tests/external/wpt/infrastructure/expected-fail/unhandled-rejection-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Unhandled rejection Unhandled rejection: error outside any setup or test +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini index 0bcdd374..40a58e41 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/uncaught-exception.html.ini
@@ -1,4 +1,2 @@ [uncaught-exception.html] - [Uncaught exception] - expected: FAIL - + expected: ERROR
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini index 39773df..da4fe27 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/expected-fail/unhandled-rejection.html.ini
@@ -1,4 +1,2 @@ [unhandled-rejection.html] - [Unhandled rejection] - expected: FAIL - + expected: ERROR
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini index c3431d6..ca095a18 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/context.any.js.ini
@@ -1,7 +1,6 @@ [context.any.sharedworker.html] - [context] - expected: - if product == "safari" or product == "epiphany" or product == "webkit": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850 + expected: + if product == "safari" or product == "epiphany" or product == "webkit": ERROR # https://bugs.webkit.org/show_bug.cgi?id=149850 [context.any.serviceworker.html] [context]
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini index 8db9536..2338765 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/order-of-metas.any.js.ini
@@ -1,6 +1,5 @@ [order-of-metas.any.sharedworker.html] - [foo] - expected: - if product == "safari" or product == "epiphany" or product == "webkit": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850 + expected: + if product == "safari" or product == "epiphany" or product == "webkit": ERROR # https://bugs.webkit.org/show_bug.cgi?id=149850
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini index 5f5ed991..5b24c942 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/secure-context.https.any.js.ini
@@ -1,7 +1,6 @@ [secure-context.https.any.sharedworker.html] - [secure-context] - expected: - if product == "safari" or product == "epiphany" or product == "webkit": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850 + expected: + if product == "safari" or product == "epiphany" or product == "webkit": ERROR # https://bugs.webkit.org/show_bug.cgi?id=149850 [secure-context.https.any.serviceworker.html] [secure-context]
diff --git a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini index e2a7b55..8cbb5f7 100644 --- a/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini +++ b/third_party/blink/web_tests/external/wpt/infrastructure/metadata/infrastructure/server/title.any.js.ini
@@ -1,6 +1,5 @@ [title.any.sharedworker.html] - [foobar] - expected: - if product == "safari" or product == "epiphany" or product == "webkit": FAIL # https://bugs.webkit.org/show_bug.cgi?id=149850 + expected: + if product == "safari" or product == "epiphany" or product == "webkit": ERROR # https://bugs.webkit.org/show_bug.cgi?id=149850
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-animations.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-animations.idl index 6fd172c..0d5d40ba 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/web-animations.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/web-animations.idl
@@ -92,11 +92,12 @@ [Exposed=Window] interface KeyframeEffect : AnimationEffect { - constructor((Element or CSSPseudoElement)? target, + constructor(Element? target, object? keyframes, optional (unrestricted double or KeyframeEffectOptions) options = {}); constructor(KeyframeEffect source); - attribute (Element or CSSPseudoElement)? target; + attribute Element? target; + attribute CSSOMString? pseudoElement; attribute CompositeOperation composite; sequence<object> getKeyframes(); void setKeyframes(object? keyframes); @@ -122,7 +123,8 @@ }; dictionary KeyframeEffectOptions : EffectTiming { - CompositeOperation composite = "replace"; + CompositeOperation composite = "replace"; + CSSOMString? pseudoElement = null; }; enum CompositeOperation { "replace", "add", "accumulate" }; @@ -153,8 +155,6 @@ Element includes Animatable; -CSSPseudoElement includes Animatable; - [Exposed=Window] interface AnimationPlaybackEvent : Event { constructor(DOMString type, optional AnimationPlaybackEventInit eventInitDict = {});
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/web-share.idl b/third_party/blink/web_tests/external/wpt/interfaces/web-share.idl index f433f23..a29107f 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/web-share.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/web-share.idl
@@ -1,7 +1,7 @@ // GENERATED CONTENT - DO NOT EDIT // Content was automatically extracted by Reffy into reffy-reports // (https://github.com/tidoust/reffy-reports) -// Source: Web Share API - Level 1 (https://w3c.github.io/web-share/) +// Source: Web Share API (https://w3c.github.io/web-share/) partial interface Navigator { [SecureContext] Promise<void> share(optional ShareData data = {});
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl index 2b82304..3e58254b 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-stats.idl
@@ -78,6 +78,8 @@ double framesPerSecond; unsigned long long qpSum; double totalDecodeTime; + double totalInterFrameDelay; + double totalSquaredInterFrameDelay; boolean voiceActivityFlag; DOMHighResTimeStamp lastPacketReceivedTimestamp; double averageRtcpInterval;
diff --git a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html index 79100ab5..790f73a 100644 --- a/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html +++ b/third_party/blink/web_tests/external/wpt/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html
@@ -12,6 +12,7 @@ the success callback in getUserMedia can be properly assigned to a video element via the <code>srcObject</code> attribute.</p> +<audio id="aud"></audio> <video id="vid"></video> <div id='log'></div> @@ -21,6 +22,11 @@ 'use strict'; const vid = document.getElementById("vid"); +function queueTask(f) { + window.onmessage = f; + window.postMessage("hi"); +} + promise_test(async t => { const stream = await navigator.mediaDevices.getUserMedia({video: true}); t.add_cleanup(() => { @@ -307,6 +313,112 @@ // otherwise the media element sets currentTime to 0 without ending. await new Promise(r => vid.onended = r); }, "Tests that the loop attribute has no effect on a media element with an assigned MediaStream"); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({video: true}); + t.add_cleanup(() => { vid.srcObject = null; }); + vid.srcObject = stream; + + await vid.play(); + + for (const track of stream.getTracks()) { + track.stop(); + } + + assert_false(stream.active, "MediaStream becomes inactive with only ended tracks"); + assert_false(vid.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (sync)"); + + await Promise.resolve(); + assert_false(vid.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (microtask)"); + + let ended = false; + vid.onended = () => ended = true; + await new Promise(r => queueTask(r)); + + assert_true(vid.ended, "HTMLMediaElement becomes ended asynchronously when its MediaStream provider becomes inactive"); + assert_true(ended, "HTMLMediaElement fires the ended event asynchronously when its MediaStream provider becomes inactive"); +}, "Tests that a media element with an assigned MediaStream ends when the MediaStream becomes inactive through tracks ending"); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true}); + t.add_cleanup(() => { + aud.srcObject = null; + stream.getTracks().forEach(track => track.stop()); + }); + aud.srcObject = stream; + + await aud.play(); + + for (const track of stream.getAudioTracks()) { + track.stop(); + } + + assert_true(stream.active, "MediaStream is still active with a live video track"); + assert_false(aud.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (sync)"); + + await Promise.resolve(); + assert_false(aud.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (microtask)"); + + let ended = false; + aud.onended = () => ended = true; + await new Promise(r => queueTask(r)); + + assert_true(aud.ended, "HTMLAudioElement becomes ended asynchronously when its MediaStream provider becomes inaudible"); + assert_true(ended, "HTMLAudioElement fires the ended event asynchronously when its MediaStream provider becomes inaudible"); +}, "Tests that an audio element with an assigned MediaStream ends when the MediaStream becomes inaudible through audio tracks ending"); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({video: true}); + t.add_cleanup(() => { vid.srcObject = null; }); + vid.srcObject = stream; + + await vid.play(); + + for (const track of stream.getTracks()) { + stream.removeTrack(track); + } + + assert_false(stream.active, "MediaStream becomes inactive with no tracks"); + assert_false(vid.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (sync)"); + + await Promise.resolve(); + assert_false(vid.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (microtask)"); + + let ended = false; + vid.onended = () => ended = true; + await new Promise(r => queueTask(r)); + + assert_true(vid.ended, "HTMLMediaElement becomes ended asynchronously when its MediaStream provider becomes inactive"); + assert_true(ended, "HTMLMediaElement fires the ended event asynchronously when its MediaStream provider becomes inactive"); +}, "Tests that a media element with an assigned MediaStream ends when the MediaStream becomes inactive through track removal"); + +promise_test(async t => { + const stream = await navigator.mediaDevices.getUserMedia({audio: true, video: true}); + t.add_cleanup(() => { + aud.srcObject = null; + stream.getTracks().forEach(track => track.stop()); + }); + aud.srcObject = stream; + + await aud.play(); + + for (const track of stream.getAudioTracks()) { + stream.removeTrack(track); + } + + assert_true(stream.active, "MediaStream is still active with a live video track"); + assert_false(aud.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (sync)"); + + await Promise.resolve(); + assert_false(aud.ended, "HTMLMediaElement reports ended the next time the event loop reaches step 1 (microtask)"); + + let ended = false; + aud.onended = () => ended = true; + await new Promise(r => queueTask(r)); + + assert_true(aud.ended, "HTMLAudioElement becomes ended asynchronously when its MediaStream provider becomes inaudible"); + assert_true(ended, "HTMLAudioElement fires the ended event asynchronously when its MediaStream provider becomes inaudible"); +}, "Tests that an audio element with an assigned MediaStream ends when the MediaStream becomes inaudible through track removal"); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt index f30628b..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-handler/change-payment-method-manual.https-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changePaymentMethod() Unhandled rejection: Not allowed to install this payment handler +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-address-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-address-manual.https-expected.txt index de7d406..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-address-manual.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-address-manual.https-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changeShippingAddress() Unhandled rejection: Not allowed to install this payment handler +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt index 4b23059b..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-handler/change-shipping-option-manual.https-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent.changeShippingOption() Unhandled rejection: Not allowed to install this payment handler +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt index a00a329..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-handler/payment-request-event-manual.https-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Tests for PaymentRequestEvent Unhandled rejection: Not allowed to install this payment handler +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt index 149709f31..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-handler/supports-shipping-contact-delegation-manual.https-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Tests for Delegation of shipping and contact collection to PH Unhandled rejection: Not allowed to install this payment handler +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-is-showing.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-is-showing.https-expected.txt index f04ac0a..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-is-showing.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-is-showing.https-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Test for PaymentRequest.show(optional promise) method Uncaught TypeError: Cannot set property 'click' of undefined +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt index 0f09114..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt +++ b/third_party/blink/web_tests/external/wpt/payment-request/payment-request-canmakepayment-method-protection.https-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL Tests for PaymentRequest.canMakePayment() method Uncaught TypeError: Cannot set property 'click' of undefined +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/resources/testharness.js b/third_party/blink/web_tests/external/wpt/resources/testharness.js index bed28566..7fb1c0c 100644 --- a/third_party/blink/web_tests/external/wpt/resources/testharness.js +++ b/third_party/blink/web_tests/external/wpt/resources/testharness.js
@@ -792,7 +792,10 @@ function done() { if (tests.tests.length === 0) { - tests.set_file_is_test(); + tests.status.status = tests.status.ERROR; + tests.status.message = "done() was called without first defining any tests"; + tests.complete(); + return; } if (tests.file_is_test) { // file is test files never have asynchronous cleanup logic, @@ -3379,9 +3382,6 @@ */ function assert(expected_true, function_name, description, error, substitutions) { - if (tests.tests.length === 0) { - tests.set_file_is_test(); - } if (expected_true !== true) { var msg = make_message(function_name, description, error, substitutions); @@ -3672,10 +3672,6 @@ if (global_scope.addEventListener) { var error_handler = function(message, stack) { - if (tests.tests.length === 0 && !tests.allow_uncaught_exception) { - tests.set_file_is_test(); - } - if (tests.file_is_test) { var test = tests.tests[0]; if (test.phase >= test.phases.HAS_RESULT) { @@ -3710,15 +3706,17 @@ }, false); addEventListener("unhandledrejection", function(e) { - var reason; - if (e.reason) { - reason = e.reason.message ? e.reason.message : e.reason; + var message; + if (e.reason && e.reason.message) { + message = "Unhandled rejection: " + e.reason.message; } else { - reason = e; + message = "Unhandled rejection"; } - var message = "Unhandled rejection: " + reason; - // There's no stack for unhandled rejections. - error_handler(message); + var stack; + if (e.reason && e.reason.stack) { + stack = e.reason.stack; + } + error_handler(message, stack); }, false); }
diff --git a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html index babfe3c..c559da1 100644 --- a/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html +++ b/third_party/blink/web_tests/external/wpt/speech-api/SpeechSynthesis-speak-events.html
@@ -5,14 +5,18 @@ <script src="/resources/testdriver-vendor.js"></script> <body> <script> -async_test(t => { - test_driver.bless('speechSynthesis.speak', t.step_func(() => { - const utter = new SpeechSynthesisUtterance('test'); - utter.onerror = t.unreached_func('error event'); - speechSynthesis.speak(utter); - utter.onstart = t.step_func(() => { - utter.onend = t.step_func_done(); - }); - })); +async function runStartEndTest(t, utterance) { + const eventWatcher = new EventWatcher(t, utterance, ['start', 'end', 'error']); + await test_driver.bless('speechSynthesis.speak', + () => speechSynthesis.speak(utterance)); + await eventWatcher.wait_for(['start', 'end']); +} +promise_test(async (t) => { + const utterance = new SpeechSynthesisUtterance(); + await runStartEndTest(t, utterance); +}, 'speechSynthesis.speak() fires start and end events with empty utterance'); +promise_test(async (t) => { + const utterance = new SpeechSynthesisUtterance('test'); + await runStartEndTest(t, utterance); }, 'speechSynthesis.speak() fires start and end events'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt index 8ec519e1..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL construct-byob-request Uncaught RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt index 6e0da30..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.serviceworker-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL construct-byob-request Unhandled rejection: Failed to register a ServiceWorker for scope ('https://web-platform.test:8444/streams/readable-byte-streams/does/not/exist') with script ('https://web-platform.test:8444/streams/readable-byte-streams/construct-byob-request.any.worker.js'): ServiceWorker script evaluation failed +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt index 8ec519e1..42e1de3 100644 --- a/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt +++ b/third_party/blink/web_tests/external/wpt/streams/readable-byte-streams/construct-byob-request.any.worker-expected.txt
@@ -1,4 +1,4 @@ This is a testharness.js-based test. -FAIL construct-byob-request Uncaught RangeError: Failed to construct 'ReadableStream': bytes type is not yet implemented +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt index d8a6c898..60775f82 100644 --- a/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt +++ b/third_party/blink/web_tests/external/wpt/tools/wptrunner/requirements.txt
@@ -5,4 +5,4 @@ pillow==6.2.1 urllib3[secure]==1.25.6 requests==2.22.0 -six==1.12.0 +six==1.13.0
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window-expected.txt b/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window-expected.txt new file mode 100644 index 0000000..38f05e8 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window-expected.txt
@@ -0,0 +1,147 @@ +This is a testharness.js-based test. +Found 143 tests; 131 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN. +PASS idl_test setup +PASS idl_test validation +PASS Partial interface Document: original interface defined +PASS Partial interface Document: member names are unique +PASS Partial interface mixin DocumentOrShadowRoot: original interface mixin defined +PASS Partial interface mixin DocumentOrShadowRoot: member names are unique +PASS Partial interface Document[2]: member names are unique +PASS Partial interface Document[3]: member names are unique +PASS Element includes Animatable: member names are unique +PASS Element includes ParentNode: member names are unique +PASS Element includes NonDocumentTypeChildNode: member names are unique +PASS Element includes ChildNode: member names are unique +PASS Element includes Slotable: member names are unique +PASS Document includes NonElementParentNode: member names are unique +PASS Document includes DocumentOrShadowRoot: member names are unique +PASS Document includes ParentNode: member names are unique +PASS Document includes XPathEvaluatorBase: member names are unique +PASS Document includes GlobalEventHandlers: member names are unique +PASS Document includes DocumentAndElementEventHandlers: member names are unique +PASS DocumentFragment includes NonElementParentNode: member names are unique +PASS DocumentFragment includes ParentNode: member names are unique +PASS ShadowRoot includes DocumentOrShadowRoot: member names are unique +PASS AnimationTimeline interface: existence and properties of interface object +PASS AnimationTimeline interface object length +PASS AnimationTimeline interface object name +PASS AnimationTimeline interface: existence and properties of interface prototype object +PASS AnimationTimeline interface: existence and properties of interface prototype object's "constructor" property +PASS AnimationTimeline interface: existence and properties of interface prototype object's @@unscopables property +PASS AnimationTimeline interface: attribute currentTime +PASS DocumentTimeline interface: existence and properties of interface object +PASS DocumentTimeline interface object length +PASS DocumentTimeline interface object name +PASS DocumentTimeline interface: existence and properties of interface prototype object +PASS DocumentTimeline interface: existence and properties of interface prototype object's "constructor" property +PASS DocumentTimeline interface: existence and properties of interface prototype object's @@unscopables property +PASS DocumentTimeline must be primary interface of document.timeline +PASS Stringification of document.timeline +PASS AnimationTimeline interface: document.timeline must inherit property "currentTime" with the proper type +PASS Animation interface: existence and properties of interface object +PASS Animation interface object length +PASS Animation interface object name +PASS Animation interface: existence and properties of interface prototype object +PASS Animation interface: existence and properties of interface prototype object's "constructor" property +PASS Animation interface: existence and properties of interface prototype object's @@unscopables property +PASS Animation interface: attribute id +PASS Animation interface: attribute effect +PASS Animation interface: attribute timeline +PASS Animation interface: attribute startTime +PASS Animation interface: attribute currentTime +PASS Animation interface: attribute playbackRate +PASS Animation interface: attribute playState +FAIL Animation interface: attribute replaceState assert_true: The prototype object must have a property "replaceState" expected true got false +PASS Animation interface: attribute pending +PASS Animation interface: attribute ready +PASS Animation interface: attribute finished +PASS Animation interface: attribute onfinish +PASS Animation interface: attribute oncancel +FAIL Animation interface: attribute onremove assert_true: The prototype object must have a property "onremove" expected true got false +PASS Animation interface: operation cancel() +PASS Animation interface: operation finish() +PASS Animation interface: operation play() +PASS Animation interface: operation pause() +PASS Animation interface: operation updatePlaybackRate(double) +PASS Animation interface: operation reverse() +FAIL Animation interface: operation persist() assert_own_property: interface prototype object missing non-static operation expected property "persist" missing +FAIL Animation interface: operation commitStyles() assert_own_property: interface prototype object missing non-static operation expected property "commitStyles" missing +PASS Animation must be primary interface of new Animation() +PASS Stringification of new Animation() +PASS Animation interface: new Animation() must inherit property "id" with the proper type +PASS Animation interface: new Animation() must inherit property "effect" with the proper type +PASS Animation interface: new Animation() must inherit property "timeline" with the proper type +PASS Animation interface: new Animation() must inherit property "startTime" with the proper type +PASS Animation interface: new Animation() must inherit property "currentTime" with the proper type +PASS Animation interface: new Animation() must inherit property "playbackRate" with the proper type +PASS Animation interface: new Animation() must inherit property "playState" with the proper type +FAIL Animation interface: new Animation() must inherit property "replaceState" with the proper type assert_inherits: property "replaceState" not found in prototype chain +PASS Animation interface: new Animation() must inherit property "pending" with the proper type +PASS Animation interface: new Animation() must inherit property "ready" with the proper type +PASS Animation interface: new Animation() must inherit property "finished" with the proper type +PASS Animation interface: new Animation() must inherit property "onfinish" with the proper type +PASS Animation interface: new Animation() must inherit property "oncancel" with the proper type +FAIL Animation interface: new Animation() must inherit property "onremove" with the proper type assert_inherits: property "onremove" not found in prototype chain +PASS Animation interface: new Animation() must inherit property "cancel()" with the proper type +PASS Animation interface: new Animation() must inherit property "finish()" with the proper type +PASS Animation interface: new Animation() must inherit property "play()" with the proper type +PASS Animation interface: new Animation() must inherit property "pause()" with the proper type +PASS Animation interface: new Animation() must inherit property "updatePlaybackRate(double)" with the proper type +PASS Animation interface: calling updatePlaybackRate(double) on new Animation() with too few arguments must throw TypeError +PASS Animation interface: new Animation() must inherit property "reverse()" with the proper type +FAIL Animation interface: new Animation() must inherit property "persist()" with the proper type assert_inherits: property "persist" not found in prototype chain +FAIL Animation interface: new Animation() must inherit property "commitStyles()" with the proper type assert_inherits: property "commitStyles" not found in prototype chain +PASS AnimationEffect interface: existence and properties of interface object +PASS AnimationEffect interface object length +PASS AnimationEffect interface object name +PASS AnimationEffect interface: existence and properties of interface prototype object +PASS AnimationEffect interface: existence and properties of interface prototype object's "constructor" property +PASS AnimationEffect interface: existence and properties of interface prototype object's @@unscopables property +PASS AnimationEffect interface: operation getTiming() +PASS AnimationEffect interface: operation getComputedTiming() +PASS AnimationEffect interface: operation updateTiming(OptionalEffectTiming) +PASS KeyframeEffect interface: existence and properties of interface object +PASS KeyframeEffect interface object length +PASS KeyframeEffect interface object name +PASS KeyframeEffect interface: existence and properties of interface prototype object +PASS KeyframeEffect interface: existence and properties of interface prototype object's "constructor" property +PASS KeyframeEffect interface: existence and properties of interface prototype object's @@unscopables property +PASS KeyframeEffect interface: attribute target +FAIL KeyframeEffect interface: attribute pseudoElement assert_true: The prototype object must have a property "pseudoElement" expected true got false +PASS KeyframeEffect interface: attribute composite +PASS KeyframeEffect interface: operation getKeyframes() +PASS KeyframeEffect interface: operation setKeyframes(object) +PASS KeyframeEffect must be primary interface of new KeyframeEffect(null, null) +PASS Stringification of new KeyframeEffect(null, null) +PASS KeyframeEffect interface: new KeyframeEffect(null, null) must inherit property "target" with the proper type +FAIL KeyframeEffect interface: new KeyframeEffect(null, null) must inherit property "pseudoElement" with the proper type assert_inherits: property "pseudoElement" not found in prototype chain +PASS KeyframeEffect interface: new KeyframeEffect(null, null) must inherit property "composite" with the proper type +PASS KeyframeEffect interface: new KeyframeEffect(null, null) must inherit property "getKeyframes()" with the proper type +PASS KeyframeEffect interface: new KeyframeEffect(null, null) must inherit property "setKeyframes(object)" with the proper type +PASS KeyframeEffect interface: calling setKeyframes(object) on new KeyframeEffect(null, null) with too few arguments must throw TypeError +PASS AnimationEffect interface: new KeyframeEffect(null, null) must inherit property "getTiming()" with the proper type +PASS AnimationEffect interface: new KeyframeEffect(null, null) must inherit property "getComputedTiming()" with the proper type +PASS AnimationEffect interface: new KeyframeEffect(null, null) must inherit property "updateTiming(OptionalEffectTiming)" with the proper type +PASS AnimationEffect interface: calling updateTiming(OptionalEffectTiming) on new KeyframeEffect(null, null) with too few arguments must throw TypeError +PASS AnimationPlaybackEvent interface: existence and properties of interface object +PASS AnimationPlaybackEvent interface object length +PASS AnimationPlaybackEvent interface object name +PASS AnimationPlaybackEvent interface: existence and properties of interface prototype object +PASS AnimationPlaybackEvent interface: existence and properties of interface prototype object's "constructor" property +PASS AnimationPlaybackEvent interface: existence and properties of interface prototype object's @@unscopables property +PASS AnimationPlaybackEvent interface: attribute currentTime +PASS AnimationPlaybackEvent interface: attribute timelineTime +PASS AnimationPlaybackEvent must be primary interface of new AnimationPlaybackEvent("cancel") +PASS Stringification of new AnimationPlaybackEvent("cancel") +PASS AnimationPlaybackEvent interface: new AnimationPlaybackEvent("cancel") must inherit property "currentTime" with the proper type +PASS AnimationPlaybackEvent interface: new AnimationPlaybackEvent("cancel") must inherit property "timelineTime" with the proper type +PASS Document interface: attribute timeline +PASS Document interface: operation getAnimations() +PASS Document interface: document must inherit property "timeline" with the proper type +PASS Document interface: document must inherit property "getAnimations()" with the proper type +FAIL ShadowRoot interface: operation getAnimations() assert_own_property: interface prototype object missing non-static operation expected property "getAnimations" missing +FAIL ShadowRoot interface: shadowRoot must inherit property "getAnimations()" with the proper type assert_inherits: property "getAnimations" not found in prototype chain +PASS Element interface: operation animate(object, [object Object],[object Object]) +PASS Element interface: operation getAnimations(GetAnimationsOptions) +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window.js b/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window.js new file mode 100644 index 0000000..c320162 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/web-animations/idlharness.window.js
@@ -0,0 +1,20 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js + +'use strict'; + +idl_test( + ['web-animations'], + ['dom', 'html'], + idl_array => { + idl_array.add_objects({ + Animation: ['new Animation()'], + AnimationPlaybackEvent: ['new AnimationPlaybackEvent("cancel")'], + Document: ['document'], + DocumentTimeline: ['document.timeline'], + KeyframeEffect: ['new KeyframeEffect(null, null)'], + ShadowRoot: ['shadowRoot'], + }); + self.shadowRoot = document.createElement("div").attachShadow({mode: "open"}); + } +);
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/idlharness.window.js b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/idlharness.window.js deleted file mode 100644 index 14b8395..0000000 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/Animation/idlharness.window.js +++ /dev/null
@@ -1,21 +0,0 @@ -// META: script=/resources/WebIDLParser.js -// META: script=/resources/idlharness.js - -// https://w3c.github.io/web-animations/#animation - -'use strict'; - -promise_test(async () => { - const srcs = ['web-animations', 'dom', 'html']; - const [idl, dom, html] = await Promise.all( - srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); - - const idlArray = new IdlArray(); - idlArray.add_idls(idl, {only: ['Animation', 'AnimationPlayState']}); - idlArray.add_dependency_idls(idl); - idlArray.add_dependency_idls(dom); - idlArray.add_dependency_idls(html); - idlArray.add_untested_idls('interface CSSPseudoElement {};'); - idlArray.add_objects( { Animation: ['new Animation()'] } ); - idlArray.test(); -}, 'Animation interface.');
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.js b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.js deleted file mode 100644 index 5124e50..0000000 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/AnimationPlaybackEvent/idlharness.window.js +++ /dev/null
@@ -1,26 +0,0 @@ -// META: script=/resources/WebIDLParser.js -// META: script=/resources/idlharness.js - -// https://w3c.github.io/web-animations/#animationplaybackevent - -'use strict'; - -promise_test(async () => { - const srcs = ['web-animations', 'dom']; - const [idl, dom] = await Promise.all( - srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); - - const idlArray = new IdlArray(); - idlArray.add_idls(idl, { - only: [ - 'AnimationPlaybackEventInit', - 'AnimationPlaybackEvent', - ] - }); - idlArray.add_dependency_idls(dom); - idlArray.add_objects({ - AnimationPlaybackEvent: ['new AnimationPlaybackEvent("cancel")'], - }); - - idlArray.test(); -}, 'AnimationPlaybackEvent interface.');
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/idlharness.window.js b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/idlharness.window.js deleted file mode 100644 index 395d133..0000000 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/DocumentTimeline/idlharness.window.js +++ /dev/null
@@ -1,22 +0,0 @@ -// META: script=/resources/WebIDLParser.js -// META: script=/resources/idlharness.js - -// https://w3c.github.io/web-animations/#documenttimeline - -'use strict'; - -promise_test(async () => { - const text = await fetch('/interfaces/web-animations.idl').then(r => r.text()); - const idlArray = new IdlArray(); - idlArray.add_idls(text, { - only: [ - 'AnimationTimeline', - 'DocumentTimelineOptions', - 'DocumentTimeline', - ] - }); - idlArray.add_objects({ DocumentTimeline: ['document.timeline'] }); - - idlArray.test(); - done(); -}, 'DocumentTimeline interface.');
diff --git a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/idlharness.window.js b/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/idlharness.window.js deleted file mode 100644 index 22548861..0000000 --- a/third_party/blink/web_tests/external/wpt/web-animations/interfaces/KeyframeEffect/idlharness.window.js +++ /dev/null
@@ -1,31 +0,0 @@ -// META: script=/resources/WebIDLParser.js -// META: script=/resources/idlharness.js - -// https://w3c.github.io/web-animations/#keyframeeffect - -'use strict'; - -promise_test(async () => { - const srcs = ['web-animations', 'html']; - const [idl, html] = await Promise.all( - srcs.map(i => fetch(`/interfaces/${i}.idl`).then(r => r.text()))); - - const idlArray = new IdlArray(); - idlArray.add_idls(idl, { - only: [ - 'IterationCompositeOperation', - 'CompositeOperation', - 'KeyframeEffectOptions', - 'KeyframeEffect', - ] - }); - idlArray.add_untested_idls('interface CSSPseudoElement {};'); - idlArray.add_dependency_idls(idl); - idlArray.add_dependency_idls(html); - idlArray.add_objects({ - KeyframeEffect: ['new KeyframeEffect(null, null)'], - }); - - idlArray.test(); - done(); -}, 'KeyframeEffect interface.');
diff --git a/third_party/blink/web_tests/external/wpt/webaudio/refresh_idl.rb b/third_party/blink/web_tests/external/wpt/webaudio/refresh_idl.rb deleted file mode 100755 index a0784753..0000000 --- a/third_party/blink/web_tests/external/wpt/webaudio/refresh_idl.rb +++ /dev/null
@@ -1,57 +0,0 @@ -#!/usr/bin/env ruby -require 'nokogiri' - -def base_dir - File.dirname(__FILE__) -end - -def output_directory - File.join(base_dir, 'idl') -end - -def specification - file = File.open(File.join(base_dir, 'specification.html')) - doc = Nokogiri::XML(file) - file.close - doc -end - -def write_node_inner_text_to_file(filename, node) - File.open(filename, 'w') { |file| file.write(node.inner_text.strip) } - puts "Wrote: #{filename}" -end - -def load_idl(id) - file = File.join(output_directory, id) - return false if !File.exist?(file) - File.read(file) -end - -# Parse the specification writing each block of idl to its own file -specification.css(".idl-code").each do |idl_block| - id = idl_block["id"] - write_node_inner_text_to_file(File.join(output_directory, id), idl_block) if id -end - -# Update the idl in the pre blocks for each idl test -idl_test_files = [ - File.join(base_dir, 'the-audio-api', 'the-gainnode-interface', 'idl-test.html'), - File.join(base_dir, 'the-audio-api', 'the-audiodestinationnode-interface', 'idl-test.html'), - File.join(base_dir, 'the-audio-api', 'the-delaynode-interface', 'idl-test.html'), - File.join(base_dir, 'the-audio-api', 'the-audiobuffer-interface', 'idl-test.html'), -] - -idl_test_files.each do |fn| - file = File.open(fn) - doc = Nokogiri::HTML(file) - file.close - - doc.css('pre').each do |node| - node_id = node["id"] - if idl = load_idl(node_id) - node.content = idl - end - end - - File.open(fn, 'w') { |file| file.write(doc.to_html)} -end
diff --git a/third_party/blink/web_tests/external/wpt/wpt.py b/third_party/blink/web_tests/external/wpt/wpt.py index 0736186c..c65e1ed2c 100644 --- a/third_party/blink/web_tests/external/wpt/wpt.py +++ b/third_party/blink/web_tests/external/wpt/wpt.py
@@ -1 +1,3 @@ -execfile("wpt") \ No newline at end of file +# This file exists to allow `python wpt <command>` to work on Windows: +# https://github.com/web-platform-tests/wpt/pull/6907 +execfile("wpt")
diff --git a/third_party/blink/web_tests/fast/text/mac-aat-morx-kern.html b/third_party/blink/web_tests/fast/text/mac-aat-morx-kern.html new file mode 100644 index 0000000..7cead172 --- /dev/null +++ b/third_party/blink/web_tests/fast/text/mac-aat-morx-kern.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<style> +.gillsanstest { +font-family: Gill Sans; +font-size: 60px; +} +</style> +<p>y needs to be kerned under the T on Gill Sans on Mac for weights under 700. <a href="https://crbug.com/1004945">https://crbug.com/1004945</a></p> +<div class="gillsanstest" style="font-weight: 300;">TyTo</div> +<div class="gillsanstest" style="font-weight: 500;">TyTo</div> +<div class="gillsanstest" style="font-weight: 600;">TyTo</div> +<div class="gillsanstest" style="font-weight: 700;">TyTo</div> +<div class="gillsanstest" style="font-weight: 800;">TyTo</div>
diff --git a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/international/complex-character-based-fallback-expected.png b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/international/complex-character-based-fallback-expected.png index 3869a74..86fd887 100644 --- a/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/international/complex-character-based-fallback-expected.png +++ b/third_party/blink/web_tests/platform/mac-mac10.10/virtual/text-antialias/international/complex-character-based-fallback-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/css1/font_properties/font_family-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/css1/font_properties/font_family-expected.png deleted file mode 100644 index 2733d4ea..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.11/css1/font_properties/font_family-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/css2.1/t1503-c522-font-family-00-b-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/css2.1/t1503-c522-font-family-00-b-expected.png deleted file mode 100644 index f7e90a75..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.11/css2.1/t1503-c522-font-family-00-b-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png new file mode 100644 index 0000000..c4bf06bb --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.11/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/fonts/fantasy-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/fonts/fantasy-expected.png deleted file mode 100644 index f6e0d7c7..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.11/fonts/fantasy-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/text-antialias/international/complex-character-based-fallback-expected.png b/third_party/blink/web_tests/platform/mac-mac10.11/virtual/text-antialias/international/complex-character-based-fallback-expected.png deleted file mode 100644 index d464d81..0000000 --- a/third_party/blink/web_tests/platform/mac-mac10.11/virtual/text-antialias/international/complex-character-based-fallback-expected.png +++ /dev/null Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.12/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png b/third_party/blink/web_tests/platform/mac-mac10.12/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png new file mode 100644 index 0000000..2dc6636 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac-mac10.12/fast/dom/rtl-scroll-to-leftmost-and-resize-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css1/font_properties/font_family-expected.png b/third_party/blink/web_tests/platform/mac/css1/font_properties/font_family-expected.png index 02c8c9e..2733d4ea 100644 --- a/third_party/blink/web_tests/platform/mac/css1/font_properties/font_family-expected.png +++ b/third_party/blink/web_tests/platform/mac/css1/font_properties/font_family-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/css2.1/t1503-c522-font-family-00-b-expected.png b/third_party/blink/web_tests/platform/mac/css2.1/t1503-c522-font-family-00-b-expected.png index 458ad41..f7e90a75 100644 --- a/third_party/blink/web_tests/platform/mac/css2.1/t1503-c522-font-family-00-b-expected.png +++ b/third_party/blink/web_tests/platform/mac/css2.1/t1503-c522-font-family-00-b-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fast/text/mac-aat-morx-kern-expected.png b/third_party/blink/web_tests/platform/mac/fast/text/mac-aat-morx-kern-expected.png new file mode 100644 index 0000000..1992dabf --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/fast/text/mac-aat-morx-kern-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/fonts/fantasy-expected.png b/third_party/blink/web_tests/platform/mac/fonts/fantasy-expected.png index 63c2816..f6e0d7c7 100644 --- a/third_party/blink/web_tests/platform/mac/fonts/fantasy-expected.png +++ b/third_party/blink/web_tests/platform/mac/fonts/fantasy-expected.png Binary files differ
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/README.md b/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/README.md deleted file mode 100644 index ac81ca3..0000000 --- a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/README.md +++ /dev/null
@@ -1,5 +0,0 @@ -# virtual/cross-origin-embedder-policy - -https://crbug.com/887967 - -Cross-Origin-Embedder-Policy (COEP)
diff --git a/third_party/blink/web_tests/virtual/cross-origin-isolation/README.md b/third_party/blink/web_tests/virtual/cross-origin-isolation/README.md new file mode 100644 index 0000000..d051641 --- /dev/null +++ b/third_party/blink/web_tests/virtual/cross-origin-isolation/README.md
@@ -0,0 +1,7 @@ +# virtual/cross-origin-isolation + +https://crbug.com/922191 +https://crbug.com/887967 + +Cross-Origin-Opener-Policy (COOP) +Cross-Origin-Embedder-Policy (COEP)
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/README.md b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/README.md similarity index 100% rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/README.md rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/README.md
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/blob.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/data.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/data.https-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/data.https-expected.txt rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/data.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/none-sw-from-require-corp.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/none-sw-from-require-corp.https-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/none-sw-from-require-corp.https-expected.txt rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/none-sw-from-require-corp.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-require-corp.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-require-corp.https-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-require-corp.https-expected.txt rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp-sw-from-require-corp.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp.https-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/require-corp.https-expected.txt rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/require-corp.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/sandbox.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/sandbox.https-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/sandbox.https-expected.txt rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/sandbox.https-expected.txt
diff --git a/third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/srcdoc.https-expected.txt b/third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/srcdoc.https-expected.txt similarity index 100% rename from third_party/blink/web_tests/virtual/cross-origin-embedder-policy/external/wpt/html/cross-origin-embedder-policy/srcdoc.https-expected.txt rename to third_party/blink/web_tests/virtual/cross-origin-isolation/external/wpt/html/cross-origin-embedder-policy/srcdoc.https-expected.txt
diff --git a/third_party/blink/web_tests/wpt_internal/infrastructure/wpt-server-http.sub-expected.txt b/third_party/blink/web_tests/wpt_internal/infrastructure/wpt-server-http.sub-expected.txt new file mode 100644 index 0000000..42e1de3 --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/infrastructure/wpt-server-http.sub-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +Harness Error. harness_status.status = 1 , harness_status.message = done() was called without first defining any tests +Harness: the test ran to completion. +
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 83a2b8e..d7dd216a 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-10-1-72-gb75031a26 -Revision: b75031a26eed8838222ddb3a81bc1672a0e463a8 +Version: VER-2-10-1-73-g3aaae716b +Revision: 3aaae716b25bd2d3232e279bc05af65cff446dd9 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses" License File: src/docs/FTL.TXT
diff --git a/third_party/harfbuzz-ng/BUILD.gn b/third_party/harfbuzz-ng/BUILD.gn index 8403845..26553bc 100644 --- a/third_party/harfbuzz-ng/BUILD.gn +++ b/third_party/harfbuzz-ng/BUILD.gn
@@ -223,7 +223,6 @@ "src/src/hb-unicode.cc", "src/src/hb-unicode.hh", "src/src/hb-utf.hh", - "src/src/hb-warning.cc", "src/src/hb.hh", ]
diff --git a/third_party/harfbuzz-ng/README.chromium b/third_party/harfbuzz-ng/README.chromium index b636820..6f1fb6a 100644 --- a/third_party/harfbuzz-ng/README.chromium +++ b/third_party/harfbuzz-ng/README.chromium
@@ -1,9 +1,9 @@ Name: harfbuzz-ng Short Name: harfbuzz-ng URL: http://harfbuzz.org -Version: 2.6.2-45 -Date: 20191016 -Revision: e637a4b3de2fb8bdbc1b82e822f4a6cc579e794b +Version: 2.6.4-5 +Date: 20191104 +Revision: 7cde68f10cdf2c3ff77c1d9077475c0fc034c75c Security Critical: yes License: MIT License File: src/COPYING
diff --git a/third_party/zlib/google/compression_utils.cc b/third_party/zlib/google/compression_utils.cc index d1218d7..9f63a840 100644 --- a/third_party/zlib/google/compression_utils.cc +++ b/third_party/zlib/google/compression_utils.cc
@@ -42,7 +42,7 @@ const uLongf input_size = static_cast<uLongf>(input.size()); uLongf compressed_data_size = - zlib_internal::GZipExpectedCompressedSize(input_size); + zlib_internal::GzipExpectedCompressedSize(input_size); Bytef* compressed_data; if (!base::UncheckedMalloc(compressed_data_size, @@ -109,7 +109,7 @@ } uint32_t GetUncompressedSize(base::StringPiece compressed_data) { - return zlib_internal::GetUncompressedSize( + return zlib_internal::GetGzipUncompressedSize( bit_cast<Bytef*>(compressed_data.data()), compressed_data.length()); }
diff --git a/third_party/zlib/google/compression_utils_portable.cc b/third_party/zlib/google/compression_utils_portable.cc index f4f36b6..21338b5 100644 --- a/third_party/zlib/google/compression_utils_portable.cc +++ b/third_party/zlib/google/compression_utils_portable.cc
@@ -28,13 +28,13 @@ // The expected compressed size is based on the input size factored by // internal Zlib constants (e.g. window size, etc) plus the wrapper // header size. -uLongf GZipExpectedCompressedSize(uLongf input_size) { +uLongf GzipExpectedCompressedSize(uLongf input_size) { return kGzipZlibHeaderDifferenceBytes + compressBound(input_size); } // The expected decompressed size is stored in the last -// 4 bytes of |input| in LE. -uint32_t GetUncompressedSize(const Bytef* compressed_data, size_t length) { +// 4 bytes of |input| in LE. See https://tools.ietf.org/html/rfc1952#page-5 +uint32_t GetGzipUncompressedSize(const Bytef* compressed_data, size_t length) { uint32_t size; if (length < sizeof(size)) return 0; @@ -47,15 +47,39 @@ #endif } -// This code is taken almost verbatim from third_party/zlib/compress.c. The only -// difference is deflateInit2() is called which sets the window bits to be > 16. -// That causes a gzip header to be emitted rather than a zlib header. +// The number of window bits determines the type of wrapper to use - see +// https://cs.chromium.org/chromium/src/third_party/zlib/zlib.h?l=566 +inline int ZlibStreamWrapperType(WrapperType type) { + if (type == ZLIB) // zlib DEFLATE stream wrapper + return MAX_WBITS; + if (type == GZIP) // gzip DEFLATE stream wrapper + return MAX_WBITS + kWindowBitsToGetGzipHeader; + if (type == ZRAW) // no wrapper, use raw DEFLATE + return -MAX_WBITS; + return 0; +} + int GzipCompressHelper(Bytef* dest, uLongf* dest_length, const Bytef* source, uLong source_length, void* (*malloc_fn)(size_t), void (*free_fn)(void*)) { + return CompressHelper(GZIP, dest, dest_length, source, source_length, + malloc_fn, free_fn); +} + +// This code is taken almost verbatim from third_party/zlib/compress.c. The only +// difference is deflateInit2() is called which allows different window bits to +// be set. > 16 causes a gzip header to be emitted rather than a zlib header, +// and negative causes no header to emitted. +int CompressHelper(WrapperType wrapper_type, + Bytef* dest, + uLongf* dest_length, + const Bytef* source, + uLong source_length, + void* (*malloc_fn)(size_t), + void (*free_fn)(void*)) { z_stream stream; // FIXME(cavalcantii): z_const is not defined as 'const'. @@ -94,17 +118,21 @@ stream.opaque = static_cast<voidpf>(0); } - gz_header gzip_header; - memset(&gzip_header, 0, sizeof(gzip_header)); int err = deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, - MAX_WBITS + kWindowBitsToGetGzipHeader, - kZlibMemoryLevel, Z_DEFAULT_STRATEGY); + ZlibStreamWrapperType(wrapper_type), kZlibMemoryLevel, + Z_DEFAULT_STRATEGY); if (err != Z_OK) return err; - err = deflateSetHeader(&stream, &gzip_header); - if (err != Z_OK) - return err; + // This has to exist outside of the if statement to prevent it going off the + // stack before deflate(), which will use this object. + gz_header gzip_header; + if (wrapper_type == GZIP) { + memset(&gzip_header, 0, sizeof(gzip_header)); + err = deflateSetHeader(&stream, &gzip_header); + if (err != Z_OK) + return err; + } err = deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { @@ -117,13 +145,22 @@ return err; } -// This code is taken almost verbatim from third_party/zlib/uncompr.c. The only -// difference is inflateInit2() is called which sets the window bits to be > 16. -// That causes a gzip header to be parsed rather than a zlib header. int GzipUncompressHelper(Bytef* dest, uLongf* dest_length, const Bytef* source, uLong source_length) { + return UncompressHelper(GZIP, dest, dest_length, source, source_length); +} + +// This code is taken almost verbatim from third_party/zlib/uncompr.c. The only +// difference is inflateInit2() is called which allows different window bits to +// be set. > 16 causes a gzip header to be emitted rather than a zlib header, +// and negative causes no header to emitted. +int UncompressHelper(WrapperType wrapper_type, + Bytef* dest, + uLongf* dest_length, + const Bytef* source, + uLong source_length) { z_stream stream; // FIXME(cavalcantii): z_const is not defined as 'const'. @@ -140,7 +177,7 @@ stream.zalloc = static_cast<alloc_func>(0); stream.zfree = static_cast<free_func>(0); - int err = inflateInit2(&stream, MAX_WBITS + kWindowBitsToGetGzipHeader); + int err = inflateInit2(&stream, ZlibStreamWrapperType(wrapper_type)); if (err != Z_OK) return err;
diff --git a/third_party/zlib/google/compression_utils_portable.h b/third_party/zlib/google/compression_utils_portable.h index 5f8b46ed..7c3753b 100644 --- a/third_party/zlib/google/compression_utils_portable.h +++ b/third_party/zlib/google/compression_utils_portable.h
@@ -17,9 +17,15 @@ namespace zlib_internal { -uLongf GZipExpectedCompressedSize(uLongf input_size); +enum WrapperType { + ZLIB, + GZIP, + ZRAW, +}; -uint32_t GetUncompressedSize(const Bytef* compressed_data, size_t length); +uLongf GzipExpectedCompressedSize(uLongf input_size); + +uint32_t GetGzipUncompressedSize(const Bytef* compressed_data, size_t length); int GzipCompressHelper(Bytef* dest, uLongf* dest_length, @@ -28,11 +34,25 @@ void* (*malloc_fn)(size_t), void (*free_fn)(void*)); +int CompressHelper(WrapperType wrapper_type, + Bytef* dest, + uLongf* dest_length, + const Bytef* source, + uLong source_length, + void* (*malloc_fn)(size_t), + void (*free_fn)(void*)); + int GzipUncompressHelper(Bytef* dest, uLongf* dest_length, const Bytef* source, uLong source_length); +int UncompressHelper(WrapperType wrapper_type, + Bytef* dest, + uLongf* dest_length, + const Bytef* source, + uLong source_length); + } // namespace zlib_internal #endif // THIRD_PARTY_ZLIB_GOOGLE_COMPRESSION_UTILS_PORTABLE_H_
diff --git a/tools/binary_size/libsupersize/caspian/BUILD.gn b/tools/binary_size/libsupersize/caspian/BUILD.gn index 116a14dc..e31449f8 100644 --- a/tools/binary_size/libsupersize/caspian/BUILD.gn +++ b/tools/binary_size/libsupersize/caspian/BUILD.gn
@@ -39,6 +39,7 @@ ":caspian-lib", "//testing/gtest", "//testing/gtest:gtest_main", + "//third_party/re2:re2", ] }
diff --git a/tools/binary_size/libsupersize/caspian/function_signature.cc b/tools/binary_size/libsupersize/caspian/function_signature.cc index a211185..721588b 100644 --- a/tools/binary_size/libsupersize/caspian/function_signature.cc +++ b/tools/binary_size/libsupersize/caspian/function_signature.cc
@@ -1,13 +1,15 @@ // 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 +// found in the LICENSE file. // Much of this logic is duplicated at // tools/binary_size/libsupersize/function_signature.py. #include <stddef.h> +#include <algorithm> #include <deque> +#include <iostream> #include <string> #include <string_view> #include <tuple> @@ -15,6 +17,20 @@ #include "tools/binary_size/libsupersize/caspian/function_signature.h" +namespace { +bool EndsWith(std::string_view str, + std::string_view suffix, + size_t pos = std::string_view::npos) { + pos = std::min(pos, str.size()); + size_t span = suffix.size(); + return pos >= span && str.substr(pos - span, span) == suffix; +} + +std::string_view Slice(std::string_view sv, size_t lo, size_t hi) { + return sv.substr(lo, hi - lo); +} +} // namespace + namespace caspian { std::vector<std::string_view> SplitBy(std::string_view str, char delim) { std::vector<std::string_view> ret; @@ -32,6 +48,8 @@ std::tuple<std::string_view, std::string_view, std::string_view> ParseJava( std::string_view full_name, std::deque<std::string>* owned_strings) { + // |owned_strings| is used as an allocator, the relative order of its + // elements can be arbitrary. std::string maybe_member_type; size_t hash_idx = full_name.find('#'); std::string_view full_class_name; @@ -42,7 +60,7 @@ // Format: Class#symbol: type full_class_name = full_name.substr(0, hash_idx); size_t colon_idx = full_name.find(':'); - member = full_name.substr(hash_idx + 1, colon_idx - hash_idx - 1); + member = Slice(full_name, hash_idx + 1, colon_idx); if (colon_idx != std::string_view::npos) { member_type = full_name.substr(colon_idx); } @@ -81,4 +99,232 @@ return std::make_tuple(full_name, template_name, name); } + +size_t FindLastCharOutsideOfBrackets(std::string_view name, + char target_char, + size_t prev_idx) { + int paren_balance_count = 0; + int angle_balance_count = 0; + std::string_view prefix = name.substr(0, prev_idx); + while (true) { + size_t idx = prefix.rfind(target_char); + if (idx == std::string_view::npos) { + return std::string_view::npos; + } + for (char c : prefix.substr(idx)) { + switch (c) { + case '<': + angle_balance_count++; + break; + case '>': + angle_balance_count--; + break; + case '(': + paren_balance_count++; + break; + case ')': + paren_balance_count--; + break; + } + } + if (angle_balance_count == 0 && paren_balance_count == 0) { + return idx; + } + prefix = prefix.substr(0, idx); + } +} + +size_t FindReturnValueSpace(std::string_view name, size_t paren_idx) { + size_t space_idx = paren_idx; + // Special case: const cast operators (see tests). + if (EndsWith(name, " const", paren_idx)) { + space_idx = paren_idx - 6; + } + while (true) { + space_idx = FindLastCharOutsideOfBrackets(name, ' ', space_idx); + // Special cases: "operator new", "operator< <templ>", "operator<< <tmpl>". + // No space is added for operator>><tmpl>. + // Currently does not handle operator->, operator->* + if (std::string_view::npos == space_idx) { + break; + } + if (EndsWith(name, "operator", space_idx)) { + space_idx -= 8; + } else if (EndsWith(name, "operator<", space_idx)) { + space_idx -= 9; + } else if (EndsWith(name, "operator<<", space_idx)) { + space_idx -= 10; + } else { + break; + } + } + return space_idx; +} + +std::string StripTemplateArgs(std::string name) { + size_t last_right_idx = std::string::npos; + while (true) { + last_right_idx = name.substr(0, last_right_idx).rfind('>'); + if (last_right_idx == std::string_view::npos) { + return name; + } + size_t left_idx = + FindLastCharOutsideOfBrackets(name, '<', last_right_idx + 1); + if (left_idx != std::string_view::npos) { + // Leave in empty <>s to denote that it's a template. + name = std::string(name.substr(0, left_idx + 1)) + + std::string(name.substr(last_right_idx)); + last_right_idx = left_idx; + } + } +} + +std::string NormalizeTopLevelGccLambda(std::string_view name, + size_t left_paren_idx) { + // cc::{lambda(PaintOp*)#63}::_FUN(cc:PaintOp*) + // -> cc::$lambda#63(cc:PaintOp*) + + size_t left_brace_idx = name.find('{'); + if (left_brace_idx == std::string_view::npos) { + exit(1); + } + size_t hash_idx = name.find('#', left_brace_idx + 1); + if (hash_idx == std::string_view::npos) { + exit(1); + } + size_t right_brace_idx = name.find('}', hash_idx + 1); + if (right_brace_idx == std::string_view::npos) { + exit(1); + } + std::string_view number = Slice(name, hash_idx + 1, right_brace_idx); + + std::string ret; + ret += name.substr(0, left_brace_idx); + ret += "$lambda#"; + ret += number; + ret += name.substr(left_paren_idx); + return ret; +} + +std::string NormalizeTopLevelClangLambda(std::string_view name, + size_t left_paren_idx) { + // cc::$_21::__invoke(int) -> cc::$lambda#21(int) + size_t dollar_idx = name.find('$'); + if (dollar_idx == std::string_view::npos) { + exit(1); + } + size_t colon_idx = name.find(':', dollar_idx + 1); + if (colon_idx == std::string_view::npos) { + exit(1); + } + std::string_view number = Slice(name, dollar_idx + 2, colon_idx); + + std::string ret; + ret += name.substr(0, dollar_idx); + ret += "$lambda#"; + ret += number; + ret += name.substr(left_paren_idx); + return ret; +} + +size_t FindParameterListParen(std::string_view name) { + size_t start_idx = 0; + int angle_balance_count = 0; + int paren_balance_count = 0; + while (true) { + size_t idx = name.find('(', start_idx); + if (idx == std::string_view::npos) { + return std::string_view::npos; + } + for (char c : Slice(name, start_idx, idx)) { + switch (c) { + case '<': + angle_balance_count++; + break; + case '>': + angle_balance_count--; + break; + case '(': + paren_balance_count++; + break; + case ')': + paren_balance_count--; + break; + } + } + size_t operator_offset = Slice(name, start_idx, idx).find("operator<"); + if (operator_offset != std::string_view::npos) { + if (name[start_idx + operator_offset + 9] == '<') { + // Handle operator<<, <<= + angle_balance_count -= 2; + } else { + // Handle operator<= + angle_balance_count -= 1; + } + } else { + operator_offset = Slice(name, start_idx, idx).find("operator>"); + if (operator_offset != std::string_view::npos) { + if (name[start_idx + operator_offset + 9] == '>') { + // Handle operator>>,>>= + angle_balance_count += 2; + } else { + // Handle operator>= + angle_balance_count += 1; + } + } + } + + // Adjust paren + if (angle_balance_count == 0 && paren_balance_count == 0) { + // Special case: skip "(anonymous namespace)". + if (name.substr(idx, 21) == "(anonymous namespace)") { + start_idx = idx + 21; + continue; + } + // Special case: skip "decltype (...)" + // Special case: skip "{lambda(PaintOp*)#63}" + if (idx && name[idx - 1] != ' ' && !EndsWith(name, "{lambda", idx)) { + return idx; + } + } + + start_idx = idx + 1; + paren_balance_count++; + } +} + +std::tuple<std::string, std::string, std::string> ParseCpp( + const std::string& input_name) { + std::string name = input_name; + size_t left_paren_idx = FindParameterListParen(input_name); + std::string full_name = input_name; + if (left_paren_idx != std::string::npos && left_paren_idx > 0) { + size_t right_paren_idx = name.rfind(')'); + if (right_paren_idx <= left_paren_idx) { + std::cerr << "ParseCpp() received bad symbol: " << name << std::endl; + exit(1); + } + size_t space_idx = FindReturnValueSpace(name, left_paren_idx); + std::string name_no_params = + std::string(Slice(name, space_idx + 1, left_paren_idx)); + // Special case for top-level lambdas. + if (EndsWith(name_no_params, "}::_FUN")) { + // Don't use |name_no_params| in here since prior _idx will be off if + // there was a return value. + name = NormalizeTopLevelGccLambda(name, left_paren_idx); + return ParseCpp(name); + } else if (EndsWith(name_no_params, "::__invoke") && + name_no_params.find('$') != std::string::npos) { + name = NormalizeTopLevelClangLambda(name, left_paren_idx); + return ParseCpp(name); + } + + full_name = name.substr(space_idx + 1); + name = name_no_params + name.substr(right_paren_idx + 1); + } + + std::string template_name = name; + name = StripTemplateArgs(name); + return std::make_tuple(full_name, template_name, name); +} } // namespace caspian
diff --git a/tools/binary_size/libsupersize/caspian/function_signature.h b/tools/binary_size/libsupersize/caspian/function_signature.h index ed40599..d8961cc 100644 --- a/tools/binary_size/libsupersize/caspian/function_signature.h +++ b/tools/binary_size/libsupersize/caspian/function_signature.h
@@ -23,6 +23,37 @@ std::tuple<std::string_view, std::string_view, std::string_view> ParseJava( std::string_view full_name, std::deque<std::string>* owned_strings); + +// Strips return type and breaks function signature into parts. +// See unit tests for example signatures. +// Returns: +// A tuple of: +// * name without return type (symbol.full_name), +// * full_name without params (symbol.template_name), +// * full_name without params and template args (symbol.name) +std::tuple<std::string, std::string, std::string> ParseCpp( + const std::string& name); + +// Returns the last index of |target_char| that is not within ()s nor <>s. +size_t FindLastCharOutsideOfBrackets(std::string_view name, + char target_char, + size_t prev_idx = std::string::npos); + +// Finds index of the "(" that denotes the start of a parameter list. +size_t FindParameterListParen(std::string_view name); + +// Returns the index of the space that comes after the return type. +size_t FindReturnValueSpace(std::string_view name, size_t paren_idx); + +// Different compilers produce different lambda symbols. These utility +// functions standardize the two, so we can compare between compilers. +std::string NormalizeTopLevelGccLambda(std::string_view name, + size_t left_paren_idx); +std::string NormalizeTopLevelClangLambda(std::string_view name, + size_t left_paren_idx); + +// Strips the contents of <>, leaving empty <>s to denote that it's a template. +std::string StripTemplateArgs(std::string name); } // namespace caspian #endif // TOOLS_BINARY_SIZE_LIBSUPERSIZE_CASPIAN_FUNCTION_SIGNATURE_H_
diff --git a/tools/binary_size/libsupersize/caspian/function_signature_test.cc b/tools/binary_size/libsupersize/caspian/function_signature_test.cc index 6dfb5edc..3bcdc5d 100644 --- a/tools/binary_size/libsupersize/caspian/function_signature_test.cc +++ b/tools/binary_size/libsupersize/caspian/function_signature_test.cc
@@ -9,6 +9,7 @@ #include <tuple> #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/re2/src/re2/re2.h" namespace { std::tuple<std::string, std::string, std::string> PrettyDebug( @@ -36,6 +37,59 @@ EXPECT_EQ(expected_output, caspian::SplitBy(input, '/')); } +TEST(AnalyzeTest, FindLastCharOutsideOfBrackets) { + EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("(a)a", 'a'), 3u); + EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("abc(a)a", 'a'), 6u); + EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("(b)aaa", 'b'), + std::string::npos); + EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("", 'b'), std::string::npos); + + EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("a(a)a", 'a', 4u), 0u); + EXPECT_EQ(caspian::FindLastCharOutsideOfBrackets("a<<>", '<', 4u), 2u); +} + +TEST(AnalyzeTest, FindParameterListParen) { + EXPECT_EQ(caspian::FindParameterListParen("a()"), 1u); + EXPECT_EQ( + caspian::FindParameterListParen( + "bool foo::Bar<unsigned int, int>::Do<unsigned int>(unsigned int)"), + 50u); + EXPECT_EQ(caspian::FindParameterListParen( + "std::basic_ostream<char, std::char_traits<char> >& " + "std::operator<< <std::char_traits<char> " + ">(std::basic_ostream<char, std::char_traits<char> >&, char)"), + 92u); +} + +TEST(AnalyzeTest, FindReturnValueSpace) { + EXPECT_EQ(caspian::FindReturnValueSpace("bool a()", 6u), 4u); + EXPECT_EQ(caspian::FindReturnValueSpace("operator delete(void*)", 15), + std::string::npos); + EXPECT_EQ( + caspian::FindReturnValueSpace( + "bool foo::Bar<unsigned int, int>::Do<unsigned int>(unsigned int)", + 50u), + 4u); + EXPECT_EQ(caspian::FindReturnValueSpace( + "std::basic_ostream<char, std::char_traits<char> >& " + "std::operator<< <std::char_traits<char> " + ">(std::basic_ostream<char, std::char_traits<char> >&, char)", + 92u), + 50u); +} + +TEST(AnalyzeTest, NormalizeTopLevelGccLambda) { + EXPECT_EQ(caspian::NormalizeTopLevelGccLambda( + "cc::{lambda(PaintOp*)#63}::_FUN()", 31u), + "cc::$lambda#63()"); +} + +TEST(AnalyzeTest, NormalizeTopLevelClangLambda) { + // cc::$_21::__invoke() -> cc::$lambda#21() + EXPECT_EQ(caspian::NormalizeTopLevelClangLambda("cc::$_21::__invoke()", 18u), + "cc::$lambda#21()"); +} + TEST(AnalyzeTest, ParseJavaFunctionSignature) { ::std::deque<std::string> owned_strings; // Java method with no args @@ -71,4 +125,118 @@ do_test("org.ClassName some.Type mField", "org.ClassName#mField: some.Type", "org.ClassName#mField", "ClassName#mField"); } + +TEST(AnalyzeTest, ParseFunctionSignature) { + auto check = [](std::string ret_part, std::string name_part, + std::string params_part, std::string after_part = "", + std::string name_without_templates = "") { + if (name_without_templates.empty()) { + name_without_templates = name_part; + // Heuristic to drop templates: std::vector<int> -> std::vector<> + RE2::GlobalReplace(&name_without_templates, "<.*?>", "<>"); + name_without_templates += after_part; + } + std::string signature = name_part + params_part + after_part; + auto result = caspian::ParseCpp(signature); + EXPECT_EQ(name_without_templates, std::get<2>(result)); + EXPECT_EQ(name_part + after_part, std::get<1>(result)); + EXPECT_EQ(name_part + params_part + after_part, std::get<0>(result)); + + if (!ret_part.empty()) { + // Parse should be unchanged when we prepend |ret_part| + signature = ret_part + name_part + params_part + after_part; + result = caspian::ParseCpp(signature); + EXPECT_EQ(name_without_templates, std::get<2>(result)); + EXPECT_EQ(name_part + after_part, std::get<1>(result)); + EXPECT_EQ(name_part + params_part + after_part, std::get<0>(result)); + } + }; + + check("bool ", "foo::Bar<unsigned int, int>::Do<unsigned int>", + "(unsigned int)"); + check("base::internal::CheckedNumeric<int>& ", + "base::internal::CheckedNumeric<int>::operator+=<int>", "(int)"); + check("base::internal::CheckedNumeric<int>& ", + "b::i::CheckedNumeric<int>::MathOp<b::i::CheckedAddOp, int>", "(int)"); + check("", "(anonymous namespace)::GetBridge", "(long long)"); + check("", "operator delete", "(void*)"); + check("", + "b::i::DstRangeRelationToSrcRangeImpl<long long, long long, " + "std::__ndk1::numeric_limits, (b::i::Integer)1>::Check", + "(long long)"); + check("", "cc::LayerIterator::operator cc::LayerIteratorPosition const", "()", + " const"); + check("decltype ({parm#1}((SkRecords::NoOp)())) ", + "SkRecord::Record::visit<SkRecords::Draw&>", "(SkRecords::Draw&)", + " const"); + check("", "base::internal::BindStateBase::BindStateBase", + "(void (*)(), void (*)(base::internal::BindStateBase const*))"); + check("int ", "std::__ndk1::__c11_atomic_load<int>", + "(std::__ndk1::<int> volatile*, std::__ndk1::memory_order)"); + check("std::basic_ostream<char, std::char_traits<char> >& ", + "std::operator<< <std::char_traits<char> >", + "(std::basic_ostream<char, std::char_traits<char> >&, char)", "", + "std::operator<< <>"); + check("", + "std::basic_istream<char, std::char_traits<char> >" + "::operator>>", + "(unsigned int&)", "", "std::basic_istream<>::operator>>"); + check("", "std::operator><std::allocator<char> >", "()", "", + "std::operator><>"); + check("", "std::operator>><std::allocator<char> >", + "(std::basic_istream<char, std::char_traits<char> >&)", "", + "std::operator>><>"); + check("", "std::basic_istream<char>::operator>", "(unsigned int&)", "", + "std::basic_istream<>::operator>"); + check("v8::internal::SlotCallbackResult ", + "v8::internal::UpdateTypedSlotHelper::UpdateCodeTarget" + "<v8::PointerUpdateJobTraits<(v8::Direction)1>::Foo(v8::Heap*, " + "v8::MemoryChunk*)::{lambda(v8::SlotType, unsigned char*)#2}::" + "operator()(v8::SlotType, unsigned char*, unsigned char*) " + "const::{lambda(v8::Object**)#1}>", + "(v8::RelocInfo, v8::Foo<(v8::PointerDirection)1>::Bar(v8::Heap*)::" + "{lambda(v8::SlotType)#2}::operator()(v8::SlotType) const::" + "{lambda(v8::Object**)#1})", + "", "v8::internal::UpdateTypedSlotHelper::UpdateCodeTarget<>"); + check("", "WTF::StringAppend<WTF::String, WTF::String>::operator WTF::String", + "()", " const"); + // Make sure []s are not removed from the name part. + check("", "Foo", "()", " [virtual thunk]"); + // Template function that accepts an anonymous lambda. + check("", + "blink::FrameView::ForAllNonThrottledFrameViews<blink::FrameView::Pre" + "Paint()::{lambda(FrameView&)#2}>", + "(blink::FrameView::PrePaint()::{lambda(FrameView&)#2} const&)", ""); + + // Test with multiple template args. + check("int ", "Foo<int()>::bar<a<b> >", "()", "", "Foo<>::bar<>"); + + // See function_signature_test.py for full comment + std::string sig = + "(anonymous namespace)::Foo::Baz() const::GLSLFP::onData(Foo, Bar)"; + auto ret = caspian::ParseCpp(sig); + EXPECT_EQ("(anonymous namespace)::Foo::Baz", std::get<2>(ret)); + EXPECT_EQ("(anonymous namespace)::Foo::Baz", std::get<1>(ret)); + EXPECT_EQ(sig, std::get<0>(ret)); + + // Top-level lambda. + // Note: Inline lambdas do not seem to be broken into their own symbols. + sig = "cc::{lambda(cc::PaintOp*)#63}::_FUN(cc::PaintOp*)"; + ret = caspian::ParseCpp(sig); + EXPECT_EQ("cc::$lambda#63", std::get<2>(ret)); + EXPECT_EQ("cc::$lambda#63", std::get<1>(ret)); + EXPECT_EQ("cc::$lambda#63(cc::PaintOp*)", std::get<0>(ret)); + + sig = "cc::$_63::__invoke(cc::PaintOp*)"; + ret = caspian::ParseCpp(sig); + EXPECT_EQ("cc::$lambda#63", std::get<2>(ret)); + EXPECT_EQ("cc::$lambda#63", std::get<1>(ret)); + EXPECT_EQ("cc::$lambda#63(cc::PaintOp*)", std::get<0>(ret)); + + // Data members + check("", "blink::CSSValueKeywordsHash::findValueImpl", "(char const*)", + "::value_word_list"); + check("", "foo::Bar<Z<Y> >::foo<bar>", "(abc)", "::var<baz>", + "foo::Bar<>::foo<>::var<>"); +} } // namespace
diff --git a/tools/binary_size/libsupersize/function_signature.py b/tools/binary_size/libsupersize/function_signature.py index 7c1741f..0cfe01e 100644 --- a/tools/binary_size/libsupersize/function_signature.py +++ b/tools/binary_size/libsupersize/function_signature.py
@@ -14,43 +14,42 @@ # is necessary (rather than reusing _FindLastCharOutsideOfBrackets), is # to capture the outer-most function in the case where classes are nested. start_idx = 0 + template_balance_count = 0 + paren_balance_count = 0 while True: - template_balance_count = 0 - paren_balance_count = 0 - while True: - idx = name.find('(', start_idx) - if idx == -1: - return -1 - template_balance_count += ( - name.count('<', start_idx, idx) - name.count('>', start_idx, idx)) - # Special: operators with angle brackets. - operator_idx = name.find('operator<', start_idx, idx) - if operator_idx != -1: - if name[operator_idx + 9] == '<': - template_balance_count -= 2 - else: - template_balance_count -= 1 + idx = name.find('(', start_idx) + if idx == -1: + return -1 + template_balance_count += ( + name.count('<', start_idx, idx) - name.count('>', start_idx, idx)) + # Special: operators with angle brackets. + operator_idx = name.find('operator<', start_idx, idx) + if operator_idx != -1: + if name[operator_idx + 9] == '<': + template_balance_count -= 2 else: - operator_idx = name.find('operator>', start_idx, idx) - if operator_idx != -1: - if name[operator_idx + 9] == '>': - template_balance_count += 2 - else: - template_balance_count += 1 + template_balance_count -= 1 + else: + operator_idx = name.find('operator>', start_idx, idx) + if operator_idx != -1: + if name[operator_idx + 9] == '>': + template_balance_count += 2 + else: + template_balance_count += 1 - paren_balance_count += ( - name.count('(', start_idx, idx) - name.count(')', start_idx, idx)) - if template_balance_count == 0 and paren_balance_count == 0: - # Special case: skip "(anonymous namespace)". - if -1 != name.find('(anonymous namespace)', idx, idx + 21): - start_idx = idx + 21 - continue - # Special case: skip "decltype (...)" - # Special case: skip "{lambda(PaintOp*)#63}" - if name[idx - 1] != ' ' and name[idx - 7:idx] != '{lambda': - return idx - start_idx = idx + 1 - paren_balance_count += 1 + paren_balance_count += ( + name.count('(', start_idx, idx) - name.count(')', start_idx, idx)) + if template_balance_count == 0 and paren_balance_count == 0: + # Special case: skip "(anonymous namespace)". + if -1 != name.find('(anonymous namespace)', idx, idx + 21): + start_idx = idx + 21 + continue + # Special case: skip "decltype (...)" + # Special case: skip "{lambda(PaintOp*)#63}" + if name[idx - 1] != ' ' and name[idx - 7:idx] != '{lambda': + return idx + start_idx = idx + 1 + paren_balance_count += 1 def _FindLastCharOutsideOfBrackets(name, target_char, prev_idx=None): @@ -82,12 +81,18 @@ space_idx = _FindLastCharOutsideOfBrackets(name, ' ', space_idx) # Special cases: "operator new", "operator< <templ>", "operator<< <tmpl>". # No space is added for operator>><tmpl>. - if -1 == space_idx or ( - -1 == name.find('operator', space_idx - 8, space_idx) and - -1 == name.find('operator<', space_idx - 9, space_idx) and - -1 == name.find('operator<<', space_idx - 10, space_idx)): + if -1 == space_idx: break - space_idx -= 8 + + if -1 != name.find('operator', space_idx - 8, space_idx): + space_idx -= 8 + elif -1 != name.find('operator<', space_idx - 9, space_idx): + space_idx -= 9 + elif -1 != name.find('operator<<', space_idx - 10, space_idx): + space_idx -= 10 + else: + break + return space_idx @@ -186,9 +191,9 @@ assert right_paren_idx > left_paren_idx space_idx = _FindReturnValueSpace(name, left_paren_idx) name_no_params = name[space_idx + 1:left_paren_idx] - # Special case for top-level lamdas. + # Special case for top-level lambdas. if name_no_params.endswith('}::_FUN'): - # Don't use name_no_params in here since prior _idx will be off if + # Don't use |name_no_params| in here since prior _idx will be off if # there was a return value. name = _NormalizeTopLevelGccLambda(name, left_paren_idx) return Parse(name)
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index bcb50d6..200ba4bca 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -35678,6 +35678,7 @@ <int value="-1961648833" label="show_summary"/> <int value="-1961497025" label="tint-gl-composited-content"/> <int value="-1961062505" label="VrBrowsingInCustomTab:disabled"/> + <int value="-1960766118" label="CrossOriginIsolation:disabled"/> <int value="-1960567385" label="KeepPrefetchedContentSuggestions:enabled"/> <int value="-1959563554" label="ChromeOSAccountManager:enabled"/> <int value="-1958315092" label="EnableGamepadButtonAxisEvents:disabled"/> @@ -35724,6 +35725,7 @@ label="AlwaysShowServerCardsInSyncTransport:disabled"/> <int value="-1916060206" label="enable-display-zoom-setting"/> <int value="-1915854488" label="enable-offline-pages"/> + <int value="-1914798479" label="CryptAuthV1DeviceSyncDeprecate:disabled"/> <int value="-1913801713" label="UploadCrashReportsUsingJobScheduler:disabled"/> <int value="-1912999136" label="enable-automatic-password-saving:enabled"/> @@ -36033,7 +36035,6 @@ <int value="-1514611301" label="enable-data-reduction-proxy-bypass-warnings"/> <int value="-1512656386" label="disable-new-audio-rendering-mixing-strategy"/> <int value="-1510839574" label="disable-sync-synced-notifications"/> - <int value="-1509001043" label="CrossOriginEmbedderPolicy:enabled"/> <int value="-1508852757" label="CreditCardAutofillTouchBar:disabled"/> <int value="-1506880454" label="SupervisedUserCommittedInterstitials:disabled"/> @@ -36485,6 +36486,7 @@ <int value="-992785453" label="ExplicitLanguageAsk:disabled"/> <int value="-991253797" label="OmniboxSpeculativeServiceWorkerStartOnQueryInput:disabled"/> + <int value="-990374250" label="CrossOriginIsolation:enabled"/> <int value="-990187062" label="SendTabToSelfShowSendingUI:enabled"/> <int value="-989671895" label="OfflineIndicatorAlwaysHttpProbe:enabled"/> <int value="-987470173" label="ClickToCallOpenDialerDirectly:disabled"/> @@ -36756,7 +36758,6 @@ <int value="-662064703" label="MediaSessionService:enabled"/> <int value="-661978438" label="enable-data-reduction-proxy-lo-fi"/> <int value="-660160292" label="enable-apps-show-on-first-paint"/> - <int value="-656345197" label="CrossOriginEmbedderPolicy:disabled"/> <int value="-654196854" label="PasswordsKeyboardAccessory:enabled"/> <int value="-653616608" label="MacSyscallSandbox:disabled"/> <int value="-650504533" label="enable-speculative-launch-service-worker"/> @@ -37105,6 +37106,7 @@ <int value="-174564579" label="ServiceWorkerImportedScriptUpdateCheck:enabled"/> <int value="-174319545" label="BulkPrinters:enabled"/> + <int value="-174161156" label="CryptAuthV1DeviceSyncDeprecate:enabled"/> <int value="-173268856" label="GesturePropertiesDBusService"/> <int value="-171232290" label="ListAllDisplayModes:disabled"/> <int value="-171173736" label="VrBrowsingExperimentalFeatures:disabled"/>
diff --git a/tools/perf/core/results_processor/command_line.py b/tools/perf/core/results_processor/command_line.py index 94b99b5..5ea5e73 100644 --- a/tools/perf/core/results_processor/command_line.py +++ b/tools/perf/core/results_processor/command_line.py
@@ -18,6 +18,7 @@ from core.results_processor import formatters from core.results_processor import util +from core.results_processor import trace_processor def ArgumentParser(standalone=False): @@ -69,6 +70,11 @@ 'How to interpret the testPath attribute.', 'Available options: %(choices)s. Default: %(default)s.')) group.add_argument( + '--trace-processor-path', default=trace_processor.DEFAULT_TP_PATH, + help=Sentences( + 'Path to trace processor shell.', + 'Default: %(default)s.')) + group.add_argument( '--upload-results', action='store_true', help='Upload generated artifacts to cloud storage.') group.add_argument(
diff --git a/tools/perf/core/results_processor/compute_metrics.py b/tools/perf/core/results_processor/compute_metrics.py index 193d964..c745f86 100644 --- a/tools/perf/core/results_processor/compute_metrics.py +++ b/tools/perf/core/results_processor/compute_metrics.py
@@ -15,9 +15,7 @@ HTML_TRACE_NAME = 'trace.html' -def _RunMetric(test_result): - metrics = [tag['value'] for tag in test_result['tags'] - if tag['key'] == 'tbmv2'] +def _RunMetric(test_result, metrics): html_trace = test_result['outputArtifacts'][HTML_TRACE_NAME] html_local_path = html_trace['filePath'] html_remote_url = html_trace.get('remoteUrl') @@ -59,8 +57,16 @@ if test_result['status'] == 'SKIP': return - if (HTML_TRACE_NAME not in artifacts or - not any(tag['key'] == 'tbmv2' for tag in test_result.get('tags', []))): + metrics = [tag['value'] for tag in test_result.get('tags', []) + if tag['key'] == 'tbmv2'] + if not metrics: + logging.info('%s: No metrics specified.', test_result['testPath']) + return + + if HTML_TRACE_NAME not in artifacts: + util.SetUnexpectedFailure(test_result) + logging.error('%s: No traces to compute metrics on.', + test_result['testPath']) return trace_size_in_mib = (os.path.getsize(artifacts[HTML_TRACE_NAME]['filePath']) @@ -73,4 +79,4 @@ test_result['testPath'], trace_size_in_mib) return - test_result['_histograms'].ImportDicts(_RunMetric(test_result)) + test_result['_histograms'].ImportDicts(_RunMetric(test_result, metrics))
diff --git a/tools/perf/core/results_processor/processor.py b/tools/perf/core/results_processor/processor.py index d5a75c3..853e55d 100644 --- a/tools/perf/core/results_processor/processor.py +++ b/tools/perf/core/results_processor/processor.py
@@ -21,6 +21,7 @@ from core.results_processor import command_line from core.results_processor import compute_metrics from core.results_processor import formatters +from core.results_processor import trace_processor from core.results_processor import util from tracing.trace_data import trace_data @@ -34,6 +35,7 @@ TEST_RESULTS = '_test_results.jsonl' DIAGNOSTICS_NAME = 'diagnostics.json' MEASUREMENTS_NAME = 'measurements.json' +CONVERTED_JSON_TRACE_NAME = 'converted_from_pb.json' FORMATS_WITH_METRICS = ['csv', 'histograms', 'html'] @@ -63,6 +65,7 @@ results_label = options.results_label max_num_values = options.max_values_per_test_case test_path_format = options.test_path_format + trace_processor_path = options.trace_processor_path test_suite_start = (test_results[0]['startTime'] if test_results and 'startTime' in test_results[0] else datetime.datetime.utcnow().isoformat() + 'Z') @@ -74,7 +77,7 @@ lambda result: ProcessTestResult( result, upload_bucket, results_label, run_identifier, test_suite_start, should_compute_metrics, max_num_values, - test_path_format), + test_path_format, trace_processor_path), test_results, on_failure=util.SetUnexpectedFailure, ) @@ -96,8 +99,9 @@ def ProcessTestResult(test_result, upload_bucket, results_label, run_identifier, test_suite_start, should_compute_metrics, - max_num_values, test_path_format): - AggregateTraces(test_result) + max_num_values, test_path_format, trace_processor_path): + ConvertProtoTraces(test_result, trace_processor_path) + AggregateJsonTraces(test_result) if upload_bucket is not None: UploadArtifacts(test_result, upload_bucket, run_identifier) @@ -152,27 +156,68 @@ return test_results -def AggregateTraces(test_result): - """Replace individual traces with an aggregate one for each test result. +def _IsProtoTrace(trace_name): + return (trace_name.startswith('trace/') and + (trace_name.endswith('.pb') or trace_name.endswith('.pb.gz'))) - For a test run with traces, generates an aggregate HTML trace. Removes + +def _IsJsonTrace(trace_name): + return (trace_name.startswith('trace/') and + (trace_name.endswith('.json') or trace_name.endswith('.json.gz'))) + + +def _BuildOutputPath(input_files, output_name): + """Build a path to a file in the same folder as input_files.""" + return os.path.join( + os.path.dirname(os.path.commonprefix(input_files)), + output_name + ) + + +def ConvertProtoTraces(test_result, trace_processor_path): + """Convert proto traces to json. + + For a test result with proto traces, converts them to json using + trace_processor and stores the json trace as a separate artifact. + """ + artifacts = test_result.get('outputArtifacts', {}) + proto_trace_files = [ + artifact['filePath'] for name, artifact in artifacts.iteritems() + if _IsProtoTrace(name)] + + if proto_trace_files: + logging.info('%s: Converting proto traces %s.', + test_result['testPath'], proto_trace_files) + json_path = _BuildOutputPath(proto_trace_files, CONVERTED_JSON_TRACE_NAME) + trace_processor.ConvertProtoTracesToJson( + trace_processor_path, proto_trace_files, json_path) + artifacts['trace/' + CONVERTED_JSON_TRACE_NAME] = { + 'filePath': json_path, + 'contentType': 'application/json', + } + + +def AggregateJsonTraces(test_result): + """Replace individual json traces with an aggregate HTML trace. + + For a test result with json traces, generates an aggregate HTML trace. Removes all entries for individual traces and adds one entry for aggregate one. """ artifacts = test_result.get('outputArtifacts', {}) - traces = [name for name in artifacts if name.startswith('trace/')] + json_traces = [name for name in artifacts if _IsJsonTrace(name)] # TODO(crbug.com/981349): Stop checking for HTML_TRACE_NAME after # Telemetry does not aggregate traces anymore. - if traces and compute_metrics.HTML_TRACE_NAME not in artifacts: - trace_files = [artifacts[name]['filePath'] for name in traces] - html_path = os.path.join( - os.path.dirname(os.path.commonprefix(trace_files)), - compute_metrics.HTML_TRACE_NAME) + if json_traces and compute_metrics.HTML_TRACE_NAME not in artifacts: + trace_files = [artifacts[name]['filePath'] for name in json_traces] + html_path = _BuildOutputPath(trace_files, compute_metrics.HTML_TRACE_NAME) + logging.info('%s: Aggregating json traces %s.', + test_result['testPath'], trace_files) trace_data.SerializeAsHtml(trace_files, html_path) artifacts[compute_metrics.HTML_TRACE_NAME] = { 'filePath': html_path, 'contentType': 'text/html', } - for name in traces: + for name in json_traces: del artifacts[name]
diff --git a/tools/perf/core/results_processor/processor_test.py b/tools/perf/core/results_processor/processor_test.py index 7c0d37e..d3962a85 100644 --- a/tools/perf/core/results_processor/processor_test.py +++ b/tools/perf/core/results_processor/processor_test.py
@@ -123,7 +123,7 @@ 'benchmark/story', output_artifacts={ 'logs': testing.Artifact('/logs.txt', 'gs://logs.txt'), - 'trace/telemetry': testing.Artifact('/telemetry.json'), + 'trace/telemetry.json': testing.Artifact('/telemetry.json'), 'trace.html': testing.Artifact('/trace.html', 'gs://trace.html'), } @@ -314,7 +314,7 @@ self.SerializeIntermediateResults( testing.TestResult( 'benchmark/story', - output_artifacts={'trace/json': testing.Artifact(json_trace)}, + output_artifacts={'trace/trace.json': testing.Artifact(json_trace)}, tags=['tbmv2:sampleMetric'], ), )
diff --git a/tools/perf/core/results_processor/processor_unittest.py b/tools/perf/core/results_processor/processor_unittest.py index 2659fce9..2dc5517 100644 --- a/tools/perf/core/results_processor/processor_unittest.py +++ b/tools/perf/core/results_processor/processor_unittest.py
@@ -90,7 +90,7 @@ test_suite_start='2019-10-01T12:00:00.123456Z') self.assertEqual(run_identifier, 'src_abc_123_20191001T120000_54321') - def testAggregateTraces(self): + def testAggregateJsonTraces(self): test_result = testing.TestResult( 'benchmark/story2', output_artifacts={ @@ -103,7 +103,7 @@ serialize_method = 'tracing.trace_data.trace_data.SerializeAsHtml' with mock.patch(serialize_method) as mock_serialize: - processor.AggregateTraces(test_result) + processor.AggregateJsonTraces(test_result) self.assertEqual(mock_serialize.call_count, 1) trace_files, file_path = mock_serialize.call_args[0][:2]
diff --git a/tools/perf/core/results_processor/trace_processor.py b/tools/perf/core/results_processor/trace_processor.py new file mode 100644 index 0000000..08ee0d3 --- /dev/null +++ b/tools/perf/core/results_processor/trace_processor.py
@@ -0,0 +1,51 @@ +# 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 gzip +import logging +import os +import shutil +import subprocess + +from core import path_util +from py_utils import tempfile_ext + + +DEFAULT_TP_PATH = os.path.join( + path_util.GetChromiumSrcDir(), 'out', 'Debug', 'trace_processor_shell') +EXPORT_JSON_QUERY_TEMPLATE = 'select export_json(%s)\n' + + +def _SqlString(s): + """Produce a valid SQL string constant.""" + return "'%s'" % s.replace("'", "''") + + +def ConvertProtoTracesToJson(trace_processor_path, proto_files, json_path): + if not os.path.isfile(trace_processor_path): + raise RuntimeError("Can't find trace processor executable at %s" % + trace_processor_path) + + with tempfile_ext.NamedTemporaryFile() as concatenated_trace: + for trace_file in proto_files: + if trace_file.endswith('.pb.gz'): + with gzip.open(trace_file, 'rb') as f: + shutil.copyfileobj(f, concatenated_trace) + else: + with open(trace_file, 'rb') as f: + shutil.copyfileobj(f, concatenated_trace) + concatenated_trace.close() + + with tempfile_ext.NamedTemporaryFile() as query_file: + query_file.write(EXPORT_JSON_QUERY_TEMPLATE % _SqlString(json_path)) + query_file.close() + subprocess.check_call([ + trace_processor_path, + concatenated_trace.name, + '-q', query_file.name, + ]) + + logging.info('Converted json trace written to %s', json_path) + + return json_path
diff --git a/tools/perf/core/results_processor/trace_processor_unittest.py b/tools/perf/core/results_processor/trace_processor_unittest.py new file mode 100644 index 0000000..642cf00b --- /dev/null +++ b/tools/perf/core/results_processor/trace_processor_unittest.py
@@ -0,0 +1,34 @@ +# 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 gzip +import os +import shutil +import tempfile +import unittest + +from core.results_processor import trace_processor + +import mock + + +class TraceProcessorTestCase(unittest.TestCase): + def setUp(self): + self.temp_dir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.temp_dir) + + def testConvertProtoTracesToJson(self): + trace_plain = os.path.join(self.temp_dir, 'trace1.pb') + with open(trace_plain, 'w') as f: + f.write('a') + trace_gzipped = os.path.join(self.temp_dir, 'trace2.pb.gz') + with gzip.open(trace_gzipped, 'w') as f: + f.write('b') + + with mock.patch('os.path.isfile', return_value=True): + with mock.patch('subprocess.check_call'): + trace_processor.ConvertProtoTracesToJson( + '/path/to/tp', [trace_plain, trace_gzipped], '/path/to/json')
diff --git a/tools/perf/examples/pinpoint_cli/bisect_job.json b/tools/perf/examples/pinpoint_cli/bisect_job.json index ada8220..5c2be88 100644 --- a/tools/perf/examples/pinpoint_cli/bisect_job.json +++ b/tools/perf/examples/pinpoint_cli/bisect_job.json
@@ -1,16 +1,14 @@ { "name": "Example bisect job", - "bug_id": "944965", + "bug_id": "1022349", "target": "performance_webview_test_suite", "configuration": "android-go_webview-perf", - "benchmark": "system_health.memory_mobile", "comparison_mode": "performance", - "story": "browse.media.facebook.photos", + "benchmark": "system_health.memory_mobile", + "story": "browse:media:facebook_photos", "chart": "memory:webview:all_processes:reported_by_os:system_memory:private_dirty_size", - "tir_label": "browse_media", - "trace": "browse:media:facebook_photos", "statistic": "avg", "repository": "chromium", - "start_git_hash": "dd0f551fcd96d46c6ec2b2a7c543cb2083f1831d", - "end_git_hash": "e6808e8d7e973f43b0796505a09ee03caf6ec976" + "start_git_hash": "9bb441de89f7d031992ec67585ac0732ef622222", + "end_git_hash": "f402331ff436d3ac12cacbd1c959641eb3524923" }
diff --git a/ui/accessibility/ax_role_properties.cc b/ui/accessibility/ax_role_properties.cc index 102ad3a..dfbd111 100644 --- a/ui/accessibility/ax_role_properties.cc +++ b/ui/accessibility/ax_role_properties.cc
@@ -205,13 +205,16 @@ case ax::mojom::Role::kImage: case ax::mojom::Role::kImageMap: case ax::mojom::Role::kSvgRoot: - case ax::mojom::Role::kVideo: return true; default: return false; } } +bool IsImageOrVideo(const ax::mojom::Role role) { + return IsImage(role) || role == ax::mojom::Role::kVideo; +} + bool IsInvokable(const AXNodeData& data) { // A control is "invokable" if it initiates an action when activated but // does not maintain any state. A control that maintains state when activated
diff --git a/ui/accessibility/ax_role_properties.h b/ui/accessibility/ax_role_properties.h index 8e4f741..e79f1d7 100644 --- a/ui/accessibility/ax_role_properties.h +++ b/ui/accessibility/ax_role_properties.h
@@ -53,6 +53,9 @@ // Returns true if the given AXNodeData has ignored state or ignored role. AX_EXPORT bool IsIgnored(const AXNodeData& data); +// Returns true if the provided role is for any kind of image or video. +AX_EXPORT bool IsImageOrVideo(const ax::mojom::Role role); + // Returns true if the provided role belongs to an image, graphic, canvas, etc. AX_EXPORT bool IsImage(const ax::mojom::Role role);
diff --git a/ui/accessibility/platform/ax_platform_node_auralinux.cc b/ui/accessibility/platform/ax_platform_node_auralinux.cc index 91a9610..241412e 100644 --- a/ui/accessibility/platform/ax_platform_node_auralinux.cc +++ b/ui/accessibility/platform/ax_platform_node_auralinux.cc
@@ -2078,7 +2078,7 @@ // for each object. interface_mask |= 1 << ATK_ACTION_INTERFACE; - if (!ui::IsImage(GetData().role)) { + if (!ui::IsImageOrVideo(GetData().role)) { interface_mask |= 1 << ATK_TEXT_INTERFACE; if (!IsPlainTextField()) interface_mask |= 1 << ATK_HYPERTEXT_INTERFACE;
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc index 4c833ca..b6c41265 100644 --- a/ui/accessibility/platform/ax_platform_node_win.cc +++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -4312,7 +4312,7 @@ if (!IsCellOrTableHeader(accessible->GetData().role)) return E_NOINTERFACE; } else if (riid == IID_IAccessibleText || riid == IID_IAccessibleHypertext) { - if (ui::IsImage(accessible->GetData().role)) { + if (ui::IsImageOrVideo(accessible->GetData().role)) { return E_NOINTERFACE; } }